1# Copyright 2024 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"""Implementation of the cc_toolchain rule.""" 15 16load("//cc/toolchains:cc_toolchain.bzl", _cc_toolchain = "cc_toolchain") 17load( 18 "//cc/toolchains/impl:toolchain_config.bzl", 19 "cc_legacy_file_group", 20 "cc_toolchain_config", 21) 22 23visibility("public") 24 25# Taken from https://bazel.build/docs/cc-toolchain-config-reference#actions 26# TODO: This is best-effort. Update this with the correct file groups once we 27# work out what actions correspond to what file groups. 28_LEGACY_FILE_GROUPS = { 29 "ar_files": [ 30 Label("//cc/toolchains/actions:ar_actions"), 31 ], 32 "as_files": [ 33 Label("//cc/toolchains/actions:assembly_actions"), 34 ], 35 "compiler_files": [ 36 Label("//cc/toolchains/actions:cc_flags_make_variable"), 37 Label("//cc/toolchains/actions:c_compile"), 38 Label("//cc/toolchains/actions:cpp_compile"), 39 Label("//cc/toolchains/actions:cpp_header_parsing"), 40 ], 41 # There are no actions listed for coverage, dwp, and objcopy in action_names.bzl. 42 "coverage_files": [], 43 "dwp_files": [], 44 "linker_files": [ 45 Label("//cc/toolchains/actions:cpp_link_dynamic_library"), 46 Label("//cc/toolchains/actions:cpp_link_nodeps_dynamic_library"), 47 Label("//cc/toolchains/actions:cpp_link_executable"), 48 ], 49 "objcopy_files": [], 50 "strip_files": [ 51 Label("//cc/toolchains/actions:strip"), 52 ], 53} 54 55def cc_toolchain( 56 *, 57 name, 58 tool_map = None, 59 args = [], 60 known_features = [], 61 enabled_features = [], 62 libc_top = None, 63 module_map = None, 64 dynamic_runtime_lib = None, 65 static_runtime_lib = None, 66 supports_header_parsing = False, 67 supports_param_files = False, 68 **kwargs): 69 """A C/C++ toolchain configuration. 70 71 This rule is the core declaration of a complete C/C++ toolchain. It collects together 72 tool configuration, which arguments to pass to each tool, and how 73 [features](https://bazel.build/docs/cc-toolchain-config-reference#features) 74 (dynamically-toggleable argument lists) interact. 75 76 A single `cc_toolchain` may support a wide variety of platforms and configurations through 77 [configurable build attributes](https://bazel.build/docs/configurable-attributes) and 78 [feature relationships](https://bazel.build/docs/cc-toolchain-config-reference#feature-relationships). 79 80 Arguments are applied to commandline invocation of tools in the following order: 81 82 1. Arguments in the order they are listed in listed in [`args`](#cc_toolchain-args). 83 2. Any legacy/built-in features that have been implicitly or explicitly enabled. 84 3. User-defined features in the order they are listed in 85 [`known_features`](#cc_toolchain-known_features). 86 87 When building a `cc_toolchain` configuration, it's important to understand how `select` 88 statements will be evaluated: 89 90 * Most attributes and dependencies of a `cc_toolchain` are evaluated under the target platform. 91 This means that a `@platforms//os:linux` constraint will be satisfied when 92 the final compiled binaries are intended to be ran from a Linux machine. This means that 93 a different operating system (e.g. Windows) may be cross-compiling to linux. 94 * The `cc_tool_map` rule performs a transition to the exec platform when evaluating tools. This 95 means that a if a `@platforms//os:linux` constraint is satisfied in a 96 `select` statement on a `cc_tool`, that means the machine that will run the tool is a Linux 97 machine. This means that a Linux machine may be cross-compiling to a different OS 98 like Windows. 99 100 Generated rules: 101 {name}: A `cc_toolchain` for this toolchain. 102 _{name}_config: A `cc_toolchain_config` for this toolchain. 103 _{name}_*_files: Generated rules that group together files for 104 "ar_files", "as_files", "compiler_files", "coverage_files", 105 "dwp_files", "linker_files", "objcopy_files", and "strip_files" 106 normally enumerated as part of the `cc_toolchain` rule. 107 108 Args: 109 name: (str) The name of the label for the toolchain. 110 tool_map: (Label) The `cc_tool_map` that specifies the tools to use for various toolchain 111 actions. 112 args: (List[Label]) A list of `cc_args` and `cc_arg_list` to apply across this toolchain. 113 known_features: (List[Label]) A list of `cc_feature` rules that this toolchain supports. 114 Whether or not these 115 [features](https://bazel.build/docs/cc-toolchain-config-reference#features) 116 are enabled may change over the course of a build. See the documentation for 117 `cc_feature` for more information. 118 enabled_features: (List[Label]) A list of `cc_feature` rules whose initial state should 119 be `enabled`. Note that it is still possible for these 120 [features](https://bazel.build/docs/cc-toolchain-config-reference#features) 121 to be disabled over the course of a build through other mechanisms. See the 122 documentation for `cc_feature` for more information. 123 libc_top: (Label) A collection of artifacts for libc passed as inputs to compile/linking 124 actions. See 125 [`cc_toolchain.libc_top`](https://bazel.build/reference/be/c-cpp#cc_toolchain.libc_top) 126 for more information. 127 module_map: (Label) Module map artifact to be used for modular builds. See 128 [`cc_toolchain.module_map`](https://bazel.build/reference/be/c-cpp#cc_toolchain.module_map) 129 for more information. 130 dynamic_runtime_lib: (Label) Dynamic library to link when the `static_link_cpp_runtimes` 131 and `dynamic_linking_mode` 132 [features](https://bazel.build/docs/cc-toolchain-config-reference#features) are both 133 enabled. See 134 [`cc_toolchain.dynamic_runtime_lib`](https://bazel.build/reference/be/c-cpp#cc_toolchain.dynamic_runtime_lib) 135 for more information. 136 static_runtime_lib: (Label) Static library to link when the `static_link_cpp_runtimes` 137 and `static_linking_mode` 138 [features](https://bazel.build/docs/cc-toolchain-config-reference#features) are both 139 enabled. See 140 [`cc_toolchain.dynamic_runtime_lib`](https://bazel.build/reference/be/c-cpp#cc_toolchain.dynamic_runtime_lib) 141 for more information. 142 supports_header_parsing: (bool) Whether or not this toolchain supports header parsing 143 actions. See 144 [`cc_toolchain.supports_header_parsing`](https://bazel.build/reference/be/c-cpp#cc_toolchain.supports_header_parsing) 145 for more information. 146 supports_param_files: (bool) Whether or not this toolchain supports linking via param files. 147 See 148 [`cc_toolchain.supports_param_files`](https://bazel.build/reference/be/c-cpp#cc_toolchain.supports_param_files) 149 for more information. 150 **kwargs: [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) 151 that should be applied to all rules created by this macro. 152 """ 153 cc_toolchain_visibility = kwargs.pop("visibility", default = None) 154 155 for group in _LEGACY_FILE_GROUPS: 156 if group in kwargs: 157 fail("Don't use legacy file groups such as %s. Instead, associate files with `cc_tool` or `cc_args` rules." % group) 158 159 config_name = "_{}_config".format(name) 160 cc_toolchain_config( 161 name = config_name, 162 tool_map = tool_map, 163 args = args, 164 known_features = known_features, 165 enabled_features = enabled_features, 166 visibility = ["//visibility:private"], 167 **kwargs 168 ) 169 170 # Provides ar_files, compiler_files, linker_files, ... 171 legacy_file_groups = {} 172 for group, actions in _LEGACY_FILE_GROUPS.items(): 173 group_name = "_{}_{}".format(name, group) 174 cc_legacy_file_group( 175 name = group_name, 176 config = config_name, 177 actions = actions, 178 visibility = ["//visibility:private"], 179 **kwargs 180 ) 181 legacy_file_groups[group] = group_name 182 183 _cc_toolchain( 184 name = name, 185 toolchain_config = config_name, 186 all_files = config_name, 187 dynamic_runtime_lib = dynamic_runtime_lib, 188 libc_top = libc_top, 189 module_map = module_map, 190 static_runtime_lib = static_runtime_lib, 191 supports_header_parsing = supports_header_parsing, 192 supports_param_files = supports_param_files, 193 # This is required for Bazel versions <= 7.x.x. It is ignored in later versions. 194 exec_transition_for_inputs = False, 195 visibility = cc_toolchain_visibility, 196 **(kwargs | legacy_file_groups) 197 ) 198