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