• 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    "env_entry",
7    "env_set",
8    "feature",
9    "feature_set",
10    "flag_group",
11    "flag_set",
12    "tool",
13    "tool_path",
14    "variable_with_value",
15)
16load(
17    "@bazel_tools//tools/build_defs/cc:action_names.bzl",
18    "ASSEMBLE_ACTION_NAME",
19    "CC_FLAGS_MAKE_VARIABLE_ACTION_NAME",
20    "CLIF_MATCH_ACTION_NAME",
21    "CPP_COMPILE_ACTION_NAME",
22    "CPP_HEADER_PARSING_ACTION_NAME",
23    "CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME",
24    "CPP_LINK_EXECUTABLE_ACTION_NAME",
25    "CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME",
26    "CPP_LINK_STATIC_LIBRARY_ACTION_NAME",
27    "CPP_MODULE_CODEGEN_ACTION_NAME",
28    "CPP_MODULE_COMPILE_ACTION_NAME",
29    "C_COMPILE_ACTION_NAME",
30    "LINKSTAMP_COMPILE_ACTION_NAME",
31    "LTO_BACKEND_ACTION_NAME",
32    "LTO_INDEXING_ACTION_NAME",
33    "OBJCPP_COMPILE_ACTION_NAME",
34    "OBJCPP_EXECUTABLE_ACTION_NAME",
35    "OBJC_ARCHIVE_ACTION_NAME",
36    "OBJC_COMPILE_ACTION_NAME",
37    "OBJC_EXECUTABLE_ACTION_NAME",
38    "OBJC_FULLY_LINK_ACTION_NAME",
39    "PREPROCESS_ASSEMBLE_ACTION_NAME",
40    "STRIP_ACTION_NAME",
41)
42
43ACTION_NAMES = struct(
44    c_compile = C_COMPILE_ACTION_NAME,
45    cpp_compile = CPP_COMPILE_ACTION_NAME,
46    linkstamp_compile = LINKSTAMP_COMPILE_ACTION_NAME,
47    cc_flags_make_variable = CC_FLAGS_MAKE_VARIABLE_ACTION_NAME,
48    cpp_module_codegen = CPP_MODULE_CODEGEN_ACTION_NAME,
49    cpp_header_parsing = CPP_HEADER_PARSING_ACTION_NAME,
50    cpp_module_compile = CPP_MODULE_COMPILE_ACTION_NAME,
51    assemble = ASSEMBLE_ACTION_NAME,
52    preprocess_assemble = PREPROCESS_ASSEMBLE_ACTION_NAME,
53    lto_indexing = LTO_INDEXING_ACTION_NAME,
54    lto_backend = LTO_BACKEND_ACTION_NAME,
55    cpp_link_executable = CPP_LINK_EXECUTABLE_ACTION_NAME,
56    cpp_link_dynamic_library = CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME,
57    cpp_link_nodeps_dynamic_library = CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME,
58    cpp_link_static_library = CPP_LINK_STATIC_LIBRARY_ACTION_NAME,
59    strip = STRIP_ACTION_NAME,
60    objc_archive = OBJC_ARCHIVE_ACTION_NAME,
61    objc_compile = OBJC_COMPILE_ACTION_NAME,
62    objc_executable = OBJC_EXECUTABLE_ACTION_NAME,
63    objc_fully_link = OBJC_FULLY_LINK_ACTION_NAME,
64    objcpp_compile = OBJCPP_COMPILE_ACTION_NAME,
65    objcpp_executable = OBJCPP_EXECUTABLE_ACTION_NAME,
66    clif_match = CLIF_MATCH_ACTION_NAME,
67    objcopy_embed_data = "objcopy_embed_data",
68    ld_embed_data = "ld_embed_data",
69)
70
71def _impl(ctx):
72    if (ctx.attr.cpu == "darwin"):
73        toolchain_identifier = "local_darwin"
74    elif (ctx.attr.cpu == "local"):
75        toolchain_identifier = "local_linux"
76    elif (ctx.attr.cpu == "x64_windows"):
77        toolchain_identifier = "local_windows"
78    else:
79        fail("Unreachable")
80
81    host_system_name = "local"
82
83    target_system_name = "local"
84
85    if (ctx.attr.cpu == "darwin"):
86        target_cpu = "darwin"
87    elif (ctx.attr.cpu == "local"):
88        target_cpu = "local"
89    elif (ctx.attr.cpu == "x64_windows"):
90        target_cpu = "x64_windows"
91    else:
92        fail("Unreachable")
93
94    if (ctx.attr.cpu == "local"):
95        target_libc = "local"
96    elif (ctx.attr.cpu == "darwin"):
97        target_libc = "macosx"
98    elif (ctx.attr.cpu == "x64_windows"):
99        target_libc = "msvcrt"
100    else:
101        fail("Unreachable")
102
103    if (ctx.attr.cpu == "darwin" or
104        ctx.attr.cpu == "local"):
105        compiler = "compiler"
106    elif (ctx.attr.cpu == "x64_windows"):
107        compiler = "msvc-cl"
108    else:
109        fail("Unreachable")
110
111    abi_version = "local"
112
113    abi_libc_version = "local"
114
115    cc_target_os = None
116
117    builtin_sysroot = ctx.attr.builtin_sysroot
118
119    all_link_actions = [
120        ACTION_NAMES.cpp_link_executable,
121        ACTION_NAMES.cpp_link_dynamic_library,
122        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
123    ]
124
125    cpp_link_dynamic_library_action = action_config(
126        action_name = ACTION_NAMES.cpp_link_dynamic_library,
127        implies = [
128            "nologo",
129            "shared_flag",
130            "linkstamps",
131            "output_execpath_flags",
132            "input_param_flags",
133            "user_link_flags",
134            "linker_subsystem_flag",
135            "linker_param_file",
136            "msvc_env",
137            "no_stripping",
138            "has_configured_linker_path",
139            "def_file",
140        ],
141        tools = [tool(path = ctx.attr.msvc_link_path)],
142    )
143
144    cpp_link_nodeps_dynamic_library_action = action_config(
145        action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library,
146        implies = [
147            "nologo",
148            "shared_flag",
149            "linkstamps",
150            "output_execpath_flags",
151            "input_param_flags",
152            "user_link_flags",
153            "linker_subsystem_flag",
154            "linker_param_file",
155            "msvc_env",
156            "no_stripping",
157            "has_configured_linker_path",
158            "def_file",
159        ],
160        tools = [tool(path = ctx.attr.msvc_link_path)],
161    )
162
163    cpp_link_static_library_action = action_config(
164        action_name = ACTION_NAMES.cpp_link_static_library,
165        implies = [
166            "nologo",
167            "archiver_flags",
168            "input_param_flags",
169            "linker_param_file",
170            "msvc_env",
171        ],
172        tools = [tool(path = ctx.attr.msvc_lib_path)],
173    )
174
175    assemble_action = action_config(
176        action_name = ACTION_NAMES.assemble,
177        implies = [
178            "compiler_input_flags",
179            "compiler_output_flags",
180            "nologo",
181            "msvc_env",
182            "sysroot",
183        ],
184        tools = [tool(path = ctx.attr.msvc_ml_path)],
185    )
186
187    preprocess_assemble_action = action_config(
188        action_name = ACTION_NAMES.preprocess_assemble,
189        implies = [
190            "compiler_input_flags",
191            "compiler_output_flags",
192            "nologo",
193            "msvc_env",
194            "sysroot",
195        ],
196        tools = [tool(path = ctx.attr.msvc_ml_path)],
197    )
198
199    c_compile_action = action_config(
200        action_name = ACTION_NAMES.c_compile,
201        implies = [
202            "compiler_input_flags",
203            "compiler_output_flags",
204            "nologo",
205            "msvc_env",
206            "parse_showincludes",
207            "user_compile_flags",
208            "sysroot",
209            "unfiltered_compile_flags",
210        ],
211        tools = [tool(path = ctx.attr.msvc_cl_path)],
212    )
213
214    cpp_compile_action = action_config(
215        action_name = ACTION_NAMES.cpp_compile,
216        implies = [
217            "compiler_input_flags",
218            "compiler_output_flags",
219            "nologo",
220            "msvc_env",
221            "parse_showincludes",
222            "user_compile_flags",
223            "sysroot",
224            "unfiltered_compile_flags",
225        ],
226        tools = [tool(path = ctx.attr.msvc_cl_path)],
227    )
228
229    cpp_link_executable_action = action_config(
230        action_name = ACTION_NAMES.cpp_link_executable,
231        implies = [
232            "nologo",
233            "linkstamps",
234            "output_execpath_flags",
235            "input_param_flags",
236            "user_link_flags",
237            "linker_subsystem_flag",
238            "linker_param_file",
239            "msvc_env",
240            "no_stripping",
241        ],
242        tools = [tool(path = ctx.attr.msvc_link_path)],
243    )
244
245    if (ctx.attr.cpu == "darwin" or
246        ctx.attr.cpu == "local"):
247        action_configs = []
248    elif (ctx.attr.cpu == "x64_windows"):
249        action_configs = [
250            assemble_action,
251            preprocess_assemble_action,
252            c_compile_action,
253            cpp_compile_action,
254            cpp_link_executable_action,
255            cpp_link_dynamic_library_action,
256            cpp_link_nodeps_dynamic_library_action,
257            cpp_link_static_library_action,
258        ]
259    else:
260        fail("Unreachable")
261
262    no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols")
263
264    pic_feature = feature(
265        name = "pic",
266        enabled = True,
267        flag_sets = [
268            flag_set(
269                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
270                flag_groups = [
271                    flag_group(flags = ["-fPIC"], expand_if_available = "pic"),
272                    flag_group(
273                        flags = ["-fPIE"],
274                        expand_if_not_available = "pic",
275                    ),
276                ],
277            ),
278        ],
279    )
280
281    preprocessor_defines_feature = feature(
282        name = "preprocessor_defines",
283        enabled = True,
284        flag_sets = [
285            flag_set(
286                actions = [
287                    ACTION_NAMES.assemble,
288                    ACTION_NAMES.preprocess_assemble,
289                    ACTION_NAMES.c_compile,
290                    ACTION_NAMES.cpp_compile,
291                    ACTION_NAMES.cpp_header_parsing,
292                    ACTION_NAMES.cpp_module_compile,
293                ],
294                flag_groups = [
295                    flag_group(
296                        flags = ["/D%{preprocessor_defines}"],
297                        iterate_over = "preprocessor_defines",
298                    ),
299                ],
300            ),
301        ],
302    )
303
304    generate_pdb_file_feature = feature(
305        name = "generate_pdb_file",
306        requires = [
307            feature_set(features = ["dbg"]),
308            feature_set(features = ["fastbuild"]),
309        ],
310    )
311
312    linkstamps_feature = feature(
313        name = "linkstamps",
314        flag_sets = [
315            flag_set(
316                actions = all_link_actions,
317                flag_groups = [
318                    flag_group(
319                        flags = ["%{linkstamp_paths}"],
320                        iterate_over = "linkstamp_paths",
321                        expand_if_available = "linkstamp_paths",
322                    ),
323                ],
324            ),
325        ],
326    )
327
328    unfiltered_compile_flags_feature = feature(
329        name = "unfiltered_compile_flags",
330        flag_sets = ([
331            flag_set(
332                actions = [
333                    ACTION_NAMES.preprocess_assemble,
334                    ACTION_NAMES.c_compile,
335                    ACTION_NAMES.cpp_compile,
336                    ACTION_NAMES.cpp_header_parsing,
337                    ACTION_NAMES.cpp_module_compile,
338                    ACTION_NAMES.cpp_module_codegen,
339                ],
340                flag_groups = [
341                    flag_group(
342                        flags = ctx.attr.host_unfiltered_compile_flags,
343                    ),
344                ],
345            ),
346        ] if ctx.attr.host_unfiltered_compile_flags else []),
347    )
348
349    determinism_feature = feature(
350        name = "determinism",
351        flag_sets = [
352            flag_set(
353                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
354                flag_groups = [
355                    flag_group(
356                        flags = [
357                            "-Wno-builtin-macro-redefined",
358                            "-D__DATE__=\"redacted\"",
359                            "-D__TIMESTAMP__=\"redacted\"",
360                            "-D__TIME__=\"redacted\"",
361                        ],
362                    ),
363                ],
364            ),
365        ],
366    )
367
368    nologo_feature = feature(
369        name = "nologo",
370        flag_sets = [
371            flag_set(
372                actions = [
373                    ACTION_NAMES.c_compile,
374                    ACTION_NAMES.cpp_compile,
375                    ACTION_NAMES.cpp_module_compile,
376                    ACTION_NAMES.cpp_module_codegen,
377                    ACTION_NAMES.cpp_header_parsing,
378                    ACTION_NAMES.assemble,
379                    ACTION_NAMES.preprocess_assemble,
380                    ACTION_NAMES.cpp_link_executable,
381                    ACTION_NAMES.cpp_link_dynamic_library,
382                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
383                    ACTION_NAMES.cpp_link_static_library,
384                ],
385                flag_groups = [flag_group(flags = ["/nologo"])],
386            ),
387        ],
388    )
389
390    supports_pic_feature = feature(name = "supports_pic", enabled = True)
391
392    output_execpath_flags_feature = feature(
393        name = "output_execpath_flags",
394        flag_sets = [
395            flag_set(
396                actions = all_link_actions,
397                flag_groups = [
398                    flag_group(
399                        flags = ["/OUT:%{output_execpath}"],
400                        expand_if_available = "output_execpath",
401                    ),
402                ],
403            ),
404        ],
405    )
406
407    default_link_flags_feature = feature(
408        name = "default_link_flags",
409        enabled = True,
410        flag_sets = [
411            flag_set(
412                actions = all_link_actions,
413                flag_groups = [flag_group(flags = ["/MACHINE:X64"])],
414            ),
415        ],
416    )
417
418    if (ctx.attr.cpu == "local"):
419        hardening_feature = feature(
420            name = "hardening",
421            flag_sets = [
422                flag_set(
423                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
424                    flag_groups = [
425                        flag_group(
426                            flags = [
427                                "-U_FORTIFY_SOURCE",
428                                "-D_FORTIFY_SOURCE=1",
429                                "-fstack-protector",
430                            ],
431                        ),
432                    ],
433                ),
434                flag_set(
435                    actions = [
436                        ACTION_NAMES.cpp_link_dynamic_library,
437                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
438                    ],
439                    flag_groups = [flag_group(flags = ["-Wl,-z,relro,-z,now"])],
440                ),
441                flag_set(
442                    actions = [ACTION_NAMES.cpp_link_executable],
443                    flag_groups = [flag_group(flags = ["-pie", "-Wl,-z,relro,-z,now"])],
444                ),
445            ],
446        )
447    elif (ctx.attr.cpu == "darwin"):
448        hardening_feature = feature(
449            name = "hardening",
450            flag_sets = [
451                flag_set(
452                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
453                    flag_groups = [
454                        flag_group(
455                            flags = [
456                                "-U_FORTIFY_SOURCE",
457                                "-D_FORTIFY_SOURCE=1",
458                                "-fstack-protector",
459                            ],
460                        ),
461                    ],
462                ),
463                flag_set(
464                    actions = [ACTION_NAMES.cpp_link_executable],
465                    flag_groups = [flag_group(flags = ["-pie"])],
466                ),
467            ],
468        )
469    else:
470        hardening_feature = None
471
472    supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True)
473
474    targets_windows_feature = feature(
475        name = "targets_windows",
476        enabled = True,
477        implies = ["copy_dynamic_libraries_to_binary"],
478    )
479
480    msvc_env_feature = feature(
481        name = "msvc_env",
482        env_sets = [
483            env_set(
484                actions = [
485                    ACTION_NAMES.c_compile,
486                    ACTION_NAMES.cpp_compile,
487                    ACTION_NAMES.cpp_module_compile,
488                    ACTION_NAMES.cpp_module_codegen,
489                    ACTION_NAMES.cpp_header_parsing,
490                    ACTION_NAMES.assemble,
491                    ACTION_NAMES.preprocess_assemble,
492                    ACTION_NAMES.cpp_link_executable,
493                    ACTION_NAMES.cpp_link_dynamic_library,
494                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
495                    ACTION_NAMES.cpp_link_static_library,
496                ],
497                env_entries = [
498                    env_entry(key = "PATH", value = ctx.attr.msvc_env_path),
499                    env_entry(
500                        key = "INCLUDE",
501                        value = ctx.attr.msvc_env_include,
502                    ),
503                    env_entry(key = "LIB", value = ctx.attr.msvc_env_lib),
504                    env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp),
505                    env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp),
506                ],
507            ),
508        ],
509    )
510
511    linker_subsystem_flag_feature = feature(
512        name = "linker_subsystem_flag",
513        flag_sets = [
514            flag_set(
515                actions = all_link_actions,
516                flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])],
517            ),
518        ],
519    )
520
521    dynamic_link_msvcrt_no_debug_feature = feature(
522        name = "dynamic_link_msvcrt_no_debug",
523        flag_sets = [
524            flag_set(
525                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
526                flag_groups = [flag_group(flags = ["/MD"])],
527            ),
528            flag_set(
529                actions = all_link_actions,
530                flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])],
531            ),
532        ],
533        requires = [
534            feature_set(features = ["fastbuild"]),
535            feature_set(features = ["opt"]),
536        ],
537    )
538
539    warnings_feature = feature(
540        name = "warnings",
541        flag_sets = [
542            flag_set(
543                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
544                flag_groups = [
545                    flag_group(
546                        flags = ["-Wall"] + ctx.attr.host_compiler_warnings,
547                    ),
548                ],
549            ),
550        ],
551    )
552
553    dynamic_link_msvcrt_debug_feature = feature(
554        name = "dynamic_link_msvcrt_debug",
555        flag_sets = [
556            flag_set(
557                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
558                flag_groups = [flag_group(flags = ["/MDd"])],
559            ),
560            flag_set(
561                actions = all_link_actions,
562                flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])],
563            ),
564        ],
565        requires = [feature_set(features = ["dbg"])],
566    )
567
568    compiler_output_flags_feature = feature(
569        name = "compiler_output_flags",
570        flag_sets = [
571            flag_set(
572                actions = [ACTION_NAMES.assemble],
573                flag_groups = [
574                    flag_group(
575                        flag_groups = [
576                            flag_group(
577                                flags = ["/Fo%{output_file}", "/Zi"],
578                                expand_if_not_available = "output_preprocess_file",
579                            ),
580                        ],
581                        expand_if_available = "output_file",
582                        expand_if_not_available = "output_assembly_file",
583                    ),
584                ],
585            ),
586            flag_set(
587                actions = [
588                    ACTION_NAMES.preprocess_assemble,
589                    ACTION_NAMES.c_compile,
590                    ACTION_NAMES.cpp_compile,
591                    ACTION_NAMES.cpp_header_parsing,
592                    ACTION_NAMES.cpp_module_compile,
593                    ACTION_NAMES.cpp_module_codegen,
594                ],
595                flag_groups = [
596                    flag_group(
597                        flag_groups = [
598                            flag_group(
599                                flags = ["/Fo%{output_file}"],
600                                expand_if_not_available = "output_preprocess_file",
601                            ),
602                        ],
603                        expand_if_available = "output_file",
604                        expand_if_not_available = "output_assembly_file",
605                    ),
606                    flag_group(
607                        flag_groups = [
608                            flag_group(
609                                flags = ["/Fa%{output_file}"],
610                                expand_if_available = "output_assembly_file",
611                            ),
612                        ],
613                        expand_if_available = "output_file",
614                    ),
615                    flag_group(
616                        flag_groups = [
617                            flag_group(
618                                flags = ["/P", "/Fi%{output_file}"],
619                                expand_if_available = "output_preprocess_file",
620                            ),
621                        ],
622                        expand_if_available = "output_file",
623                    ),
624                ],
625            ),
626        ],
627    )
628
629    default_compile_flags_feature = feature(
630        name = "default_compile_flags",
631        enabled = True,
632        flag_sets = [
633            flag_set(
634                actions = [
635                    ACTION_NAMES.assemble,
636                    ACTION_NAMES.preprocess_assemble,
637                    ACTION_NAMES.linkstamp_compile,
638                    ACTION_NAMES.c_compile,
639                    ACTION_NAMES.cpp_compile,
640                    ACTION_NAMES.cpp_header_parsing,
641                    ACTION_NAMES.cpp_module_compile,
642                    ACTION_NAMES.cpp_module_codegen,
643                    ACTION_NAMES.lto_backend,
644                    ACTION_NAMES.clif_match,
645                ],
646                flag_groups = [
647                    flag_group(
648                        flags = [
649                            "/DCOMPILER_MSVC",
650                            "/DNOMINMAX",
651                            "/D_WIN32_WINNT=0x0600",
652                            "/D_CRT_SECURE_NO_DEPRECATE",
653                            "/D_CRT_SECURE_NO_WARNINGS",
654                            "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS",
655                            "/bigobj",
656                            "/Zm500",
657                            "/J",
658                            "/Gy",
659                            "/GF",
660                            "/EHsc",
661                            "/wd4351",
662                            "/wd4291",
663                            "/wd4250",
664                            "/wd4996",
665                        ],
666                    ),
667                ],
668            ),
669        ],
670    )
671
672    static_link_msvcrt_debug_feature = feature(
673        name = "static_link_msvcrt_debug",
674        flag_sets = [
675            flag_set(
676                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
677                flag_groups = [flag_group(flags = ["/MTd"])],
678            ),
679            flag_set(
680                actions = all_link_actions,
681                flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])],
682            ),
683        ],
684        requires = [feature_set(features = ["dbg"])],
685    )
686
687    static_link_msvcrt_feature = feature(name = "static_link_msvcrt")
688
689    if (ctx.attr.cpu == "darwin" or
690        ctx.attr.cpu == "local"):
691        dbg_feature = feature(
692            name = "dbg",
693            flag_sets = [
694                flag_set(
695                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
696                    flag_groups = [flag_group(flags = ["-g"])],
697                ),
698            ],
699            implies = ["common"],
700        )
701    elif (ctx.attr.cpu == "x64_windows"):
702        dbg_feature = feature(
703            name = "dbg",
704            flag_sets = [
705                flag_set(
706                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
707                    flag_groups = [flag_group(flags = ["/Od", "/Z7", "/DDEBUG"])],
708                ),
709                flag_set(
710                    actions = all_link_actions,
711                    flag_groups = [flag_group(flags = ["/DEBUG:FULL", "/INCREMENTAL:NO"])],
712                ),
713            ],
714            implies = ["generate_pdb_file"],
715        )
716    else:
717        dbg_feature = None
718
719    undefined_dynamic_feature = feature(
720        name = "undefined-dynamic",
721        flag_sets = [
722            flag_set(
723                actions = [
724                    ACTION_NAMES.cpp_link_dynamic_library,
725                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
726                    ACTION_NAMES.cpp_link_executable,
727                ],
728                flag_groups = [flag_group(flags = ["-undefined", "dynamic_lookup"])],
729            ),
730        ],
731    )
732
733    parse_showincludes_feature = feature(
734        name = "parse_showincludes",
735        flag_sets = [
736            flag_set(
737                actions = [
738                    ACTION_NAMES.preprocess_assemble,
739                    ACTION_NAMES.c_compile,
740                    ACTION_NAMES.cpp_compile,
741                    ACTION_NAMES.cpp_module_compile,
742                    ACTION_NAMES.cpp_header_parsing,
743                ],
744                flag_groups = [flag_group(flags = ["/showIncludes"])],
745            ),
746        ],
747    )
748
749    linker_param_file_feature = feature(
750        name = "linker_param_file",
751        flag_sets = [
752            flag_set(
753                actions = all_link_actions +
754                          [ACTION_NAMES.cpp_link_static_library],
755                flag_groups = [
756                    flag_group(
757                        flags = ["@%{linker_param_file}"],
758                        expand_if_available = "linker_param_file",
759                    ),
760                ],
761            ),
762        ],
763    )
764
765    static_link_msvcrt_no_debug_feature = feature(
766        name = "static_link_msvcrt_no_debug",
767        flag_sets = [
768            flag_set(
769                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
770                flag_groups = [flag_group(flags = ["/MT"])],
771            ),
772            flag_set(
773                actions = all_link_actions,
774                flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])],
775            ),
776        ],
777        requires = [
778            feature_set(features = ["fastbuild"]),
779            feature_set(features = ["opt"]),
780        ],
781    )
782
783    supports_interface_shared_libraries_feature = feature(
784        name = "supports_interface_shared_libraries",
785        enabled = True,
786    )
787
788    disable_assertions_feature = feature(
789        name = "disable-assertions",
790        flag_sets = [
791            flag_set(
792                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
793                flag_groups = [flag_group(flags = ["-DNDEBUG"])],
794            ),
795        ],
796    )
797
798    if (ctx.attr.cpu == "x64_windows"):
799        fastbuild_feature = feature(
800            name = "fastbuild",
801            flag_sets = [
802                flag_set(
803                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
804                    flag_groups = [flag_group(flags = ["/Od", "/Z7", "/DDEBUG"])],
805                ),
806                flag_set(
807                    actions = all_link_actions,
808                    flag_groups = [
809                        flag_group(flags = ["/DEBUG:FASTLINK", "/INCREMENTAL:NO"]),
810                    ],
811                ),
812            ],
813            implies = ["generate_pdb_file"],
814        )
815    elif (ctx.attr.cpu == "darwin" or
816          ctx.attr.cpu == "local"):
817        fastbuild_feature = feature(name = "fastbuild", implies = ["common"])
818    else:
819        fastbuild_feature = None
820
821    user_compile_flags_feature = feature(
822        name = "user_compile_flags",
823        flag_sets = [
824            flag_set(
825                actions = [
826                    ACTION_NAMES.preprocess_assemble,
827                    ACTION_NAMES.c_compile,
828                    ACTION_NAMES.cpp_compile,
829                    ACTION_NAMES.cpp_header_parsing,
830                    ACTION_NAMES.cpp_module_compile,
831                    ACTION_NAMES.cpp_module_codegen,
832                ],
833                flag_groups = [
834                    flag_group(
835                        flags = ["%{user_compile_flags}"],
836                        iterate_over = "user_compile_flags",
837                        expand_if_available = "user_compile_flags",
838                    ),
839                ],
840            ),
841        ],
842    )
843
844    compiler_input_flags_feature = feature(
845        name = "compiler_input_flags",
846        flag_sets = [
847            flag_set(
848                actions = [
849                    ACTION_NAMES.assemble,
850                    ACTION_NAMES.preprocess_assemble,
851                    ACTION_NAMES.c_compile,
852                    ACTION_NAMES.cpp_compile,
853                    ACTION_NAMES.cpp_header_parsing,
854                    ACTION_NAMES.cpp_module_compile,
855                    ACTION_NAMES.cpp_module_codegen,
856                ],
857                flag_groups = [
858                    flag_group(
859                        flags = ["/c", "%{source_file}"],
860                        expand_if_available = "source_file",
861                    ),
862                ],
863            ),
864        ],
865    )
866
867    no_legacy_features_feature = feature(name = "no_legacy_features")
868
869    archiver_flags_feature = feature(
870        name = "archiver_flags",
871        flag_sets = [
872            flag_set(
873                actions = [ACTION_NAMES.cpp_link_static_library],
874                flag_groups = [
875                    flag_group(
876                        flags = ["/OUT:%{output_execpath}"],
877                        expand_if_available = "output_execpath",
878                    ),
879                ],
880            ),
881        ],
882    )
883
884    redirector_feature = feature(
885        name = "redirector",
886        enabled = True,
887        flag_sets = [
888            flag_set(
889                actions = [
890                    ACTION_NAMES.c_compile,
891                    ACTION_NAMES.cpp_compile,
892                    ACTION_NAMES.cpp_module_compile,
893                    ACTION_NAMES.cpp_module_codegen,
894                    ACTION_NAMES.cpp_header_parsing,
895                    ACTION_NAMES.assemble,
896                    ACTION_NAMES.preprocess_assemble,
897                ],
898                flag_groups = [
899                    flag_group(
900                        flags = [
901                            "-B",
902                            "external/local_config_cuda/crosstool/windows/msvc_wrapper_for_nvcc.py",
903                        ],
904                    ),
905                ],
906            ),
907        ],
908    )
909
910    linker_bin_path_feature = feature(
911        name = "linker-bin-path",
912        flag_sets = [
913            flag_set(
914                actions = all_link_actions,
915                flag_groups = [flag_group(flags = ["-B" + ctx.attr.linker_bin_path])],
916            ),
917        ],
918    )
919
920    if (ctx.attr.cpu == "local"):
921        opt_feature = feature(
922            name = "opt",
923            flag_sets = [
924                flag_set(
925                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
926                    flag_groups = [
927                        flag_group(
928                            flags = ["-g0", "-O2", "-ffunction-sections", "-fdata-sections"],
929                        ),
930                    ],
931                ),
932                flag_set(
933                    actions = [
934                        ACTION_NAMES.cpp_link_dynamic_library,
935                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
936                        ACTION_NAMES.cpp_link_executable,
937                    ],
938                    flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])],
939                ),
940            ],
941            implies = ["common", "disable-assertions"],
942        )
943    elif (ctx.attr.cpu == "darwin"):
944        opt_feature = feature(
945            name = "opt",
946            flag_sets = [
947                flag_set(
948                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
949                    flag_groups = [
950                        flag_group(
951                            flags = ["-g0", "-O2", "-ffunction-sections", "-fdata-sections"],
952                        ),
953                    ],
954                ),
955            ],
956            implies = ["common", "disable-assertions"],
957        )
958    elif (ctx.attr.cpu == "x64_windows"):
959        opt_feature = feature(
960            name = "opt",
961            flag_sets = [
962                flag_set(
963                    actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
964                    flag_groups = [flag_group(flags = ["/O2", "/DNDEBUG"])],
965                ),
966            ],
967        )
968    else:
969        opt_feature = None
970
971    include_paths_feature = feature(
972        name = "include_paths",
973        enabled = True,
974        flag_sets = [
975            flag_set(
976                actions = [
977                    ACTION_NAMES.assemble,
978                    ACTION_NAMES.preprocess_assemble,
979                    ACTION_NAMES.c_compile,
980                    ACTION_NAMES.cpp_compile,
981                    ACTION_NAMES.cpp_header_parsing,
982                    ACTION_NAMES.cpp_module_compile,
983                ],
984                flag_groups = [
985                    flag_group(
986                        flags = ["/I%{quote_include_paths}"],
987                        iterate_over = "quote_include_paths",
988                    ),
989                    flag_group(
990                        flags = ["/I%{include_paths}"],
991                        iterate_over = "include_paths",
992                    ),
993                    flag_group(
994                        flags = ["/I%{system_include_paths}"],
995                        iterate_over = "system_include_paths",
996                    ),
997                ],
998            ),
999        ],
1000    )
1001
1002    shared_flag_feature = feature(
1003        name = "shared_flag",
1004        flag_sets = [
1005            flag_set(
1006                actions = [
1007                    ACTION_NAMES.cpp_link_dynamic_library,
1008                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1009                ],
1010                flag_groups = [flag_group(flags = ["/DLL"])],
1011            ),
1012        ],
1013    )
1014
1015    windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols")
1016
1017    frame_pointer_feature = feature(
1018        name = "frame-pointer",
1019        flag_sets = [
1020            flag_set(
1021                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
1022                flag_groups = [flag_group(flags = ["-fno-omit-frame-pointer"])],
1023            ),
1024        ],
1025    )
1026
1027    build_id_feature = feature(
1028        name = "build-id",
1029        flag_sets = [
1030            flag_set(
1031                actions = all_link_actions,
1032                flag_groups = [
1033                    flag_group(
1034                        flags = ["-Wl,--build-id=md5", "-Wl,--hash-style=gnu"],
1035                    ),
1036                ],
1037            ),
1038        ],
1039    )
1040
1041    sysroot_feature = feature(
1042        name = "sysroot",
1043        flag_sets = [
1044            flag_set(
1045                actions = [
1046                    ACTION_NAMES.assemble,
1047                    ACTION_NAMES.preprocess_assemble,
1048                    ACTION_NAMES.c_compile,
1049                    ACTION_NAMES.cpp_compile,
1050                    ACTION_NAMES.cpp_header_parsing,
1051                    ACTION_NAMES.cpp_module_compile,
1052                    ACTION_NAMES.cpp_module_codegen,
1053                    ACTION_NAMES.cpp_link_executable,
1054                    ACTION_NAMES.cpp_link_dynamic_library,
1055                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1056                ],
1057                flag_groups = [
1058                    flag_group(
1059                        flags = ["--sysroot=%{sysroot}"],
1060                        iterate_over = "sysroot",
1061                        expand_if_available = "sysroot",
1062                    ),
1063                ],
1064            ),
1065        ],
1066    )
1067
1068    cuda_path_feature = feature(
1069        name = "cuda_path",
1070        enabled = True,
1071        flag_sets = [
1072            flag_set(
1073                actions = [
1074                    ACTION_NAMES.assemble,
1075                    ACTION_NAMES.preprocess_assemble,
1076                    ACTION_NAMES.c_compile,
1077                    ACTION_NAMES.cpp_compile,
1078                    ACTION_NAMES.cpp_header_parsing,
1079                    ACTION_NAMES.cpp_module_compile,
1080                    ACTION_NAMES.cpp_module_codegen,
1081                    ACTION_NAMES.cpp_link_executable,
1082                    ACTION_NAMES.cpp_link_dynamic_library,
1083                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1084                ],
1085                flag_groups = [
1086                    flag_group(
1087                        flags = ["--cuda-path=" + ctx.attr.cuda_path],
1088                    ),
1089                ],
1090            ),
1091        ],
1092    )
1093
1094    def_file_feature = feature(
1095        name = "def_file",
1096        flag_sets = [
1097            flag_set(
1098                actions = all_link_actions,
1099                flag_groups = [
1100                    flag_group(
1101                        flags = ["/DEF:%{def_file_path}", "/ignore:4070"],
1102                        expand_if_available = "def_file_path",
1103                    ),
1104                ],
1105            ),
1106        ],
1107    )
1108
1109    if (ctx.attr.cpu == "darwin"):
1110        stdlib_feature = feature(
1111            name = "stdlib",
1112            flag_sets = [
1113                flag_set(
1114                    actions = all_link_actions,
1115                    flag_groups = [flag_group(flags = ["-lc++"])],
1116                ),
1117            ],
1118        )
1119    elif (ctx.attr.cpu == "local"):
1120        stdlib_feature = feature(
1121            name = "stdlib",
1122            flag_sets = [
1123                flag_set(
1124                    actions = all_link_actions,
1125                    flag_groups = [flag_group(flags = ["-lstdc++"])],
1126                ),
1127            ],
1128        )
1129    else:
1130        stdlib_feature = None
1131
1132    no_stripping_feature = feature(name = "no_stripping")
1133
1134    alwayslink_feature = feature(
1135        name = "alwayslink",
1136        flag_sets = [
1137            flag_set(
1138                actions = [
1139                    ACTION_NAMES.cpp_link_dynamic_library,
1140                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1141                    ACTION_NAMES.cpp_link_executable,
1142                ],
1143                flag_groups = [flag_group(flags = ["-Wl,-no-as-needed"])],
1144            ),
1145        ],
1146    )
1147
1148    input_param_flags_feature = feature(
1149        name = "input_param_flags",
1150        flag_sets = [
1151            flag_set(
1152                actions = [
1153                    ACTION_NAMES.cpp_link_dynamic_library,
1154                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1155                ],
1156                flag_groups = [
1157                    flag_group(
1158                        flags = ["/IMPLIB:%{interface_library_output_path}"],
1159                        expand_if_available = "interface_library_output_path",
1160                    ),
1161                ],
1162            ),
1163            flag_set(
1164                actions = all_link_actions +
1165                          [ACTION_NAMES.cpp_link_static_library],
1166                flag_groups = [
1167                    flag_group(
1168                        iterate_over = "libraries_to_link",
1169                        flag_groups = [
1170                            flag_group(
1171                                iterate_over = "libraries_to_link.object_files",
1172                                flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])],
1173                                expand_if_equal = variable_with_value(
1174                                    name = "libraries_to_link.type",
1175                                    value = "object_file_group",
1176                                ),
1177                            ),
1178                            flag_group(
1179                                flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])],
1180                                expand_if_equal = variable_with_value(
1181                                    name = "libraries_to_link.type",
1182                                    value = "object_file",
1183                                ),
1184                            ),
1185                            flag_group(
1186                                flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])],
1187                                expand_if_equal = variable_with_value(
1188                                    name = "libraries_to_link.type",
1189                                    value = "interface_library",
1190                                ),
1191                            ),
1192                            flag_group(
1193                                flag_groups = [
1194                                    flag_group(
1195                                        flags = ["%{libraries_to_link.name}"],
1196                                        expand_if_false = "libraries_to_link.is_whole_archive",
1197                                    ),
1198                                    flag_group(
1199                                        flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"],
1200                                        expand_if_true = "libraries_to_link.is_whole_archive",
1201                                    ),
1202                                ],
1203                                expand_if_equal = variable_with_value(
1204                                    name = "libraries_to_link.type",
1205                                    value = "static_library",
1206                                ),
1207                            ),
1208                        ],
1209                        expand_if_available = "libraries_to_link",
1210                    ),
1211                ],
1212            ),
1213        ],
1214    )
1215
1216    if (ctx.attr.cpu == "local"):
1217        no_canonical_prefixes_feature = feature(
1218            name = "no-canonical-prefixes",
1219            flag_sets = [
1220                flag_set(
1221                    actions = [
1222                        ACTION_NAMES.c_compile,
1223                        ACTION_NAMES.cpp_compile,
1224                        ACTION_NAMES.cpp_link_executable,
1225                        ACTION_NAMES.cpp_link_dynamic_library,
1226                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1227                    ],
1228                    flag_groups = [
1229                        flag_group(
1230                            flags = [
1231                                "-no-canonical-prefixes",
1232                            ] + ctx.attr.extra_no_canonical_prefixes_flags,
1233                        ),
1234                    ],
1235                ),
1236            ],
1237        )
1238    elif (ctx.attr.cpu == "darwin"):
1239        no_canonical_prefixes_feature = feature(
1240            name = "no-canonical-prefixes",
1241            flag_sets = [
1242                flag_set(
1243                    actions = [
1244                        ACTION_NAMES.c_compile,
1245                        ACTION_NAMES.cpp_compile,
1246                        ACTION_NAMES.cpp_link_executable,
1247                        ACTION_NAMES.cpp_link_dynamic_library,
1248                        ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1249                    ],
1250                    flag_groups = [flag_group(flags = ["-no-canonical-prefixes"])],
1251                ),
1252            ],
1253        )
1254    else:
1255        no_canonical_prefixes_feature = None
1256
1257    has_configured_linker_path_feature = feature(name = "has_configured_linker_path")
1258
1259    copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary")
1260
1261    user_link_flags_feature = feature(
1262        name = "user_link_flags",
1263        flag_sets = [
1264            flag_set(
1265                actions = all_link_actions,
1266                flag_groups = [
1267                    flag_group(
1268                        flags = ["%{user_link_flags}"],
1269                        iterate_over = "user_link_flags",
1270                        expand_if_available = "user_link_flags",
1271                    ),
1272                ],
1273            ),
1274        ],
1275    )
1276
1277    cpp11_feature = feature(
1278        name = "c++11",
1279        flag_sets = [
1280            flag_set(
1281                actions = [ACTION_NAMES.cpp_compile],
1282                flag_groups = [flag_group(flags = ["-std=c++11"])],
1283            ),
1284        ],
1285    )
1286
1287    if (ctx.attr.cpu == "local"):
1288        common_feature = feature(
1289            name = "common",
1290            implies = [
1291                "stdlib",
1292                "c++11",
1293                "determinism",
1294                "alwayslink",
1295                "hardening",
1296                "warnings",
1297                "frame-pointer",
1298                "build-id",
1299                "no-canonical-prefixes",
1300                "linker-bin-path",
1301            ],
1302        )
1303    elif (ctx.attr.cpu == "darwin"):
1304        common_feature = feature(
1305            name = "common",
1306            implies = [
1307                "stdlib",
1308                "c++11",
1309                "determinism",
1310                "hardening",
1311                "warnings",
1312                "frame-pointer",
1313                "no-canonical-prefixes",
1314                "linker-bin-path",
1315                "undefined-dynamic",
1316            ],
1317        )
1318    else:
1319        common_feature = None
1320
1321    if (ctx.attr.cpu == "local"):
1322        features = [
1323            cpp11_feature,
1324            stdlib_feature,
1325            determinism_feature,
1326            alwayslink_feature,
1327            pic_feature,
1328            hardening_feature,
1329            warnings_feature,
1330            frame_pointer_feature,
1331            build_id_feature,
1332            no_canonical_prefixes_feature,
1333            disable_assertions_feature,
1334            linker_bin_path_feature,
1335            common_feature,
1336            opt_feature,
1337            fastbuild_feature,
1338            dbg_feature,
1339            supports_dynamic_linker_feature,
1340            supports_pic_feature,
1341        ]
1342        if ctx.attr.cuda_path:
1343            features += [cuda_path_feature]
1344    elif (ctx.attr.cpu == "darwin"):
1345        features = [
1346            cpp11_feature,
1347            stdlib_feature,
1348            determinism_feature,
1349            pic_feature,
1350            hardening_feature,
1351            warnings_feature,
1352            frame_pointer_feature,
1353            no_canonical_prefixes_feature,
1354            disable_assertions_feature,
1355            linker_bin_path_feature,
1356            undefined_dynamic_feature,
1357            common_feature,
1358            opt_feature,
1359            fastbuild_feature,
1360            dbg_feature,
1361            supports_dynamic_linker_feature,
1362            supports_pic_feature,
1363        ]
1364    elif (ctx.attr.cpu == "x64_windows"):
1365        features = [
1366            no_legacy_features_feature,
1367            redirector_feature,
1368            nologo_feature,
1369            has_configured_linker_path_feature,
1370            no_stripping_feature,
1371            targets_windows_feature,
1372            copy_dynamic_libraries_to_binary_feature,
1373            default_compile_flags_feature,
1374            msvc_env_feature,
1375            include_paths_feature,
1376            preprocessor_defines_feature,
1377            parse_showincludes_feature,
1378            generate_pdb_file_feature,
1379            shared_flag_feature,
1380            linkstamps_feature,
1381            output_execpath_flags_feature,
1382            archiver_flags_feature,
1383            input_param_flags_feature,
1384            linker_subsystem_flag_feature,
1385            user_link_flags_feature,
1386            default_link_flags_feature,
1387            linker_param_file_feature,
1388            static_link_msvcrt_feature,
1389            static_link_msvcrt_no_debug_feature,
1390            dynamic_link_msvcrt_no_debug_feature,
1391            static_link_msvcrt_debug_feature,
1392            dynamic_link_msvcrt_debug_feature,
1393            dbg_feature,
1394            fastbuild_feature,
1395            opt_feature,
1396            user_compile_flags_feature,
1397            sysroot_feature,
1398            unfiltered_compile_flags_feature,
1399            compiler_output_flags_feature,
1400            compiler_input_flags_feature,
1401            def_file_feature,
1402            windows_export_all_symbols_feature,
1403            no_windows_export_all_symbols_feature,
1404            supports_dynamic_linker_feature,
1405            supports_interface_shared_libraries_feature,
1406        ]
1407    else:
1408        fail("Unreachable")
1409
1410    cxx_builtin_include_directories = ctx.attr.builtin_include_directories
1411
1412    if (ctx.attr.cpu == "x64_windows"):
1413        tool_paths = [
1414            tool_path(name = "ar", path = ctx.attr.msvc_lib_path),
1415            tool_path(name = "ml", path = ctx.attr.msvc_ml_path),
1416            tool_path(name = "cpp", path = ctx.attr.msvc_cl_path),
1417            tool_path(name = "gcc", path = ctx.attr.msvc_cl_path),
1418            tool_path(name = "gcov", path = "wrapper/bin/msvc_nop.bat"),
1419            tool_path(name = "ld", path = ctx.attr.msvc_link_path),
1420            tool_path(name = "nm", path = "wrapper/bin/msvc_nop.bat"),
1421            tool_path(
1422                name = "objcopy",
1423                path = "wrapper/bin/msvc_nop.bat",
1424            ),
1425            tool_path(
1426                name = "objdump",
1427                path = "wrapper/bin/msvc_nop.bat",
1428            ),
1429            tool_path(
1430                name = "strip",
1431                path = "wrapper/bin/msvc_nop.bat",
1432            ),
1433        ]
1434    elif (ctx.attr.cpu == "local"):
1435        tool_paths = [
1436            tool_path(name = "gcc", path = ctx.attr.host_compiler_path),
1437            tool_path(name = "ar", path = ctx.attr.host_compiler_prefix + "/ar"),
1438            tool_path(name = "compat-ld", path = ctx.attr.host_compiler_prefix + "/ld"),
1439            tool_path(name = "cpp", path = ctx.attr.host_compiler_prefix + "/cpp"),
1440            tool_path(name = "dwp", path = ctx.attr.host_compiler_prefix + "/dwp"),
1441            tool_path(name = "gcov", path = ctx.attr.host_compiler_prefix + "/gcov"),
1442            tool_path(name = "ld", path = ctx.attr.host_compiler_prefix + "/ld"),
1443            tool_path(name = "nm", path = ctx.attr.host_compiler_prefix + "/nm"),
1444            tool_path(name = "objcopy", path = ctx.attr.host_compiler_prefix + "/objcopy"),
1445            tool_path(name = "objdump", path = ctx.attr.host_compiler_prefix + "/objdump"),
1446            tool_path(name = "strip", path = ctx.attr.host_compiler_prefix + "/strip"),
1447        ]
1448    elif (ctx.attr.cpu == "darwin"):
1449        tool_paths = [
1450            tool_path(name = "gcc", path = ctx.attr.host_compiler_path),
1451            tool_path(name = "ar", path = ctx.attr.host_compiler_prefix + "/libtool"),
1452            tool_path(name = "compat-ld", path = ctx.attr.host_compiler_prefix + "/ld"),
1453            tool_path(name = "cpp", path = ctx.attr.host_compiler_prefix + "/cpp"),
1454            tool_path(name = "dwp", path = ctx.attr.host_compiler_prefix + "/dwp"),
1455            tool_path(name = "gcov", path = ctx.attr.host_compiler_prefix + "/gcov"),
1456            tool_path(name = "ld", path = ctx.attr.host_compiler_prefix + "/ld"),
1457            tool_path(name = "nm", path = ctx.attr.host_compiler_prefix + "/nm"),
1458            tool_path(name = "objcopy", path = ctx.attr.host_compiler_prefix + "/objcopy"),
1459            tool_path(name = "objdump", path = ctx.attr.host_compiler_prefix + "/objdump"),
1460            tool_path(name = "strip", path = ctx.attr.host_compiler_prefix + "/strip"),
1461        ]
1462    else:
1463        fail("Unreachable")
1464
1465    out = ctx.actions.declare_file(ctx.label.name)
1466    ctx.actions.write(out, "Fake executable")
1467    return [
1468        cc_common.create_cc_toolchain_config_info(
1469            ctx = ctx,
1470            features = features,
1471            action_configs = action_configs,
1472            artifact_name_patterns = [],
1473            cxx_builtin_include_directories = cxx_builtin_include_directories,
1474            toolchain_identifier = toolchain_identifier,
1475            host_system_name = host_system_name,
1476            target_system_name = target_system_name,
1477            target_cpu = target_cpu,
1478            target_libc = target_libc,
1479            compiler = compiler,
1480            abi_version = abi_version,
1481            abi_libc_version = abi_libc_version,
1482            tool_paths = tool_paths,
1483            make_variables = [],
1484            builtin_sysroot = builtin_sysroot,
1485            cc_target_os = cc_target_os,
1486        ),
1487        DefaultInfo(
1488            executable = out,
1489        ),
1490    ]
1491
1492cc_toolchain_config = rule(
1493    implementation = _impl,
1494    attrs = {
1495        "cpu": attr.string(mandatory = True, values = ["darwin", "local", "x64_windows"]),
1496        "builtin_include_directories": attr.string_list(),
1497        "extra_no_canonical_prefixes_flags": attr.string_list(),
1498        "host_compiler_path": attr.string(),
1499        "host_compiler_prefix": attr.string(),
1500        "host_compiler_warnings": attr.string_list(),
1501        "host_unfiltered_compile_flags": attr.string_list(),
1502        "linker_bin_path": attr.string(),
1503        "builtin_sysroot": attr.string(),
1504        "cuda_path": attr.string(),
1505        "msvc_cl_path": attr.string(default = "msvc_not_used"),
1506        "msvc_env_include": attr.string(default = "msvc_not_used"),
1507        "msvc_env_lib": attr.string(default = "msvc_not_used"),
1508        "msvc_env_path": attr.string(default = "msvc_not_used"),
1509        "msvc_env_tmp": attr.string(default = "msvc_not_used"),
1510        "msvc_lib_path": attr.string(default = "msvc_not_used"),
1511        "msvc_link_path": attr.string(default = "msvc_not_used"),
1512        "msvc_ml_path": attr.string(default = "msvc_not_used"),
1513    },
1514    provides = [CcToolchainConfigInfo],
1515    executable = True,
1516)
1517