github.com/GoogleCloudPlatform/testgrid@v0.0.174/cc/cc_toolchain_config.bzl (about)

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