• 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 = ["-fexperimental-new-pass-manager"]),
357                        ] if compiler == "clang" else [],
358                    ),
359                    flag_set(
360                        actions = all_compile_actions(),
361                        flag_groups = [
362                            flag_group(
363                                flags = [
364                                    "-Wno-builtin-macro-redefined",
365                                    "-D__DATE__=\"redacted\"",
366                                    "-D__TIMESTAMP__=\"redacted\"",
367                                    "-D__TIME__=\"redacted\"",
368                                ],
369                            ),
370                            flag_group(
371                                flags = ["-fPIC"],
372                                expand_if_available = "pic",
373                            ),
374                            flag_group(
375                                flags = ["-fPIE"],
376                                expand_if_not_available = "pic",
377                            ),
378                            flag_group(
379                                flags = [
380                                    "-U_FORTIFY_SOURCE",
381                                    "-D_FORTIFY_SOURCE=1",
382                                    "-fstack-protector",
383                                    "-Wall",
384                                ] + ctx.attr.host_compiler_warnings + [
385                                    "-fno-omit-frame-pointer",
386                                ],
387                            ),
388                            _no_canonical_prefixes_group(
389                                ctx.attr.extra_no_canonical_prefixes_flags,
390                            ),
391                        ],
392                    ),
393                    flag_set(
394                        actions = all_compile_actions(),
395                        flag_groups = [flag_group(flags = ["-DNDEBUG"])],
396                        with_features = [with_feature_set(features = ["disable-assertions"])],
397                    ),
398                    flag_set(
399                        actions = all_compile_actions(),
400                        flag_groups = [
401                            flag_group(
402                                flags = [
403                                    "-g0",
404                                    "-O2",
405                                    "-ffunction-sections",
406                                    "-fdata-sections",
407                                ],
408                            ),
409                        ],
410                        with_features = [with_feature_set(features = ["opt"])],
411                    ),
412                    flag_set(
413                        actions = all_compile_actions(),
414                        flag_groups = [flag_group(flags = ["-g"])],
415                        with_features = [with_feature_set(features = ["dbg"])],
416                    ),
417                ] + _cuda_set(
418                    ctx.attr.cuda_path,
419                    all_compile_actions(),
420                ) + [
421                    flag_set(
422                        actions = all_compile_actions(),
423                        flag_groups = [
424                            _iterate_flag_group(
425                                flags = ["%{user_compile_flags}"],
426                                iterate_over = "user_compile_flags",
427                            ),
428                            _sysroot_group(),
429                            flag_group(
430                                expand_if_available = "source_file",
431                                flags = ["-c", "%{source_file}"],
432                            ),
433                            flag_group(
434                                expand_if_available = "output_assembly_file",
435                                flags = ["-S"],
436                            ),
437                            flag_group(
438                                expand_if_available = "output_preprocess_file",
439                                flags = ["-E"],
440                            ),
441                            flag_group(
442                                expand_if_available = "output_file",
443                                flags = ["-o", "%{output_file}"],
444                            ),
445                        ],
446                    ),
447                ],
448            ),
449            feature(
450                name = "all_archive_flags",
451                enabled = True,
452                flag_sets = [
453                    flag_set(
454                        actions = all_archive_actions(),
455                        flag_groups = [
456                            flag_group(
457                                expand_if_available = "linker_param_file",
458                                flags = ["@%{linker_param_file}"],
459                            ),
460                            flag_group(flags = ["rcsD"]),
461                            flag_group(
462                                flags = ["%{output_execpath}"],
463                                expand_if_available = "output_execpath",
464                            ),
465                            flag_group(
466                                iterate_over = "libraries_to_link",
467                                flag_groups = [
468                                    flag_group(
469                                        flags = ["%{libraries_to_link.name}"],
470                                        expand_if_equal = variable_with_value(
471                                            name = "libraries_to_link.type",
472                                            value = "object_file",
473                                        ),
474                                    ),
475                                    flag_group(
476                                        flags = ["%{libraries_to_link.object_files}"],
477                                        iterate_over = "libraries_to_link.object_files",
478                                        expand_if_equal = variable_with_value(
479                                            name = "libraries_to_link.type",
480                                            value = "object_file_group",
481                                        ),
482                                    ),
483                                ],
484                                expand_if_available = "libraries_to_link",
485                            ),
486                        ],
487                    ),
488                ],
489            ),
490            feature(
491                name = "all_link_flags",
492                enabled = True,
493                flag_sets = [
494                    flag_set(
495                        actions = all_shared_library_link_actions(),
496                        flag_groups = [flag_group(flags = ["-shared"])],
497                    ),
498                    flag_set(
499                        actions = all_link_actions(),
500                        flag_groups = ([
501                            flag_group(flags = ["-Wl,-no-as-needed"])
502                        ] if cpu == "local" else []) + ([
503                            flag_group(flags = ["-B" + ctx.attr.linker_bin_path])
504                        ] if ctx.attr.linker_bin_path else []) + [
505                            flag_group(
506                                flags = ["@%{linker_param_file}"],
507                                expand_if_available = "linker_param_file",
508                            ),
509                            _iterate_flag_group(
510                                flags = ["%{linkstamp_paths}"],
511                                iterate_over = "linkstamp_paths",
512                            ),
513                            flag_group(
514                                flags = ["-o", "%{output_execpath}"],
515                                expand_if_available = "output_execpath",
516                            ),
517                            _iterate_flag_group(
518                                flags = ["-L%{library_search_directories}"],
519                                iterate_over = "library_search_directories",
520                            ),
521                            _iterate_flag_group(
522                                iterate_over = "runtime_library_search_directories",
523                                flags = [
524                                    "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
525                                ] if cpu == "local" else [
526                                    "-Wl,-rpath,@loader_path/%{runtime_library_search_directories}",
527                                ],
528                            ),
529                            _libraries_to_link_group("darwin" if cpu == "darwin" else "linux"),
530                            _iterate_flag_group(
531                                flags = ["%{user_link_flags}"],
532                                iterate_over = "user_link_flags",
533                            ),
534                            flag_group(
535                                flags = ["-Wl,--gdb-index"],
536                                expand_if_available = "is_using_fission",
537                            ),
538                            flag_group(
539                                flags = ["-Wl,-S"],
540                                expand_if_available = "strip_debug_symbols",
541                            ),
542                            flag_group(flags = ["-lc++" if cpu == "darwin" else "-lstdc++"]),
543                            _no_canonical_prefixes_group(
544                                ctx.attr.extra_no_canonical_prefixes_flags,
545                            ),
546                        ],
547                    ),
548                    flag_set(
549                        actions = all_executable_link_actions(),
550                        flag_groups = [flag_group(flags = ["-pie"])],
551                    ),
552                ] + ([
553                    flag_set(
554                        actions = all_link_actions(),
555                        flag_groups = [flag_group(flags = [
556                            "-Wl,-z,relro,-z,now",
557                        ])],
558                    ),
559                ] if cpu == "local" else []) + ([
560                    flag_set(
561                        actions = all_link_actions(),
562                        flag_groups = [
563                            flag_group(flags = ["-Wl,--gc-sections"]),
564                            flag_group(
565                                flags = ["-Wl,--build-id=md5", "-Wl,--hash-style=gnu"],
566                            ),
567                        ],
568                    ),
569                ] if cpu == "local" else []) + ([
570                    flag_set(
571                        actions = all_link_actions(),
572                        flag_groups = [flag_group(flags = ["-undefined", "dynamic_lookup"])],
573                    ),
574                ] if cpu == "darwin" else []) + _cuda_set(
575                    ctx.attr.cuda_path,
576                    all_link_actions(),
577                ) + [
578                    flag_set(
579                        actions = all_link_actions(),
580                        flag_groups = [
581                            _sysroot_group(),
582                        ],
583                    ),
584                ],
585            ),
586            feature(name = "disable-assertions"),
587            feature(
588                name = "opt",
589                implies = ["disable-assertions"],
590            ),
591            feature(name = "fastbuild"),
592            feature(name = "dbg"),
593            feature(name = "supports_dynamic_linker", enabled = True),
594            feature(name = "pic", enabled = True),
595            feature(name = "supports_pic", enabled = True),
596            feature(name = "has_configured_linker_path", enabled = True),
597        ]
598    elif cpu == "x64_windows":
599        return [
600            feature(name = "no_legacy_features"),
601            feature(
602                name = "common_flags",
603                enabled = True,
604                env_sets = [
605                    env_set(
606                        actions = all_compile_actions() + all_link_actions() + all_archive_actions(),
607                        env_entries = [
608                            env_entry(key = "PATH", value = ctx.attr.msvc_env_path),
609                            env_entry(key = "INCLUDE", value = ctx.attr.msvc_env_include),
610                            env_entry(key = "LIB", value = ctx.attr.msvc_env_lib),
611                            env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp),
612                            env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp),
613                        ],
614                    ),
615                ],
616            ),
617            feature(
618                name = "all_compile_flags",
619                enabled = True,
620                flag_sets = [
621                    flag_set(
622                        actions = all_compile_actions(),
623                        flag_groups = [
624                            flag_group(
625                                flags = [
626                                    "-B",
627                                    "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py",
628                                ],
629                            ),
630                            _nologo(),
631                            flag_group(
632                                flags = [
633                                    "/DCOMPILER_MSVC",
634                                    "/DNOMINMAX",
635                                    "/D_WIN32_WINNT=0x0600",
636                                    "/D_CRT_SECURE_NO_DEPRECATE",
637                                    "/D_CRT_SECURE_NO_WARNINGS",
638                                    "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS",
639                                    "/bigobj",
640                                    "/Zm500",
641                                    "/J",
642                                    "/Gy",
643                                    "/GF",
644                                    "/EHsc",
645                                    "/wd4351",
646                                    "/wd4291",
647                                    "/wd4250",
648                                    "/wd4996",
649                                ],
650                            ),
651                            _iterate_flag_group(
652                                flags = ["/I%{quote_include_paths}"],
653                                iterate_over = "quote_include_paths",
654                            ),
655                            _iterate_flag_group(
656                                flags = ["/I%{include_paths}"],
657                                iterate_over = "include_paths",
658                            ),
659                            _iterate_flag_group(
660                                flags = ["/I%{system_include_paths}"],
661                                iterate_over = "system_include_paths",
662                            ),
663                            _iterate_flag_group(
664                                flags = ["/D%{preprocessor_defines}"],
665                                iterate_over = "preprocessor_defines",
666                            ),
667                        ],
668                    ),
669                    flag_set(
670                        actions = all_preprocessed_actions(),
671                        flag_groups = [flag_group(flags = ["/showIncludes"])],
672                    ),
673                    flag_set(
674                        actions = all_compile_actions(),
675                        flag_groups = [flag_group(flags = ["/MT"])],
676                        with_features = [with_feature_set(features = ["static_link_msvcrt_no_debug"])],
677                    ),
678                    flag_set(
679                        actions = all_compile_actions(),
680                        flag_groups = [flag_group(flags = ["/MD"])],
681                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_no_debug"])],
682                    ),
683                    flag_set(
684                        actions = all_compile_actions(),
685                        flag_groups = [flag_group(flags = ["/MTd"])],
686                        with_features = [with_feature_set(features = ["static_link_msvcrt_debug"])],
687                    ),
688                    flag_set(
689                        actions = all_compile_actions(),
690                        flag_groups = [flag_group(flags = ["/MDd"])],
691                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_debug"])],
692                    ),
693                    flag_set(
694                        actions = all_compile_actions(),
695                        flag_groups = [flag_group(flags = ["/Od", "/Z7", "/DDEBUG"])],
696                        with_features = [with_feature_set(features = ["dbg"])],
697                    ),
698                    flag_set(
699                        actions = all_compile_actions(),
700                        flag_groups = [flag_group(flags = ["/Od", "/Z7", "/DDEBUG"])],
701                        with_features = [with_feature_set(features = ["fastbuild"])],
702                    ),
703                    flag_set(
704                        actions = all_compile_actions(),
705                        flag_groups = [flag_group(flags = ["/O2", "/DNDEBUG"])],
706                        with_features = [with_feature_set(features = ["opt"])],
707                    ),
708                    flag_set(
709                        actions = all_preprocessed_actions(),
710                        flag_groups = [
711                            _iterate_flag_group(
712                                flags = ["%{user_compile_flags}"],
713                                iterate_over = "user_compile_flags",
714                            ),
715                        ] + ([
716                            flag_group(flags = ctx.attr.host_unfiltered_compile_flags),
717                        ] if ctx.attr.host_unfiltered_compile_flags else []),
718                    ),
719                    flag_set(
720                        actions = [ACTION_NAMES.assemble],
721                        flag_groups = [
722                            flag_group(
723                                flag_groups = [
724                                    flag_group(
725                                        flags = ["/Fo%{output_file}", "/Zi"],
726                                        expand_if_not_available = "output_preprocess_file",
727                                    ),
728                                ],
729                                expand_if_available = "output_file",
730                                expand_if_not_available = "output_assembly_file",
731                            ),
732                        ],
733                    ),
734                    flag_set(
735                        actions = all_preprocessed_actions(),
736                        flag_groups = [
737                            flag_group(
738                                flag_groups = [
739                                    flag_group(
740                                        flags = ["/Fo%{output_file}"],
741                                        expand_if_not_available = "output_preprocess_file",
742                                    ),
743                                ],
744                                expand_if_available = "output_file",
745                                expand_if_not_available = "output_assembly_file",
746                            ),
747                            flag_group(
748                                flag_groups = [
749                                    flag_group(
750                                        flags = ["/Fa%{output_file}"],
751                                        expand_if_available = "output_assembly_file",
752                                    ),
753                                ],
754                                expand_if_available = "output_file",
755                            ),
756                            flag_group(
757                                flag_groups = [
758                                    flag_group(
759                                        flags = ["/P", "/Fi%{output_file}"],
760                                        expand_if_available = "output_preprocess_file",
761                                    ),
762                                ],
763                                expand_if_available = "output_file",
764                            ),
765                        ],
766                    ),
767                    flag_set(
768                        actions = all_compile_actions(),
769                        flag_groups = [
770                            flag_group(
771                                flags = ["/c", "%{source_file}"],
772                                expand_if_available = "source_file",
773                            ),
774                        ],
775                    ),
776                ],
777            ),
778            feature(
779                name = "all_archive_flags",
780                enabled = True,
781                flag_sets = [
782                    flag_set(
783                        actions = all_archive_actions(),
784                        flag_groups = [
785                            _nologo(),
786                            flag_group(
787                                flags = ["/OUT:%{output_execpath}"],
788                                expand_if_available = "output_execpath",
789                            ),
790                        ],
791                    ),
792                ],
793            ),
794            feature(
795                name = "all_link_flags",
796                enabled = True,
797                flag_sets = [
798                    flag_set(
799                        actions = all_shared_library_link_actions(),
800                        flag_groups = [flag_group(flags = ["/DLL"])],
801                    ),
802                    flag_set(
803                        actions = all_link_actions(),
804                        flag_groups = [
805                            _nologo(),
806                            _iterate_flag_group(
807                                flags = ["%{linkstamp_paths}"],
808                                iterate_over = "linkstamp_paths",
809                            ),
810                            flag_group(
811                                flags = ["/OUT:%{output_execpath}"],
812                                expand_if_available = "output_execpath",
813                            ),
814                        ],
815                    ),
816                    flag_set(
817                        actions = all_shared_library_link_actions(),
818                        flag_groups = [
819                            flag_group(
820                                flags = ["/IMPLIB:%{interface_library_output_path}"],
821                                expand_if_available = "interface_library_output_path",
822                            ),
823                        ],
824                    ),
825                    flag_set(
826                        actions = all_link_actions() +
827                                  all_archive_actions(),
828                        flag_groups = [
829                            _libraries_to_link_group("msvc"),
830                        ],
831                    ),
832                    flag_set(
833                        actions = all_link_actions(),
834                        flag_groups = [
835                            flag_group(flags = ["/SUBSYSTEM:CONSOLE"]),
836                            _iterate_flag_group(
837                                flags = ["%{user_link_flags}"],
838                                iterate_over = "user_link_flags",
839                            ),
840                            flag_group(flags = ["/MACHINE:X64"]),
841                        ],
842                    ),
843                    flag_set(
844                        actions = all_link_actions() +
845                                  all_archive_actions(),
846                        flag_groups = [
847                            flag_group(
848                                flags = ["@%{linker_param_file}"],
849                                expand_if_available = "linker_param_file",
850                            ),
851                        ],
852                    ),
853                    flag_set(
854                        actions = all_link_actions(),
855                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])],
856                        with_features = [with_feature_set(features = ["static_link_msvcrt_no_debug"])],
857                    ),
858                    flag_set(
859                        actions = all_link_actions(),
860                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])],
861                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_no_debug"])],
862                    ),
863                    flag_set(
864                        actions = all_link_actions(),
865                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])],
866                        with_features = [with_feature_set(features = ["static_link_msvcrt_debug"])],
867                    ),
868                    flag_set(
869                        actions = all_link_actions(),
870                        flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])],
871                        with_features = [with_feature_set(features = ["dynamic_link_msvcrt_debug"])],
872                    ),
873                    flag_set(
874                        actions = all_link_actions(),
875                        flag_groups = [flag_group(flags = ["/DEBUG:FULL", "/INCREMENTAL:NO"])],
876                        with_features = [with_feature_set(features = ["dbg"])],
877                    ),
878                    flag_set(
879                        actions = all_link_actions(),
880                        flag_groups = [
881                            flag_group(flags = ["/DEBUG:FASTLINK", "/INCREMENTAL:NO"]),
882                        ],
883                        with_features = [with_feature_set(features = ["fastbuild"])],
884                    ),
885                    flag_set(
886                        actions = all_link_actions(),
887                        flag_groups = [
888                            flag_group(
889                                flags = ["/DEF:%{def_file_path}", "/ignore:4070"],
890                                expand_if_available = "def_file_path",
891                            ),
892                        ],
893                    ),
894                ],
895            ),
896            feature(name = "parse_showincludes", enabled = True),
897            feature(name = "no_stripping", enabled = True),
898            feature(
899                name = "targets_windows",
900                enabled = True,
901                implies = ["copy_dynamic_libraries_to_binary"],
902            ),
903            feature(name = "copy_dynamic_libraries_to_binary"),
904            feature(
905                name = "generate_pdb_file",
906                requires = [
907                    feature_set(features = ["dbg"]),
908                    feature_set(features = ["fastbuild"]),
909                ],
910            ),
911            feature(name = "static_link_msvcrt"),
912            feature(
913                name = "static_link_msvcrt_no_debug",
914                requires = [
915                    feature_set(features = ["fastbuild"]),
916                    feature_set(features = ["opt"]),
917                ],
918            ),
919            feature(
920                name = "dynamic_link_msvcrt_no_debug",
921                requires = [
922                    feature_set(features = ["fastbuild"]),
923                    feature_set(features = ["opt"]),
924                ],
925            ),
926            feature(
927                name = "static_link_msvcrt_debug",
928                requires = [feature_set(features = ["dbg"])],
929            ),
930            feature(
931                name = "dynamic_link_msvcrt_debug",
932                requires = [feature_set(features = ["dbg"])],
933            ),
934            feature(
935                name = "dbg",
936                implies = ["generate_pdb_file"],
937            ),
938            feature(
939                name = "fastbuild",
940                implies = ["generate_pdb_file"],
941            ),
942            feature(
943                name = "opt",
944            ),
945            feature(name = "windows_export_all_symbols"),
946            feature(name = "no_windows_export_all_symbols"),
947            feature(name = "supports_dynamic_linker", enabled = True),
948            feature(
949                name = "supports_interface_shared_libraries",
950                enabled = True,
951            ),
952            feature(name = "has_configured_linker_path", enabled = True),
953        ]
954    else:
955        fail("Unreachable")
956
957def _impl(ctx):
958    cpu = ctx.attr.cpu
959    compiler = ctx.attr.compiler
960
961    if (cpu == "darwin"):
962        toolchain_identifier = "local_darwin"
963        target_cpu = "darwin"
964        target_libc = "macosx"
965        compiler = "compiler"
966        action_configs = _action_configs(
967            assembly_path = ctx.attr.host_compiler_path,
968            c_compiler_path = ctx.attr.host_compiler_path,
969            cc_compiler_path = ctx.attr.host_compiler_path,
970            archiver_path = ctx.attr.host_compiler_prefix + "/libtool",
971            linker_path = ctx.attr.host_compiler_path,
972            strip_path = ctx.attr.host_compiler_prefix + "/strip",
973        )
974        artifact_name_patterns = []
975    elif (cpu == "local"):
976        toolchain_identifier = "local_linux"
977        target_cpu = "local"
978        target_libc = "local"
979        compiler = "compiler"
980        action_configs = _action_configs(
981            assembly_path = ctx.attr.host_compiler_path,
982            c_compiler_path = ctx.attr.host_compiler_path,
983            cc_compiler_path = ctx.attr.host_compiler_path,
984            archiver_path = ctx.attr.host_compiler_prefix + "/ar",
985            linker_path = ctx.attr.host_compiler_path,
986            strip_path = ctx.attr.host_compiler_prefix + "/strip",
987        )
988        artifact_name_patterns = []
989    elif (cpu == "x64_windows"):
990        toolchain_identifier = "local_windows"
991        target_cpu = "x64_windows"
992        target_libc = "msvcrt"
993        compiler = "msvc-cl"
994        action_configs = _action_configs(
995            assembly_path = ctx.attr.msvc_ml_path,
996            c_compiler_path = ctx.attr.msvc_cl_path,
997            cc_compiler_path = ctx.attr.msvc_cl_path,
998            archiver_path = ctx.attr.msvc_lib_path,
999            linker_path = ctx.attr.msvc_link_path,
1000            strip_path = "fake_tool_strip_not_supported",
1001        )
1002        artifact_name_patterns = [
1003            artifact_name_pattern(
1004                category_name = "object_file",
1005                prefix = "",
1006                extension = ".obj",
1007            ),
1008            artifact_name_pattern(
1009                category_name = "static_library",
1010                prefix = "",
1011                extension = ".lib",
1012            ),
1013            artifact_name_pattern(
1014                category_name = "alwayslink_static_library",
1015                prefix = "",
1016                extension = ".lo.lib",
1017            ),
1018            artifact_name_pattern(
1019                category_name = "executable",
1020                prefix = "",
1021                extension = ".exe",
1022            ),
1023            artifact_name_pattern(
1024                category_name = "dynamic_library",
1025                prefix = "",
1026                extension = ".dll",
1027            ),
1028            artifact_name_pattern(
1029                category_name = "interface_library",
1030                prefix = "",
1031                extension = ".if.lib",
1032            ),
1033        ]
1034    else:
1035        fail("Unreachable")
1036
1037    out = ctx.actions.declare_file(ctx.label.name)
1038    ctx.actions.write(out, "Fake executable")
1039    return [
1040        cc_common.create_cc_toolchain_config_info(
1041            ctx = ctx,
1042            features = _features(cpu, compiler, ctx),
1043            action_configs = action_configs,
1044            artifact_name_patterns = artifact_name_patterns,
1045            cxx_builtin_include_directories = ctx.attr.builtin_include_directories,
1046            toolchain_identifier = toolchain_identifier,
1047            host_system_name = "local",
1048            target_system_name = "local",
1049            target_cpu = target_cpu,
1050            target_libc = target_libc,
1051            compiler = compiler,
1052            abi_version = "local",
1053            abi_libc_version = "local",
1054            tool_paths = _tool_paths(cpu, ctx),
1055            make_variables = [],
1056            builtin_sysroot = ctx.attr.builtin_sysroot,
1057            cc_target_os = None,
1058        ),
1059        DefaultInfo(
1060            executable = out,
1061        ),
1062    ]
1063
1064cc_toolchain_config = rule(
1065    implementation = _impl,
1066    attrs = {
1067        "cpu": attr.string(mandatory = True, values = ["darwin", "local", "x64_windows"]),
1068        "compiler": attr.string(values = ["clang", "msvc", "unknown"], default = "unknown"),
1069        "builtin_include_directories": attr.string_list(),
1070        "extra_no_canonical_prefixes_flags": attr.string_list(),
1071        "host_compiler_path": attr.string(),
1072        "host_compiler_prefix": attr.string(),
1073        "host_compiler_warnings": attr.string_list(),
1074        "host_unfiltered_compile_flags": attr.string_list(),
1075        "linker_bin_path": attr.string(),
1076        "builtin_sysroot": attr.string(),
1077        "cuda_path": attr.string(),
1078        "msvc_cl_path": attr.string(default = "msvc_not_used"),
1079        "msvc_env_include": attr.string(default = "msvc_not_used"),
1080        "msvc_env_lib": attr.string(default = "msvc_not_used"),
1081        "msvc_env_path": attr.string(default = "msvc_not_used"),
1082        "msvc_env_tmp": attr.string(default = "msvc_not_used"),
1083        "msvc_lib_path": attr.string(default = "msvc_not_used"),
1084        "msvc_link_path": attr.string(default = "msvc_not_used"),
1085        "msvc_ml_path": attr.string(default = "msvc_not_used"),
1086    },
1087    provides = [CcToolchainConfigInfo],
1088    executable = True,
1089)
1090