• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""cc_toolchain_config rule for configuring ROCm toolchain on Linux."""
2
3load(
4    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
5    "feature",
6    "feature_set",
7    "flag_group",
8    "flag_set",
9    "tool_path",
10    "variable_with_value",
11    "with_feature_set",
12)
13load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
14
15all_compile_actions = [
16    ACTION_NAMES.c_compile,
17    ACTION_NAMES.cpp_compile,
18    ACTION_NAMES.linkstamp_compile,
19    ACTION_NAMES.assemble,
20    ACTION_NAMES.preprocess_assemble,
21    ACTION_NAMES.cpp_header_parsing,
22    ACTION_NAMES.cpp_module_compile,
23    ACTION_NAMES.cpp_module_codegen,
24    ACTION_NAMES.clif_match,
25    ACTION_NAMES.lto_backend,
26]
27
28all_cpp_compile_actions = [
29    ACTION_NAMES.cpp_compile,
30    ACTION_NAMES.linkstamp_compile,
31    ACTION_NAMES.cpp_header_parsing,
32    ACTION_NAMES.cpp_module_compile,
33    ACTION_NAMES.cpp_module_codegen,
34    ACTION_NAMES.clif_match,
35]
36
37preprocessor_compile_actions = [
38    ACTION_NAMES.c_compile,
39    ACTION_NAMES.cpp_compile,
40    ACTION_NAMES.linkstamp_compile,
41    ACTION_NAMES.preprocess_assemble,
42    ACTION_NAMES.cpp_header_parsing,
43    ACTION_NAMES.cpp_module_compile,
44    ACTION_NAMES.clif_match,
45]
46
47codegen_compile_actions = [
48    ACTION_NAMES.c_compile,
49    ACTION_NAMES.cpp_compile,
50    ACTION_NAMES.linkstamp_compile,
51    ACTION_NAMES.assemble,
52    ACTION_NAMES.preprocess_assemble,
53    ACTION_NAMES.cpp_module_codegen,
54    ACTION_NAMES.lto_backend,
55]
56
57all_link_actions = [
58    ACTION_NAMES.cpp_link_executable,
59    ACTION_NAMES.cpp_link_dynamic_library,
60    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
61]
62
63lto_index_actions = [
64    ACTION_NAMES.lto_index_for_executable,
65    ACTION_NAMES.lto_index_for_dynamic_library,
66    ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
67]
68
69def _impl(ctx):
70    tool_paths = [
71        tool_path(name = "gcc", path = ctx.attr.host_compiler_path),
72        tool_path(name = "ar", path = ctx.attr.host_compiler_prefix + "/ar"),
73        tool_path(name = "compat-ld", path = ctx.attr.host_compiler_prefix + "/ld"),
74        tool_path(name = "cpp", path = ctx.attr.host_compiler_prefix + "/cpp"),
75        tool_path(name = "dwp", path = ctx.attr.host_compiler_prefix + "/dwp"),
76        tool_path(name = "gcov", path = ctx.attr.host_compiler_prefix + "/gcov"),
77        tool_path(name = "ld", path = ctx.attr.host_compiler_prefix + "/ld"),
78        tool_path(name = "nm", path = ctx.attr.host_compiler_prefix + "/nm"),
79        tool_path(name = "objcopy", path = ctx.attr.host_compiler_prefix + "/objcopy"),
80        tool_path(name = "objdump", path = ctx.attr.host_compiler_prefix + "/objdump"),
81        tool_path(name = "strip", path = ctx.attr.host_compiler_prefix + "/strip"),
82    ]
83
84    action_configs = []
85
86    supports_pic_feature = feature(
87        name = "supports_pic",
88        enabled = True,
89    )
90    supports_start_end_lib_feature = feature(
91        name = "supports_start_end_lib",
92        enabled = True,
93    )
94
95    default_compile_flags_feature = feature(
96        name = "default_compile_flags",
97        enabled = True,
98        flag_sets = [
99            flag_set(
100                actions = all_compile_actions,
101                flag_groups = ([
102                    flag_group(
103                        flags = ctx.attr.compile_flags,
104                    ),
105                ] if ctx.attr.compile_flags else []),
106            ),
107            flag_set(
108                actions = all_compile_actions,
109                flag_groups = ([
110                    flag_group(
111                        flags = ctx.attr.dbg_compile_flags,
112                    ),
113                ] if ctx.attr.dbg_compile_flags else []),
114                with_features = [with_feature_set(features = ["dbg"])],
115            ),
116            flag_set(
117                actions = all_compile_actions,
118                flag_groups = ([
119                    flag_group(
120                        flags = ctx.attr.opt_compile_flags,
121                    ),
122                ] if ctx.attr.opt_compile_flags else []),
123                with_features = [with_feature_set(features = ["opt"])],
124            ),
125            flag_set(
126                actions = all_cpp_compile_actions + [ACTION_NAMES.lto_backend],
127                flag_groups = ([
128                    flag_group(
129                        flags = ctx.attr.cxx_flags,
130                    ),
131                ] if ctx.attr.cxx_flags else []),
132            ),
133        ],
134    )
135
136    default_link_flags_feature = feature(
137        name = "default_link_flags",
138        enabled = True,
139        flag_sets = [
140            flag_set(
141                actions = all_link_actions + lto_index_actions,
142                flag_groups = ([
143                    flag_group(
144                        flags = ctx.attr.link_flags,
145                    ),
146                ] if ctx.attr.link_flags else []),
147            ),
148            flag_set(
149                actions = all_link_actions + lto_index_actions,
150                flag_groups = ([
151                    flag_group(
152                        flags = ctx.attr.opt_link_flags,
153                    ),
154                ] if ctx.attr.opt_link_flags else []),
155                with_features = [with_feature_set(features = ["opt"])],
156            ),
157        ],
158    )
159
160    dbg_feature = feature(name = "dbg")
161
162    opt_feature = feature(name = "opt")
163
164    sysroot_feature = feature(
165        name = "sysroot",
166        enabled = True,
167        flag_sets = [
168            flag_set(
169                actions = [
170                    ACTION_NAMES.preprocess_assemble,
171                    ACTION_NAMES.linkstamp_compile,
172                    ACTION_NAMES.c_compile,
173                    ACTION_NAMES.cpp_compile,
174                    ACTION_NAMES.cpp_header_parsing,
175                    ACTION_NAMES.cpp_module_compile,
176                    ACTION_NAMES.cpp_module_codegen,
177                    ACTION_NAMES.lto_backend,
178                    ACTION_NAMES.clif_match,
179                ] + all_link_actions + lto_index_actions,
180                flag_groups = [
181                    flag_group(
182                        flags = ["--sysroot=%{sysroot}"],
183                        expand_if_available = "sysroot",
184                    ),
185                ],
186            ),
187        ],
188    )
189
190    fdo_optimize_feature = feature(
191        name = "fdo_optimize",
192        flag_sets = [
193            flag_set(
194                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
195                flag_groups = [
196                    flag_group(
197                        flags = [
198                            "-fprofile-use=%{fdo_profile_path}",
199                            "-fprofile-correction",
200                        ],
201                        expand_if_available = "fdo_profile_path",
202                    ),
203                ],
204            ),
205        ],
206        provides = ["profile"],
207    )
208
209    supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True)
210
211    user_compile_flags_feature = feature(
212        name = "user_compile_flags",
213        enabled = True,
214        flag_sets = [
215            flag_set(
216                actions = all_compile_actions,
217                flag_groups = [
218                    flag_group(
219                        flags = ["%{user_compile_flags}"],
220                        iterate_over = "user_compile_flags",
221                        expand_if_available = "user_compile_flags",
222                    ),
223                ],
224            ),
225        ],
226    )
227
228    unfiltered_compile_flags_feature = feature(
229        name = "unfiltered_compile_flags",
230        enabled = True,
231        flag_sets = [
232            flag_set(
233                actions = all_compile_actions,
234                flag_groups = ([
235                    flag_group(
236                        flags = ctx.attr.unfiltered_compile_flags,
237                    ),
238                ] if ctx.attr.unfiltered_compile_flags else []),
239            ),
240        ],
241    )
242
243    library_search_directories_feature = feature(
244        name = "library_search_directories",
245        flag_sets = [
246            flag_set(
247                actions = all_link_actions + lto_index_actions,
248                flag_groups = [
249                    flag_group(
250                        flags = ["-L%{library_search_directories}"],
251                        iterate_over = "library_search_directories",
252                        expand_if_available = "library_search_directories",
253                    ),
254                ],
255            ),
256        ],
257    )
258
259    static_libgcc_feature = feature(
260        name = "static_libgcc",
261        enabled = True,
262        flag_sets = [
263            flag_set(
264                actions = [
265                    ACTION_NAMES.cpp_link_executable,
266                    ACTION_NAMES.cpp_link_dynamic_library,
267                    ACTION_NAMES.lto_index_for_executable,
268                    ACTION_NAMES.lto_index_for_dynamic_library,
269                ],
270                flag_groups = [flag_group(flags = ["-static-libgcc"])],
271                with_features = [
272                    with_feature_set(features = ["static_link_cpp_runtimes"]),
273                ],
274            ),
275        ],
276    )
277
278    pic_feature = feature(
279        name = "pic",
280        enabled = True,
281        flag_sets = [
282            flag_set(
283                actions = [
284                    ACTION_NAMES.assemble,
285                    ACTION_NAMES.preprocess_assemble,
286                    ACTION_NAMES.linkstamp_compile,
287                    ACTION_NAMES.c_compile,
288                    ACTION_NAMES.cpp_compile,
289                    ACTION_NAMES.cpp_module_codegen,
290                    ACTION_NAMES.cpp_module_compile,
291                ],
292                flag_groups = [
293                    flag_group(flags = ["-fPIC"], expand_if_available = "pic"),
294                ],
295            ),
296        ],
297    )
298
299    per_object_debug_info_feature = feature(
300        name = "per_object_debug_info",
301        flag_sets = [
302            flag_set(
303                actions = [
304                    ACTION_NAMES.assemble,
305                    ACTION_NAMES.preprocess_assemble,
306                    ACTION_NAMES.c_compile,
307                    ACTION_NAMES.cpp_compile,
308                    ACTION_NAMES.cpp_module_codegen,
309                ],
310                flag_groups = [
311                    flag_group(
312                        flags = ["-gsplit-dwarf"],
313                        expand_if_available = "per_object_debug_info_file",
314                    ),
315                ],
316            ),
317        ],
318    )
319
320    preprocessor_defines_feature = feature(
321        name = "preprocessor_defines",
322        enabled = True,
323        flag_sets = [
324            flag_set(
325                actions = [
326                    ACTION_NAMES.preprocess_assemble,
327                    ACTION_NAMES.linkstamp_compile,
328                    ACTION_NAMES.c_compile,
329                    ACTION_NAMES.cpp_compile,
330                    ACTION_NAMES.cpp_header_parsing,
331                    ACTION_NAMES.cpp_module_compile,
332                    ACTION_NAMES.clif_match,
333                ],
334                flag_groups = [
335                    flag_group(
336                        flags = ["-D%{preprocessor_defines}"],
337                        iterate_over = "preprocessor_defines",
338                    ),
339                ],
340            ),
341        ],
342    )
343
344    cs_fdo_optimize_feature = feature(
345        name = "cs_fdo_optimize",
346        flag_sets = [
347            flag_set(
348                actions = [ACTION_NAMES.lto_backend],
349                flag_groups = [
350                    flag_group(
351                        flags = [
352                            "-fprofile-use=%{fdo_profile_path}",
353                            "-Xclang-only=-Wno-profile-instr-unprofiled",
354                            "-Xclang-only=-Wno-profile-instr-out-of-date",
355                            "-fprofile-correction",
356                        ],
357                        expand_if_available = "fdo_profile_path",
358                    ),
359                ],
360            ),
361        ],
362        provides = ["csprofile"],
363    )
364
365    autofdo_feature = feature(
366        name = "autofdo",
367        flag_sets = [
368            flag_set(
369                actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile],
370                flag_groups = [
371                    flag_group(
372                        flags = [
373                            "-fauto-profile=%{fdo_profile_path}",
374                            "-fprofile-correction",
375                        ],
376                        expand_if_available = "fdo_profile_path",
377                    ),
378                ],
379            ),
380        ],
381        provides = ["profile"],
382    )
383
384    runtime_library_search_directories_feature = feature(
385        name = "runtime_library_search_directories",
386        flag_sets = [
387            flag_set(
388                actions = all_link_actions + lto_index_actions,
389                flag_groups = [
390                    flag_group(
391                        iterate_over = "runtime_library_search_directories",
392                        flag_groups = [
393                            flag_group(
394                                flags = [
395                                    "-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}",
396                                ],
397                                expand_if_true = "is_cc_test",
398                            ),
399                            flag_group(
400                                flags = [
401                                    "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
402                                ],
403                                expand_if_false = "is_cc_test",
404                            ),
405                        ],
406                        expand_if_available =
407                            "runtime_library_search_directories",
408                    ),
409                ],
410                with_features = [
411                    with_feature_set(features = ["static_link_cpp_runtimes"]),
412                ],
413            ),
414            flag_set(
415                actions = all_link_actions + lto_index_actions,
416                flag_groups = [
417                    flag_group(
418                        iterate_over = "runtime_library_search_directories",
419                        flag_groups = [
420                            flag_group(
421                                flags = [
422                                    "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
423                                ],
424                            ),
425                        ],
426                        expand_if_available =
427                            "runtime_library_search_directories",
428                    ),
429                ],
430                with_features = [
431                    with_feature_set(
432                        not_features = ["static_link_cpp_runtimes"],
433                    ),
434                ],
435            ),
436        ],
437    )
438
439    fission_support_feature = feature(
440        name = "fission_support",
441        flag_sets = [
442            flag_set(
443                actions = all_link_actions + lto_index_actions,
444                flag_groups = [
445                    flag_group(
446                        flags = ["-Wl,--gdb-index"],
447                        expand_if_available = "is_using_fission",
448                    ),
449                ],
450            ),
451        ],
452    )
453
454    shared_flag_feature = feature(
455        name = "shared_flag",
456        flag_sets = [
457            flag_set(
458                actions = [
459                    ACTION_NAMES.cpp_link_dynamic_library,
460                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
461                    ACTION_NAMES.lto_index_for_dynamic_library,
462                    ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
463                ],
464                flag_groups = [flag_group(flags = ["-shared"])],
465            ),
466        ],
467    )
468
469    random_seed_feature = feature(
470        name = "random_seed",
471        enabled = True,
472        flag_sets = [
473            flag_set(
474                actions = [
475                    ACTION_NAMES.c_compile,
476                    ACTION_NAMES.cpp_compile,
477                    ACTION_NAMES.cpp_module_codegen,
478                    ACTION_NAMES.cpp_module_compile,
479                ],
480                flag_groups = [
481                    flag_group(
482                        flags = ["-frandom-seed=%{output_file}"],
483                        expand_if_available = "output_file",
484                    ),
485                ],
486            ),
487        ],
488    )
489
490    includes_feature = feature(
491        name = "includes",
492        enabled = True,
493        flag_sets = [
494            flag_set(
495                actions = [
496                    ACTION_NAMES.preprocess_assemble,
497                    ACTION_NAMES.linkstamp_compile,
498                    ACTION_NAMES.c_compile,
499                    ACTION_NAMES.cpp_compile,
500                    ACTION_NAMES.cpp_header_parsing,
501                    ACTION_NAMES.cpp_module_compile,
502                    ACTION_NAMES.clif_match,
503                    ACTION_NAMES.objc_compile,
504                    ACTION_NAMES.objcpp_compile,
505                ],
506                flag_groups = [
507                    flag_group(
508                        flags = ["-include", "%{includes}"],
509                        iterate_over = "includes",
510                        expand_if_available = "includes",
511                    ),
512                ],
513            ),
514        ],
515    )
516
517    fdo_instrument_feature = feature(
518        name = "fdo_instrument",
519        flag_sets = [
520            flag_set(
521                actions = [
522                    ACTION_NAMES.c_compile,
523                    ACTION_NAMES.cpp_compile,
524                ] + all_link_actions + lto_index_actions,
525                flag_groups = [
526                    flag_group(
527                        flags = [
528                            "-fprofile-generate=%{fdo_instrument_path}",
529                            "-fno-data-sections",
530                        ],
531                        expand_if_available = "fdo_instrument_path",
532                    ),
533                ],
534            ),
535        ],
536        provides = ["profile"],
537    )
538
539    cs_fdo_instrument_feature = feature(
540        name = "cs_fdo_instrument",
541        flag_sets = [
542            flag_set(
543                actions = [
544                    ACTION_NAMES.c_compile,
545                    ACTION_NAMES.cpp_compile,
546                    ACTION_NAMES.lto_backend,
547                ] + all_link_actions + lto_index_actions,
548                flag_groups = [
549                    flag_group(
550                        flags = [
551                            "-fcs-profile-generate=%{cs_fdo_instrument_path}",
552                        ],
553                        expand_if_available = "cs_fdo_instrument_path",
554                    ),
555                ],
556            ),
557        ],
558        provides = ["csprofile"],
559    )
560
561    include_paths_feature = feature(
562        name = "include_paths",
563        enabled = True,
564        flag_sets = [
565            flag_set(
566                actions = [
567                    ACTION_NAMES.preprocess_assemble,
568                    ACTION_NAMES.linkstamp_compile,
569                    ACTION_NAMES.c_compile,
570                    ACTION_NAMES.cpp_compile,
571                    ACTION_NAMES.cpp_header_parsing,
572                    ACTION_NAMES.cpp_module_compile,
573                    ACTION_NAMES.clif_match,
574                    ACTION_NAMES.objc_compile,
575                    ACTION_NAMES.objcpp_compile,
576                ],
577                flag_groups = [
578                    flag_group(
579                        flags = ["-iquote", "%{quote_include_paths}"],
580                        iterate_over = "quote_include_paths",
581                    ),
582                    flag_group(
583                        flags = ["-I%{include_paths}"],
584                        iterate_over = "include_paths",
585                    ),
586                    flag_group(
587                        flags = ["-isystem", "%{system_include_paths}"],
588                        iterate_over = "system_include_paths",
589                    ),
590                ],
591            ),
592        ],
593    )
594
595    symbol_counts_feature = feature(
596        name = "symbol_counts",
597        flag_sets = [
598            flag_set(
599                actions = all_link_actions + lto_index_actions,
600                flag_groups = [
601                    flag_group(
602                        flags = [
603                            "-Wl,--print-symbol-counts=%{symbol_counts_output}",
604                        ],
605                        expand_if_available = "symbol_counts_output",
606                    ),
607                ],
608            ),
609        ],
610    )
611
612    llvm_coverage_map_format_feature = feature(
613        name = "llvm_coverage_map_format",
614        flag_sets = [
615            flag_set(
616                actions = [
617                    ACTION_NAMES.preprocess_assemble,
618                    ACTION_NAMES.c_compile,
619                    ACTION_NAMES.cpp_compile,
620                    ACTION_NAMES.cpp_module_compile,
621                    ACTION_NAMES.objc_compile,
622                    ACTION_NAMES.objcpp_compile,
623                ],
624                flag_groups = [
625                    flag_group(
626                        flags = [
627                            "-fprofile-instr-generate",
628                            "-fcoverage-mapping",
629                        ],
630                    ),
631                ],
632            ),
633            flag_set(
634                actions = all_link_actions + lto_index_actions + [
635                    "objc-executable",
636                    "objc++-executable",
637                ],
638                flag_groups = [
639                    flag_group(flags = ["-fprofile-instr-generate"]),
640                ],
641            ),
642        ],
643        requires = [feature_set(features = ["coverage"])],
644        provides = ["profile"],
645    )
646
647    strip_debug_symbols_feature = feature(
648        name = "strip_debug_symbols",
649        flag_sets = [
650            flag_set(
651                actions = all_link_actions + lto_index_actions,
652                flag_groups = [
653                    flag_group(
654                        flags = ["-Wl,-S"],
655                        expand_if_available = "strip_debug_symbols",
656                    ),
657                ],
658            ),
659        ],
660    )
661
662    build_interface_libraries_feature = feature(
663        name = "build_interface_libraries",
664        flag_sets = [
665            flag_set(
666                actions = [
667                    ACTION_NAMES.cpp_link_dynamic_library,
668                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
669                    ACTION_NAMES.lto_index_for_dynamic_library,
670                    ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
671                ],
672                flag_groups = [
673                    flag_group(
674                        flags = [
675                            "%{generate_interface_library}",
676                            "%{interface_library_builder_path}",
677                            "%{interface_library_input_path}",
678                            "%{interface_library_output_path}",
679                        ],
680                        expand_if_available = "generate_interface_library",
681                    ),
682                ],
683                with_features = [
684                    with_feature_set(
685                        features = ["supports_interface_shared_libraries"],
686                    ),
687                ],
688            ),
689        ],
690    )
691
692    libraries_to_link_feature = feature(
693        name = "libraries_to_link",
694        flag_sets = [
695            flag_set(
696                actions = all_link_actions + lto_index_actions,
697                flag_groups = [
698                    flag_group(
699                        iterate_over = "libraries_to_link",
700                        flag_groups = [
701                            flag_group(
702                                flags = ["-Wl,--start-lib"],
703                                expand_if_equal = variable_with_value(
704                                    name = "libraries_to_link.type",
705                                    value = "object_file_group",
706                                ),
707                            ),
708                            flag_group(
709                                flags = ["-Wl,-whole-archive"],
710                                expand_if_true =
711                                    "libraries_to_link.is_whole_archive",
712                            ),
713                            flag_group(
714                                flags = ["%{libraries_to_link.object_files}"],
715                                iterate_over = "libraries_to_link.object_files",
716                                expand_if_equal = variable_with_value(
717                                    name = "libraries_to_link.type",
718                                    value = "object_file_group",
719                                ),
720                            ),
721                            flag_group(
722                                flags = ["%{libraries_to_link.name}"],
723                                expand_if_equal = variable_with_value(
724                                    name = "libraries_to_link.type",
725                                    value = "object_file",
726                                ),
727                            ),
728                            flag_group(
729                                flags = ["%{libraries_to_link.name}"],
730                                expand_if_equal = variable_with_value(
731                                    name = "libraries_to_link.type",
732                                    value = "interface_library",
733                                ),
734                            ),
735                            flag_group(
736                                flags = ["%{libraries_to_link.name}"],
737                                expand_if_equal = variable_with_value(
738                                    name = "libraries_to_link.type",
739                                    value = "static_library",
740                                ),
741                            ),
742                            flag_group(
743                                flags = ["-l%{libraries_to_link.name}"],
744                                expand_if_equal = variable_with_value(
745                                    name = "libraries_to_link.type",
746                                    value = "dynamic_library",
747                                ),
748                            ),
749                            flag_group(
750                                flags = ["-l:%{libraries_to_link.name}"],
751                                expand_if_equal = variable_with_value(
752                                    name = "libraries_to_link.type",
753                                    value = "versioned_dynamic_library",
754                                ),
755                            ),
756                            flag_group(
757                                flags = ["-Wl,-no-whole-archive"],
758                                expand_if_true = "libraries_to_link.is_whole_archive",
759                            ),
760                            flag_group(
761                                flags = ["-Wl,--end-lib"],
762                                expand_if_equal = variable_with_value(
763                                    name = "libraries_to_link.type",
764                                    value = "object_file_group",
765                                ),
766                            ),
767                        ],
768                        expand_if_available = "libraries_to_link",
769                    ),
770                    flag_group(
771                        flags = ["-Wl,@%{thinlto_param_file}"],
772                        expand_if_true = "thinlto_param_file",
773                    ),
774                ],
775            ),
776        ],
777    )
778
779    user_link_flags_feature = feature(
780        name = "user_link_flags",
781        flag_sets = [
782            flag_set(
783                actions = all_link_actions + lto_index_actions,
784                flag_groups = [
785                    flag_group(
786                        flags = ["%{user_link_flags}"],
787                        iterate_over = "user_link_flags",
788                        expand_if_available = "user_link_flags",
789                    ),
790                ] + ([flag_group(flags = ctx.attr.link_libs)] if ctx.attr.link_libs else []),
791            ),
792        ],
793    )
794
795    fdo_prefetch_hints_feature = feature(
796        name = "fdo_prefetch_hints",
797        flag_sets = [
798            flag_set(
799                actions = [
800                    ACTION_NAMES.c_compile,
801                    ACTION_NAMES.cpp_compile,
802                    ACTION_NAMES.lto_backend,
803                ],
804                flag_groups = [
805                    flag_group(
806                        flags = [
807                            "-Xclang-only=-mllvm",
808                            "-Xclang-only=-prefetch-hints-file=%{fdo_prefetch_hints_path}",
809                        ],
810                        expand_if_available = "fdo_prefetch_hints_path",
811                    ),
812                ],
813            ),
814        ],
815    )
816
817    linkstamps_feature = feature(
818        name = "linkstamps",
819        flag_sets = [
820            flag_set(
821                actions = all_link_actions + lto_index_actions,
822                flag_groups = [
823                    flag_group(
824                        flags = ["%{linkstamp_paths}"],
825                        iterate_over = "linkstamp_paths",
826                        expand_if_available = "linkstamp_paths",
827                    ),
828                ],
829            ),
830        ],
831    )
832
833    gcc_coverage_map_format_feature = feature(
834        name = "gcc_coverage_map_format",
835        flag_sets = [
836            flag_set(
837                actions = [
838                    ACTION_NAMES.preprocess_assemble,
839                    ACTION_NAMES.c_compile,
840                    ACTION_NAMES.cpp_compile,
841                    ACTION_NAMES.cpp_module_compile,
842                    ACTION_NAMES.objc_compile,
843                    ACTION_NAMES.objcpp_compile,
844                    "objc-executable",
845                    "objc++-executable",
846                ],
847                flag_groups = [
848                    flag_group(
849                        flags = ["-fprofile-arcs", "-ftest-coverage"],
850                        expand_if_available = "gcov_gcno_file",
851                    ),
852                ],
853            ),
854            flag_set(
855                actions = all_link_actions + lto_index_actions,
856                flag_groups = [flag_group(flags = ["--coverage"])],
857            ),
858        ],
859        requires = [feature_set(features = ["coverage"])],
860        provides = ["profile"],
861    )
862
863    archiver_flags_feature = feature(
864        name = "archiver_flags",
865        flag_sets = [
866            flag_set(
867                actions = [ACTION_NAMES.cpp_link_static_library],
868                flag_groups = [
869                    flag_group(flags = ["rcsD"]),
870                    flag_group(
871                        flags = ["%{output_execpath}"],
872                        expand_if_available = "output_execpath",
873                    ),
874                ],
875            ),
876            flag_set(
877                actions = [ACTION_NAMES.cpp_link_static_library],
878                flag_groups = [
879                    flag_group(
880                        iterate_over = "libraries_to_link",
881                        flag_groups = [
882                            flag_group(
883                                flags = ["%{libraries_to_link.name}"],
884                                expand_if_equal = variable_with_value(
885                                    name = "libraries_to_link.type",
886                                    value = "object_file",
887                                ),
888                            ),
889                            flag_group(
890                                flags = ["%{libraries_to_link.object_files}"],
891                                iterate_over = "libraries_to_link.object_files",
892                                expand_if_equal = variable_with_value(
893                                    name = "libraries_to_link.type",
894                                    value = "object_file_group",
895                                ),
896                            ),
897                        ],
898                        expand_if_available = "libraries_to_link",
899                    ),
900                ],
901            ),
902        ],
903    )
904
905    force_pic_flags_feature = feature(
906        name = "force_pic_flags",
907        flag_sets = [
908            flag_set(
909                actions = [
910                    ACTION_NAMES.cpp_link_executable,
911                    ACTION_NAMES.lto_index_for_executable,
912                ],
913                flag_groups = [
914                    flag_group(
915                        flags = ["-pie"],
916                        expand_if_available = "force_pic",
917                    ),
918                ],
919            ),
920        ],
921    )
922
923    dependency_file_feature = feature(
924        name = "dependency_file",
925        enabled = True,
926        flag_sets = [
927            flag_set(
928                actions = [
929                    ACTION_NAMES.assemble,
930                    ACTION_NAMES.preprocess_assemble,
931                    ACTION_NAMES.c_compile,
932                    ACTION_NAMES.cpp_compile,
933                    ACTION_NAMES.cpp_module_compile,
934                    ACTION_NAMES.objc_compile,
935                    ACTION_NAMES.objcpp_compile,
936                    ACTION_NAMES.cpp_header_parsing,
937                    ACTION_NAMES.clif_match,
938                ],
939                flag_groups = [
940                    flag_group(
941                        flags = ["-MD", "-MF", "%{dependency_file}"],
942                        expand_if_available = "dependency_file",
943                    ),
944                ],
945            ),
946        ],
947    )
948
949    dynamic_library_linker_tool_path = tool_paths
950    dynamic_library_linker_tool_feature = feature(
951        name = "dynamic_library_linker_tool",
952        flag_sets = [
953            flag_set(
954                actions = [
955                    ACTION_NAMES.cpp_link_dynamic_library,
956                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
957                    ACTION_NAMES.lto_index_for_dynamic_library,
958                    ACTION_NAMES.lto_index_for_nodeps_dynamic_library,
959                ],
960                flag_groups = [
961                    flag_group(
962                        flags = [" + cppLinkDynamicLibraryToolPath + "],
963                        expand_if_available = "generate_interface_library",
964                    ),
965                ],
966                with_features = [
967                    with_feature_set(
968                        features = ["supports_interface_shared_libraries"],
969                    ),
970                ],
971            ),
972        ],
973    )
974
975    output_execpath_flags_feature = feature(
976        name = "output_execpath_flags",
977        flag_sets = [
978            flag_set(
979                actions = all_link_actions + lto_index_actions,
980                flag_groups = [
981                    flag_group(
982                        flags = ["-o", "%{output_execpath}"],
983                        expand_if_available = "output_execpath",
984                    ),
985                ],
986            ),
987        ],
988    )
989
990    # Note that we also set --coverage for c++-link-nodeps-dynamic-library. The
991    # generated code contains references to gcov symbols, and the dynamic linker
992    # can't resolve them unless the library is linked against gcov.
993    coverage_feature = feature(
994        name = "coverage",
995        provides = ["profile"],
996        flag_sets = [
997            flag_set(
998                actions = [
999                    ACTION_NAMES.preprocess_assemble,
1000                    ACTION_NAMES.c_compile,
1001                    ACTION_NAMES.cpp_compile,
1002                    ACTION_NAMES.cpp_header_parsing,
1003                    ACTION_NAMES.cpp_module_compile,
1004                ],
1005                flag_groups = ([
1006                    flag_group(flags = ctx.attr.coverage_compile_flags),
1007                ] if ctx.attr.coverage_compile_flags else []),
1008            ),
1009            flag_set(
1010                actions = all_link_actions + lto_index_actions,
1011                flag_groups = ([
1012                    flag_group(flags = ctx.attr.coverage_link_flags),
1013                ] if ctx.attr.coverage_link_flags else []),
1014            ),
1015        ],
1016    )
1017
1018    build_id_feature = feature(
1019        name = "build-id",
1020        enabled = True,
1021        flag_sets = [
1022            flag_set(
1023                actions = all_link_actions,
1024                flag_groups = [
1025                    flag_group(
1026                        flags = ["-Wl,--build-id=md5", "-Wl,--hash-style=gnu"],
1027                    ),
1028                ],
1029            ),
1030        ],
1031    )
1032
1033    no_canonical_prefixes_feature = feature(
1034        name = "no-canonical-prefixes",
1035        enabled = True,
1036        flag_sets = [
1037            flag_set(
1038                actions = [
1039                    ACTION_NAMES.c_compile,
1040                    ACTION_NAMES.cpp_compile,
1041                    ACTION_NAMES.cpp_link_executable,
1042                    ACTION_NAMES.cpp_link_dynamic_library,
1043                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
1044                ],
1045                flag_groups = [
1046                    flag_group(
1047                        flags = [
1048                            "-no-canonical-prefixes",
1049                            "-fno-canonical-system-headers",
1050                        ]
1051                    ),
1052                ],
1053            ),
1054        ],
1055    )
1056
1057    linker_bin_path_feature = feature(
1058        name = "linker-bin-path",
1059        enabled = True,
1060        flag_sets = [
1061            flag_set(
1062                actions = all_link_actions,
1063                flag_groups = [flag_group(flags = ["-B" + ctx.attr.linker_bin_path])],
1064            ),
1065        ],
1066    )
1067
1068    features = [
1069        dependency_file_feature,
1070        random_seed_feature,
1071        pic_feature,
1072        per_object_debug_info_feature,
1073        preprocessor_defines_feature,
1074        includes_feature,
1075        include_paths_feature,
1076        fdo_instrument_feature,
1077        cs_fdo_instrument_feature,
1078        cs_fdo_optimize_feature,
1079        fdo_prefetch_hints_feature,
1080        autofdo_feature,
1081        build_interface_libraries_feature,
1082        dynamic_library_linker_tool_feature,
1083        symbol_counts_feature,
1084        shared_flag_feature,
1085        linkstamps_feature,
1086        output_execpath_flags_feature,
1087        runtime_library_search_directories_feature,
1088        library_search_directories_feature,
1089        archiver_flags_feature,
1090        force_pic_flags_feature,
1091        fission_support_feature,
1092        strip_debug_symbols_feature,
1093        coverage_feature,
1094        supports_pic_feature,
1095    ] + (
1096        [
1097            supports_start_end_lib_feature,
1098        ] if ctx.attr.supports_start_end_lib else []
1099    ) + [
1100        default_compile_flags_feature,
1101        default_link_flags_feature,
1102        libraries_to_link_feature,
1103        user_link_flags_feature,
1104        static_libgcc_feature,
1105        fdo_optimize_feature,
1106        supports_dynamic_linker_feature,
1107        dbg_feature,
1108        opt_feature,
1109        user_compile_flags_feature,
1110        sysroot_feature,
1111        unfiltered_compile_flags_feature,
1112        build_id_feature,
1113        no_canonical_prefixes_feature,
1114        linker_bin_path_feature,
1115    ]
1116
1117    return cc_common.create_cc_toolchain_config_info(
1118        ctx = ctx,
1119        features = features,
1120        action_configs = action_configs,
1121        cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories,
1122        toolchain_identifier = ctx.attr.toolchain_identifier,
1123        host_system_name = ctx.attr.host_system_name,
1124        target_system_name = ctx.attr.target_system_name,
1125        target_cpu = ctx.attr.cpu,
1126        target_libc = ctx.attr.target_libc,
1127        compiler = ctx.attr.compiler,
1128        abi_version = ctx.attr.abi_version,
1129        abi_libc_version = ctx.attr.abi_libc_version,
1130        tool_paths = tool_paths,
1131    )
1132
1133cc_toolchain_config = rule(
1134    implementation = _impl,
1135    attrs = {
1136        "cpu": attr.string(mandatory = True),
1137        "compiler": attr.string(mandatory = True),
1138        "toolchain_identifier": attr.string(mandatory = True),
1139        "host_system_name": attr.string(mandatory = True),
1140        "target_system_name": attr.string(mandatory = True),
1141        "target_libc": attr.string(mandatory = True),
1142        "abi_version": attr.string(mandatory = True),
1143        "abi_libc_version": attr.string(mandatory = True),
1144        "cxx_builtin_include_directories": attr.string_list(),
1145        "compile_flags": attr.string_list(),
1146        "dbg_compile_flags": attr.string_list(),
1147        "opt_compile_flags": attr.string_list(),
1148        "cxx_flags": attr.string_list(),
1149        "link_flags": attr.string_list(),
1150        "link_libs": attr.string_list(),
1151        "opt_link_flags": attr.string_list(),
1152        "unfiltered_compile_flags": attr.string_list(),
1153        "coverage_compile_flags": attr.string_list(),
1154        "coverage_link_flags": attr.string_list(),
1155        "supports_start_end_lib": attr.bool(),
1156        "host_compiler_path": attr.string(),
1157        "host_compiler_prefix": attr.string(),
1158        "linker_bin_path": attr.string(),
1159    },
1160    provides = [CcToolchainConfigInfo],
1161)
1162
1163