• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""cc_toolchain_config rule for configuring CUDA toolchains on Linux, Mac, and Windows."""
2
3load(
4    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
5    "action_config",
6    "artifact_name_pattern",
7    "env_entry",
8    "env_set",
9    "feature",
10    "feature_set",
11    "flag_group",
12    "flag_set",
13    "tool",
14    "tool_path",
15    "variable_with_value",
16    "with_feature_set",
17)
18load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
19
20def all_assembly_actions():
21    return [
22        ACTION_NAMES.assemble,
23        ACTION_NAMES.preprocess_assemble,
24    ]
25
26def all_compile_actions():
27    return [
28        ACTION_NAMES.assemble,
29        ACTION_NAMES.c_compile,
30        ACTION_NAMES.cpp_compile,
31        ACTION_NAMES.cpp_header_parsing,
32        ACTION_NAMES.cpp_module_codegen,
33        ACTION_NAMES.cpp_module_compile,
34        ACTION_NAMES.linkstamp_compile,
35        ACTION_NAMES.preprocess_assemble,
36    ]
37
38def all_c_compile_actions():
39    return [
40        ACTION_NAMES.c_compile,
41    ]
42
43def all_cpp_compile_actions():
44    return [
45        ACTION_NAMES.cpp_compile,
46        ACTION_NAMES.cpp_header_parsing,
47        ACTION_NAMES.cpp_module_codegen,
48        ACTION_NAMES.cpp_module_compile,
49        ACTION_NAMES.linkstamp_compile,
50    ]
51
52def all_preprocessed_actions():
53    return [
54        ACTION_NAMES.c_compile,
55        ACTION_NAMES.cpp_compile,
56        ACTION_NAMES.cpp_header_parsing,
57        ACTION_NAMES.cpp_module_codegen,
58        ACTION_NAMES.cpp_module_compile,
59        ACTION_NAMES.linkstamp_compile,
60        ACTION_NAMES.preprocess_assemble,
61    ]
62
63def all_link_actions():
64    return [
65        ACTION_NAMES.cpp_link_executable,
66        ACTION_NAMES.cpp_link_dynamic_library,
67        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
68    ]
69
70def all_executable_link_actions():
71    return [
72        ACTION_NAMES.cpp_link_executable,
73    ]
74
75def all_shared_library_link_actions():
76    return [
77        ACTION_NAMES.cpp_link_dynamic_library,
78        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
79    ]
80
81def all_archive_actions():
82    return [ACTION_NAMES.cpp_link_static_library]
83
84def all_strip_actions():
85    return [ACTION_NAMES.strip]
86
87def _library_to_link(flag_prefix, value, iterate = None):
88    return flag_group(
89        flags = [
90            "{}%{{libraries_to_link.{}}}".format(
91                flag_prefix,
92                iterate if iterate else "name",
93            ),
94        ],
95        iterate_over = ("libraries_to_link." + iterate if iterate else None),
96        expand_if_equal = variable_with_value(
97            name = "libraries_to_link.type",
98            value = value,
99        ),
100    )
101
102def _surround_static_library(prefix, suffix):
103    return [
104        flag_group(
105            flags = [prefix, "%{libraries_to_link.name}", suffix],
106            expand_if_true = "libraries_to_link.is_whole_archive",
107        ),
108        flag_group(
109            flags = ["%{libraries_to_link.name}"],
110            expand_if_false = "libraries_to_link.is_whole_archive",
111        ),
112    ]
113
114def _prefix_static_library(prefix):
115    return [
116        flag_group(
117            flags = ["%{libraries_to_link.name}"],
118            expand_if_false = "libraries_to_link.is_whole_archive",
119        ),
120        flag_group(
121            flags = [prefix + "%{libraries_to_link.name}"],
122            expand_if_true = "libraries_to_link.is_whole_archive",
123        ),
124    ]
125
126def _static_library_to_link(alwayslink_prefix, alwayslink_suffix = None):
127    if alwayslink_suffix:
128        flag_groups = _surround_static_library(alwayslink_prefix, alwayslink_suffix)
129    else:
130        flag_groups = _prefix_static_library(alwayslink_prefix)
131    return flag_group(
132        flag_groups = flag_groups,
133        expand_if_equal = variable_with_value(
134            name = "libraries_to_link.type",
135            value = "static_library",
136        ),
137    )
138
139def _iterate_flag_group(iterate_over, flags = [], flag_groups = []):
140    return flag_group(
141        iterate_over = iterate_over,
142        expand_if_available = iterate_over,
143        flag_groups = flag_groups,
144        flags = flags,
145    )
146
147def _libraries_to_link_group(flavour):
148    if flavour == "linux":
149        return _iterate_flag_group(
150            iterate_over = "libraries_to_link",
151            flag_groups = [
152                flag_group(
153                    flags = ["-Wl,--start-lib"],
154                    expand_if_equal = variable_with_value(
155                        name = "libraries_to_link.type",
156                        value = "object_file_group",
157                    ),
158                ),
159                _library_to_link("", "object_file_group", "object_files"),
160                flag_group(
161                    flags = ["-Wl,--end-lib"],
162                    expand_if_equal = variable_with_value(
163                        name = "libraries_to_link.type",
164                        value = "object_file_group",
165                    ),
166                ),
167                _library_to_link("", "object_file"),
168                _library_to_link("", "interface_library"),
169                _static_library_to_link("-Wl,-whole-archive", "-Wl,-no-whole-archive"),
170                _library_to_link("-l", "dynamic_library"),
171                _library_to_link("-l:", "versioned_dynamic_library"),
172            ],
173        )
174    elif flavour == "darwin":
175        return _iterate_flag_group(
176            iterate_over = "libraries_to_link",
177            flag_groups = [
178                _library_to_link("", "object_file_group", "object_files"),
179                _library_to_link("", "object_file"),
180                _library_to_link("", "interface_library"),
181                _static_library_to_link("-Wl,-force_load,"),
182                _library_to_link("-l", "dynamic_library"),
183                _library_to_link("-l:", "versioned_dynamic_library"),
184            ],
185        )
186    elif flavour == "msvc":
187        return _iterate_flag_group(
188            iterate_over = "libraries_to_link",
189            flag_groups = [
190                _library_to_link("", "object_file_group", "object_files"),
191                _library_to_link("", "object_file"),
192                _library_to_link("", "interface_library"),
193                _static_library_to_link("/WHOLEARCHIVE:"),
194            ],
195        )
196
197def _action_configs_with_tool(path, actions):
198    return [
199        action_config(
200            action_name = name,
201            enabled = True,
202            tools = [tool(path = path)],
203        )
204        for name in actions
205    ]
206
207def _action_configs(assembly_path, c_compiler_path, cc_compiler_path, archiver_path, linker_path, strip_path):
208    return _action_configs_with_tool(
209        assembly_path,
210        all_assembly_actions(),
211    ) + _action_configs_with_tool(
212        c_compiler_path,
213        all_c_compile_actions(),
214    ) + _action_configs_with_tool(
215        cc_compiler_path,
216        all_cpp_compile_actions(),
217    ) + _action_configs_with_tool(
218        archiver_path,
219        all_archive_actions(),
220    ) + _action_configs_with_tool(
221        linker_path,
222        all_link_actions(),
223    ) + _action_configs_with_tool(
224        strip_path,
225        all_strip_actions(),
226    )
227
228def _tool_paths(cpu, ctx):
229    if cpu in ["local", "darwin"]:
230        return [
231            tool_path(name = "gcc", path = ctx.attr.host_compiler_path),
232            tool_path(name = "ar", path = ctx.attr.host_compiler_prefix + (
233                "/ar" if cpu == "local" else "/libtool"
234            )),
235            tool_path(name = "compat-ld", path = ctx.attr.host_compiler_prefix + "/ld"),
236            tool_path(name = "cpp", path = ctx.attr.host_compiler_prefix + "/cpp"),
237            tool_path(name = "dwp", path = ctx.attr.host_compiler_prefix + "/dwp"),
238            tool_path(name = "gcov", path = ctx.attr.host_compiler_prefix + "/gcov"),
239            tool_path(name = "ld", path = ctx.attr.host_compiler_prefix + "/ld"),
240            tool_path(name = "nm", path = ctx.attr.host_compiler_prefix + "/nm"),
241            tool_path(name = "objcopy", path = ctx.attr.host_compiler_prefix + "/objcopy"),
242            tool_path(name = "objdump", path = ctx.attr.host_compiler_prefix + "/objdump"),
243            tool_path(name = "strip", path = ctx.attr.host_compiler_prefix + "/strip"),
244        ]
245    elif cpu == "x64_windows":
246        return [
247            tool_path(name = "ar", path = ctx.attr.msvc_lib_path),
248            tool_path(name = "ml", path = ctx.attr.msvc_ml_path),
249            tool_path(name = "cpp", path = ctx.attr.msvc_cl_path),
250            tool_path(name = "gcc", path = ctx.attr.msvc_cl_path),
251            tool_path(name = "gcov", path = "wrapper/bin/msvc_nop.bat"),
252            tool_path(name = "ld", path = ctx.attr.msvc_link_path),
253            tool_path(name = "nm", path = "wrapper/bin/msvc_nop.bat"),
254            tool_path(
255                name = "objcopy",
256                path = "wrapper/bin/msvc_nop.bat",
257            ),
258            tool_path(
259                name = "objdump",
260                path = "wrapper/bin/msvc_nop.bat",
261            ),
262            tool_path(
263                name = "strip",
264                path = "wrapper/bin/msvc_nop.bat",
265            ),
266        ]
267    else:
268        fail("Unreachable")
269
270def _sysroot_group():
271    return flag_group(
272        flags = ["--sysroot=%{sysroot}"],
273        expand_if_available = "sysroot",
274    )
275
276def _no_canonical_prefixes_group(extra_flags):
277    return flag_group(
278        flags = [
279            "-no-canonical-prefixes",
280        ] + extra_flags,
281    )
282
283def _cuda_set(cuda_path, actions):
284    if cuda_path:
285        return [flag_set(
286            actions = actions,
287            flag_groups = [
288                flag_group(
289                    flags = ["--cuda-path=" + cuda_path],
290                ),
291            ],
292        )]
293    else:
294        return []
295
296def _nologo():
297    return flag_group(flags = ["/nologo"])
298
299def _features(cpu, compiler, ctx):
300    if cpu in ["local", "darwin"]:
301        return [
302            feature(name = "no_legacy_features"),
303            feature(
304                name = "all_compile_flags",
305                enabled = True,
306                flag_sets = [
307                    flag_set(
308                        actions = all_compile_actions(),
309                        flag_groups = [
310                            flag_group(
311                                flags = ["-MD", "-MF", "%{dependency_file}"],
312                                expand_if_available = "dependency_file",
313                            ),
314                            flag_group(
315                                flags = ["-gsplit-dwarf"],
316                                expand_if_available = "per_object_debug_info_file",
317                            ),
318                        ],
319                    ),
320                    flag_set(
321                        actions = all_preprocessed_actions(),
322                        flag_groups = [
323                            flag_group(
324                                flags = ["-frandom-seed=%{output_file}"],
325                                expand_if_available = "output_file",
326                            ),
327                            _iterate_flag_group(
328                                flags = ["-D%{preprocessor_defines}"],
329                                iterate_over = "preprocessor_defines",
330                            ),
331                            _iterate_flag_group(
332                                flags = ["-include", "%{includes}"],
333                                iterate_over = "includes",
334                            ),
335                            _iterate_flag_group(
336                                flags = ["-iquote", "%{quote_include_paths}"],
337                                iterate_over = "quote_include_paths",
338                            ),
339                            _iterate_flag_group(
340                                flags = ["-I%{include_paths}"],
341                                iterate_over = "include_paths",
342                            ),
343                            _iterate_flag_group(
344                                flags = ["-isystem", "%{system_include_paths}"],
345                                iterate_over = "system_include_paths",
346                            ),
347                            _iterate_flag_group(
348                                flags = ["-F", "%{framework_include_paths}"],
349                                iterate_over = "framework_include_paths",
350                            ),
351                        ],
352                    ),
353                    flag_set(
354                        actions = all_cpp_compile_actions(),
355                        flag_groups = [
356                            flag_group(flags = [
357                                "-fexperimental-new-pass-manager",
358                                "-fmerge-all-constants",
359                            ]),
360                        ] if compiler == "clang" else [],
361                    ),
362                    flag_set(
363                        actions = all_compile_actions(),
364                        flag_groups = [
365                            flag_group(
366                                flags = [
367                                    "-Wno-builtin-macro-redefined",
368                                    "-D__DATE__=\"redacted\"",
369                                    "-D__TIMESTAMP__=\"redacted\"",
370                                    "-D__TIME__=\"redacted\"",
371                                ],
372                            ),
373                            flag_group(
374                                flags = ["-fPIC"],
375                                expand_if_available = "pic",
376                            ),
377                            flag_group(
378                                flags = ["-fPIE"],
379                                expand_if_not_available = "pic",
380                            ),
381                            flag_group(
382                                flags = [
383                                    "-U_FORTIFY_SOURCE",
384                                    "-D_FORTIFY_SOURCE=1",
385                                    "-fstack-protector",
386                                    "-Wall",
387                                ] + ctx.attr.host_compiler_warnings + [
388                                    "-fno-omit-frame-pointer",
389                                ],
390                            ),
391                            _no_canonical_prefixes_group(
392                                ctx.attr.extra_no_canonical_prefixes_flags,
393                            ),
394                        ],
395                    ),
396                    flag_set(
397                        actions = all_compile_actions(),
398                        flag_groups = [flag_group(flags = ["-DNDEBUG"])],
399                        with_features = [with_feature_set(features = ["disable-assertions"])],
400                    ),
401                    flag_set(
402                        actions = all_compile_actions(),
403                        flag_groups = [
404                            flag_group(
405                                flags = [
406                                    "-g0",
407                                    "-O2",
408                                    "-ffunction-sections",
409                                    "-fdata-sections",
410                                ],
411                            ),
412                        ],
413                        with_features = [with_feature_set(features = ["opt"])],
414                    ),
415                    flag_set(
416                        actions = all_compile_actions(),
417                        flag_groups = [flag_group(flags = ["-g"])],
418                        with_features = [with_feature_set(features = ["dbg"])],
419                    ),
420                ] + _cuda_set(
421                    ctx.attr.cuda_path,
422                    all_compile_actions(),
423                ) + [
424                    flag_set(
425                        actions = all_compile_actions(),
426                        flag_groups = [
427                            _iterate_flag_group(
428                                flags = ["%{user_compile_flags}"],
429                                iterate_over = "user_compile_flags",
430                            ),
431                            _sysroot_group(),
432                            flag_group(
433                                expand_if_available = "source_file",
434                                flags = ["-c", "%{source_file}"],
435                            ),
436                            flag_group(
437                                expand_if_available = "output_assembly_file",
438                                flags = ["-S"],
439                            ),
440                            flag_group(
441                                expand_if_available = "output_preprocess_file",
442                                flags = ["-E"],
443                            ),
444                            flag_group(
445                                expand_if_available = "output_file",
446                                flags = ["-o", "%{output_file}"],
447                            ),
448                        ],
449                    ),
450                ],
451            ),
452            feature(
453                name = "all_archive_flags",
454                enabled = True,
455                flag_sets = [
456                    flag_set(
457                        actions = all_archive_actions(),
458                        flag_groups = [
459                            flag_group(
460                                expand_if_available = "linker_param_file",
461                                flags = ["@%{linker_param_file}"],
462                            ),
463                            flag_group(flags = ["rcsD"]),
464                            flag_group(
465                                flags = ["%{output_execpath}"],
466                                expand_if_available = "output_execpath",
467                            ),
468                            flag_group(
469                                iterate_over = "libraries_to_link",
470                                flag_groups = [
471                                    flag_group(
472                                        flags = ["%{libraries_to_link.name}"],
473                                        expand_if_equal = variable_with_value(
474                                            name = "libraries_to_link.type",
475                                            value = "object_file",
476                                        ),
477                                    ),
478                                    flag_group(
479                                        flags = ["%{libraries_to_link.object_files}"],
480                                        iterate_over = "libraries_to_link.object_files",
481                                        expand_if_equal = variable_with_value(
482                                            name = "libraries_to_link.type",
483                                            value = "object_file_group",
484                                        ),
485                                    ),
486                                ],
487                                expand_if_available = "libraries_to_link",
488                            ),
489                        ],
490                    ),
491                ],
492            ),
493            feature(
494                name = "all_link_flags",
495                enabled = True,
496                flag_sets = [
497                    flag_set(
498                        actions = all_shared_library_link_actions(),
499                        flag_groups = [flag_group(flags = ["-shared"])],
500                    ),
501                    flag_set(
502                        actions = all_link_actions(),
503                        flag_groups = ([
504                            flag_group(flags = ["-Wl,-no-as-needed"])
505                        ] if cpu == "local" else []) + ([
506                            flag_group(flags = ["-B" + ctx.attr.linker_bin_path])
507                        ] if ctx.attr.linker_bin_path else []) + [
508                            flag_group(
509                                flags = ["@%{linker_param_file}"],
510                                expand_if_available = "linker_param_file",
511                            ),
512                            _iterate_flag_group(
513                                flags = ["%{linkstamp_paths}"],
514                                iterate_over = "linkstamp_paths",
515                            ),
516                            flag_group(
517                                flags = ["-o", "%{output_execpath}"],
518                                expand_if_available = "output_execpath",
519                            ),
520                            _iterate_flag_group(
521                                flags = ["-L%{library_search_directories}"],
522                                iterate_over = "library_search_directories",
523                            ),
524                            _iterate_flag_group(
525                                iterate_over = "runtime_library_search_directories",
526                                flags = [
527                                    "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
528                                ] if cpu == "local" else [
529                                    "-Wl,-rpath,@loader_path/%{runtime_library_search_directories}",
530                                ],
531                            ),
532                            _libraries_to_link_group("darwin" if cpu == "darwin" else "linux"),
533                            _iterate_flag_group(
534                                flags = ["%{user_link_flags}"],
535                                iterate_over = "user_link_flags",
536                            ),
537                            flag_group(
538                                flags = ["-Wl,--gdb-index"],
539                                expand_if_available = "is_using_fission",
540                            ),
541                            flag_group(
542                                flags = ["-Wl,-S"],
543                                expand_if_available = "strip_debug_symbols",
544                            ),
545                            flag_group(flags = ["-lc++" if cpu == "darwin" else "-lstdc++"]),
546                            _no_canonical_prefixes_group(
547                                ctx.attr.extra_no_canonical_prefixes_flags,
548                            ),
549                        ],
550                    ),
551                    flag_set(
552                        actions = all_executable_link_actions(),
553                        flag_groups = [flag_group(flags = ["-pie"])],
554                    ),
555                ] + ([
556                    flag_set(
557                        actions = all_link_actions(),
558                        flag_groups = [flag_group(flags = [
559                            "-Wl,-z,relro,-z,now",
560                        ])],
561                    ),
562                ] if cpu == "local" else []) + ([
563                    flag_set(
564                        actions = all_link_actions(),
565                        flag_groups = [
566                            flag_group(flags = ["-Wl,--gc-sections"]),
567                            flag_group(
568                                flags = ["-Wl,--build-id=md5", "-Wl,--hash-style=gnu"],
569                            ),
570                        ],
571                    ),
572                ] if cpu == "local" else []) + ([
573                    flag_set(
574                        actions = all_link_actions(),
575                        flag_groups = [flag_group(flags = ["-undefined", "dynamic_lookup"])],
576                    ),
577                ] if cpu == "darwin" else []) + _cuda_set(
578                    ctx.attr.cuda_path,
579                    all_link_actions(),
580                ) + [
581                    flag_set(
582                        actions = all_link_actions(),
583                        flag_groups = [
584                            _sysroot_group(),
585                        ],
586                    ),
587                ],
588            ),
589            feature(name = "disable-assertions"),
590            feature(
591                name = "opt",
592                implies = ["disable-assertions"],
593            ),
594            feature(name = "fastbuild"),
595            feature(name = "dbg"),
596            feature(name = "supports_dynamic_linker", enabled = True),
597            feature(name = "pic", enabled = True),
598            feature(name = "supports_pic", enabled = True),
599            feature(name = "has_configured_linker_path", enabled = True),
600        ]
601    elif cpu == "x64_windows":
602        return [
603            feature(name = "no_legacy_features"),
604            feature(
605                name = "common_flags",
606                enabled = True,
607                env_sets = [
608                    env_set(
609                        actions = all_compile_actions() + all_link_actions() + all_archive_actions(),
610                        env_entries = [
611                            env_entry(key = "PATH", value = ctx.attr.msvc_env_path),
612                            env_entry(key = "INCLUDE", value = ctx.attr.msvc_env_include),
613                            env_entry(key = "LIB", value = ctx.attr.msvc_env_lib),
614                            env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp),
615                            env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp),
616                        ],
617                    ),
618                ],
619            ),
620            feature(
621                name = "all_compile_flags",
622                enabled = True,
623                flag_sets = [
624                    flag_set(
625                        actions = all_compile_actions(),
626                        flag_groups = [
627                            flag_group(
628                                flags = [
629                                    "-B",
630                                    "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py",
631                                ],
632                            ),
633                            _nologo(),
634                            flag_group(
635                                flags = [
636                                    "/DCOMPILER_MSVC",
637                                    "/DNOMINMAX",
638                                    "/D_WIN32_WINNT=0x0600",
639                                    "/D_CRT_SECURE_NO_DEPRECATE",
640                                    "/D_CRT_SECURE_NO_WARNINGS",
641                                    "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS",
642                                    "/bigobj",
643                                    "/Zm500",
644                                    "/J",
645                                    "/Gy",
646                                    "/GF",
647                                    "/EHsc",
648                                    "/wd4351",
649                                    "/wd4291",
650                                    "/wd4250",
651                                    "/wd4996",
652                                ],
653                            ),
654                            _iterate_flag_group(
655                                flags = ["/I%{quote_include_paths}"],
656                                iterate_over = "quote_include_paths",
657                            ),
658                            _iterate_flag_group(
659                                flags = ["/I%{include_paths}"],
660                                iterate_over = "include_paths",
661                            ),
662                            _iterate_flag_group(
663                                flags = ["/I%{system_include_paths}"],
664                                iterate_over = "system_include_paths",
665                            ),
666                            _iterate_flag_group(
667                                flags = ["/D%{preprocessor_defines}"],
668                                iterate_over = "preprocessor_defines",
669                            ),
670                        ],
671                    ),
672                    flag_set(
673                        actions = all_preprocessed_actions(),
674                        flag_groups = [flag_group(flags = ["/showIncludes"])],
675                    ),
676                    flag_set(
677                        actions = all_compile_actions(),
678                        flag_groups = [flag_group(flags = ["/MT"])],
679                        with_features = [with_feature_set(features = ["static_link_msvcrt_no_debug"])],
680                    ),
681                    flag_set(
682                        actions = all_compile_actions(),
683                        flag_groups = [flag_group(flags = ["/MD"])],
684                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_no_debug"])],
685                    ),
686                    flag_set(
687                        actions = all_compile_actions(),
688                        flag_groups = [flag_group(flags = ["/MTd"])],
689                        with_features = [with_feature_set(features = ["static_link_msvcrt_debug"])],
690                    ),
691                    flag_set(
692                        actions = all_compile_actions(),
693                        flag_groups = [flag_group(flags = ["/MDd"])],
694                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_debug"])],
695                    ),
696                    flag_set(
697                        actions = all_compile_actions(),
698                        flag_groups = [flag_group(flags = ["/Od", "/Z7", "/DDEBUG"])],
699                        with_features = [with_feature_set(features = ["dbg"])],
700                    ),
701                    flag_set(
702                        actions = all_compile_actions(),
703                        flag_groups = [flag_group(flags = ["/Od", "/Z7", "/DDEBUG"])],
704                        with_features = [with_feature_set(features = ["fastbuild"])],
705                    ),
706                    flag_set(
707                        actions = all_compile_actions(),
708                        flag_groups = [flag_group(flags = ["/O2", "/DNDEBUG"])],
709                        with_features = [with_feature_set(features = ["opt"])],
710                    ),
711                    flag_set(
712                        actions = all_preprocessed_actions(),
713                        flag_groups = [
714                            _iterate_flag_group(
715                                flags = ["%{user_compile_flags}"],
716                                iterate_over = "user_compile_flags",
717                            ),
718                        ] + ([
719                            flag_group(flags = ctx.attr.host_unfiltered_compile_flags),
720                        ] if ctx.attr.host_unfiltered_compile_flags else []),
721                    ),
722                    flag_set(
723                        actions = [ACTION_NAMES.assemble],
724                        flag_groups = [
725                            flag_group(
726                                flag_groups = [
727                                    flag_group(
728                                        flags = ["/Fo%{output_file}", "/Zi"],
729                                        expand_if_not_available = "output_preprocess_file",
730                                    ),
731                                ],
732                                expand_if_available = "output_file",
733                                expand_if_not_available = "output_assembly_file",
734                            ),
735                        ],
736                    ),
737                    flag_set(
738                        actions = all_preprocessed_actions(),
739                        flag_groups = [
740                            flag_group(
741                                flag_groups = [
742                                    flag_group(
743                                        flags = ["/Fo%{output_file}"],
744                                        expand_if_not_available = "output_preprocess_file",
745                                    ),
746                                ],
747                                expand_if_available = "output_file",
748                                expand_if_not_available = "output_assembly_file",
749                            ),
750                            flag_group(
751                                flag_groups = [
752                                    flag_group(
753                                        flags = ["/Fa%{output_file}"],
754                                        expand_if_available = "output_assembly_file",
755                                    ),
756                                ],
757                                expand_if_available = "output_file",
758                            ),
759                            flag_group(
760                                flag_groups = [
761                                    flag_group(
762                                        flags = ["/P", "/Fi%{output_file}"],
763                                        expand_if_available = "output_preprocess_file",
764                                    ),
765                                ],
766                                expand_if_available = "output_file",
767                            ),
768                        ],
769                    ),
770                    flag_set(
771                        actions = all_compile_actions(),
772                        flag_groups = [
773                            flag_group(
774                                flags = ["/c", "%{source_file}"],
775                                expand_if_available = "source_file",
776                            ),
777                        ],
778                    ),
779                ],
780            ),
781            feature(
782                name = "all_archive_flags",
783                enabled = True,
784                flag_sets = [
785                    flag_set(
786                        actions = all_archive_actions(),
787                        flag_groups = [
788                            _nologo(),
789                            flag_group(
790                                flags = ["/OUT:%{output_execpath}"],
791                                expand_if_available = "output_execpath",
792                            ),
793                        ],
794                    ),
795                ],
796            ),
797            feature(
798                name = "all_link_flags",
799                enabled = True,
800                flag_sets = [
801                    flag_set(
802                        actions = all_shared_library_link_actions(),
803                        flag_groups = [flag_group(flags = ["/DLL"])],
804                    ),
805                    flag_set(
806                        actions = all_link_actions(),
807                        flag_groups = [
808                            _nologo(),
809                            _iterate_flag_group(
810                                flags = ["%{linkstamp_paths}"],
811                                iterate_over = "linkstamp_paths",
812                            ),
813                            flag_group(
814                                flags = ["/OUT:%{output_execpath}"],
815                                expand_if_available = "output_execpath",
816                            ),
817                        ],
818                    ),
819                    flag_set(
820                        actions = all_shared_library_link_actions(),
821                        flag_groups = [
822                            flag_group(
823                                flags = ["/IMPLIB:%{interface_library_output_path}"],
824                                expand_if_available = "interface_library_output_path",
825                            ),
826                        ],
827                    ),
828                    flag_set(
829                        actions = all_link_actions() +
830                                  all_archive_actions(),
831                        flag_groups = [
832                            _libraries_to_link_group("msvc"),
833                        ],
834                    ),
835                    flag_set(
836                        actions = all_link_actions(),
837                        flag_groups = [
838                            flag_group(flags = ["/SUBSYSTEM:CONSOLE"]),
839                            _iterate_flag_group(
840                                flags = ["%{user_link_flags}"],
841                                iterate_over = "user_link_flags",
842                            ),
843                            flag_group(flags = ["/MACHINE:X64"]),
844                        ],
845                    ),
846                    flag_set(
847                        actions = all_link_actions() +
848                                  all_archive_actions(),
849                        flag_groups = [
850                            flag_group(
851                                flags = ["@%{linker_param_file}"],
852                                expand_if_available = "linker_param_file",
853                            ),
854                        ],
855                    ),
856                    flag_set(
857                        actions = all_link_actions(),
858                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])],
859                        with_features = [with_feature_set(features = ["static_link_msvcrt_no_debug"])],
860                    ),
861                    flag_set(
862                        actions = all_link_actions(),
863                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])],
864                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_no_debug"])],
865                    ),
866                    flag_set(
867                        actions = all_link_actions(),
868                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])],
869                        with_features = [with_feature_set(features = ["static_link_msvcrt_debug"])],
870                    ),
871                    flag_set(
872                        actions = all_link_actions(),
873                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])],
874                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_debug"])],
875                    ),
876                    flag_set(
877                        actions = all_link_actions(),
878                        flag_groups = [flag_group(flags = ["/DEBUG:FULL", "/INCREMENTAL:NO"])],
879                        with_features = [with_feature_set(features = ["dbg"])],
880                    ),
881                    flag_set(
882                        actions = all_link_actions(),
883                        flag_groups = [
884                            flag_group(flags = ["/DEBUG:FASTLINK", "/INCREMENTAL:NO"]),
885                        ],
886                        with_features = [with_feature_set(features = ["fastbuild"])],
887                    ),
888                    flag_set(
889                        actions = all_link_actions(),
890                        flag_groups = [
891                            flag_group(
892                                flags = ["/DEF:%{def_file_path}", "/ignore:4070"],
893                                expand_if_available = "def_file_path",
894                            ),
895                        ],
896                    ),
897                ],
898            ),
899            feature(name = "parse_showincludes", enabled = True),
900            feature(name = "no_stripping", enabled = True),
901            feature(
902                name = "targets_windows",
903                enabled = True,
904                implies = ["copy_dynamic_libraries_to_binary"],
905            ),
906            feature(name = "copy_dynamic_libraries_to_binary"),
907            feature(
908                name = "generate_pdb_file",
909                requires = [
910                    feature_set(features = ["dbg"]),
911                    feature_set(features = ["fastbuild"]),
912                ],
913            ),
914            feature(name = "static_link_msvcrt"),
915            feature(
916                name = "static_link_msvcrt_no_debug",
917                requires = [
918                    feature_set(features = ["fastbuild"]),
919                    feature_set(features = ["opt"]),
920                ],
921            ),
922            feature(
923                name = "dynamic_link_msvcrt_no_debug",
924                requires = [
925                    feature_set(features = ["fastbuild"]),
926                    feature_set(features = ["opt"]),
927                ],
928            ),
929            feature(
930                name = "static_link_msvcrt_debug",
931                requires = [feature_set(features = ["dbg"])],
932            ),
933            feature(
934                name = "dynamic_link_msvcrt_debug",
935                requires = [feature_set(features = ["dbg"])],
936            ),
937            feature(
938                name = "dbg",
939                implies = ["generate_pdb_file"],
940            ),
941            feature(
942                name = "fastbuild",
943                implies = ["generate_pdb_file"],
944            ),
945            feature(
946                name = "opt",
947            ),
948            feature(name = "windows_export_all_symbols"),
949            feature(name = "no_windows_export_all_symbols"),
950            feature(name = "supports_dynamic_linker", enabled = True),
951            feature(
952                name = "supports_interface_shared_libraries",
953                enabled = True,
954            ),
955            feature(name = "has_configured_linker_path", enabled = True),
956        ]
957    else:
958        fail("Unreachable")
959
960def _impl(ctx):
961    cpu = ctx.attr.cpu
962    compiler = ctx.attr.compiler
963
964    if (cpu == "darwin"):
965        toolchain_identifier = "local_darwin"
966        target_cpu = "darwin"
967        target_libc = "macosx"
968        compiler = "compiler"
969        action_configs = _action_configs(
970            assembly_path = ctx.attr.host_compiler_path,
971            c_compiler_path = ctx.attr.host_compiler_path,
972            cc_compiler_path = ctx.attr.host_compiler_path,
973            archiver_path = ctx.attr.host_compiler_prefix + "/libtool",
974            linker_path = ctx.attr.host_compiler_path,
975            strip_path = ctx.attr.host_compiler_prefix + "/strip",
976        )
977        artifact_name_patterns = []
978    elif (cpu == "local"):
979        toolchain_identifier = "local_linux"
980        target_cpu = "local"
981        target_libc = "local"
982        action_configs = _action_configs(
983            assembly_path = ctx.attr.host_compiler_path,
984            c_compiler_path = ctx.attr.host_compiler_path,
985            cc_compiler_path = ctx.attr.host_compiler_path,
986            archiver_path = ctx.attr.host_compiler_prefix + "/ar",
987            linker_path = ctx.attr.host_compiler_path,
988            strip_path = ctx.attr.host_compiler_prefix + "/strip",
989        )
990        artifact_name_patterns = []
991    elif (cpu == "x64_windows"):
992        toolchain_identifier = "local_windows"
993        target_cpu = "x64_windows"
994        target_libc = "msvcrt"
995        compiler = "msvc-cl"
996        action_configs = _action_configs(
997            assembly_path = ctx.attr.msvc_ml_path,
998            c_compiler_path = ctx.attr.msvc_cl_path,
999            cc_compiler_path = ctx.attr.msvc_cl_path,
1000            archiver_path = ctx.attr.msvc_lib_path,
1001            linker_path = ctx.attr.msvc_link_path,
1002            strip_path = "fake_tool_strip_not_supported",
1003        )
1004        artifact_name_patterns = [
1005            artifact_name_pattern(
1006                category_name = "object_file",
1007                prefix = "",
1008                extension = ".obj",
1009            ),
1010            artifact_name_pattern(
1011                category_name = "static_library",
1012                prefix = "",
1013                extension = ".lib",
1014            ),
1015            artifact_name_pattern(
1016                category_name = "alwayslink_static_library",
1017                prefix = "",
1018                extension = ".lo.lib",
1019            ),
1020            artifact_name_pattern(
1021                category_name = "executable",
1022                prefix = "",
1023                extension = ".exe",
1024            ),
1025            artifact_name_pattern(
1026                category_name = "dynamic_library",
1027                prefix = "",
1028                extension = ".dll",
1029            ),
1030            artifact_name_pattern(
1031                category_name = "interface_library",
1032                prefix = "",
1033                extension = ".if.lib",
1034            ),
1035        ]
1036    else:
1037        fail("Unreachable")
1038
1039    out = ctx.actions.declare_file(ctx.label.name)
1040    ctx.actions.write(out, "Fake executable")
1041    return [
1042        cc_common.create_cc_toolchain_config_info(
1043            ctx = ctx,
1044            features = _features(cpu, compiler, ctx),
1045            action_configs = action_configs,
1046            artifact_name_patterns = artifact_name_patterns,
1047            cxx_builtin_include_directories = ctx.attr.builtin_include_directories,
1048            toolchain_identifier = toolchain_identifier,
1049            host_system_name = "local",
1050            target_system_name = "local",
1051            target_cpu = target_cpu,
1052            target_libc = target_libc,
1053            compiler = compiler,
1054            abi_version = "local",
1055            abi_libc_version = "local",
1056            tool_paths = _tool_paths(cpu, ctx),
1057            make_variables = [],
1058            builtin_sysroot = ctx.attr.builtin_sysroot,
1059            cc_target_os = None,
1060        ),
1061        DefaultInfo(
1062            executable = out,
1063        ),
1064    ]
1065
1066cc_toolchain_config = rule(
1067    implementation = _impl,
1068    attrs = {
1069        "cpu": attr.string(mandatory = True, values = ["darwin", "local", "x64_windows"]),
1070        "compiler": attr.string(values = ["clang", "msvc", "unknown"], default = "unknown"),
1071        "builtin_include_directories": attr.string_list(),
1072        "extra_no_canonical_prefixes_flags": attr.string_list(),
1073        "host_compiler_path": attr.string(),
1074        "host_compiler_prefix": attr.string(),
1075        "host_compiler_warnings": attr.string_list(),
1076        "host_unfiltered_compile_flags": attr.string_list(),
1077        "linker_bin_path": attr.string(),
1078        "builtin_sysroot": attr.string(),
1079        "cuda_path": attr.string(),
1080        "msvc_cl_path": attr.string(default = "msvc_not_used"),
1081        "msvc_env_include": attr.string(default = "msvc_not_used"),
1082        "msvc_env_lib": attr.string(default = "msvc_not_used"),
1083        "msvc_env_path": attr.string(default = "msvc_not_used"),
1084        "msvc_env_tmp": attr.string(default = "msvc_not_used"),
1085        "msvc_lib_path": attr.string(default = "msvc_not_used"),
1086        "msvc_link_path": attr.string(default = "msvc_not_used"),
1087        "msvc_ml_path": attr.string(default = "msvc_not_used"),
1088    },
1089    provides = [CcToolchainConfigInfo],
1090    executable = True,
1091)
1092