| # Copyright 2024 The Bazel Authors. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| """Implementation of the cc_toolchain rule.""" |
| |
| load("//cc/toolchains:cc_toolchain.bzl", _cc_toolchain = "cc_toolchain") |
| load( |
| "//cc/toolchains/impl:toolchain_config.bzl", |
| "cc_legacy_file_group", |
| "cc_toolchain_config", |
| ) |
| |
| visibility("public") |
| |
| # Taken from https://bazel.build/docs/cc-toolchain-config-reference#actions |
| # TODO: This is best-effort. Update this with the correct file groups once we |
| # work out what actions correspond to what file groups. |
| _LEGACY_FILE_GROUPS = { |
| "ar_files": [ |
| Label("//cc/toolchains/actions:ar_actions"), |
| ], |
| "as_files": [ |
| Label("//cc/toolchains/actions:assembly_actions"), |
| ], |
| "compiler_files": [ |
| Label("//cc/toolchains/actions:cc_flags_make_variable"), |
| Label("//cc/toolchains/actions:c_compile"), |
| Label("//cc/toolchains/actions:cpp_compile"), |
| Label("//cc/toolchains/actions:cpp_header_parsing"), |
| ], |
| # There are no actions listed for coverage, dwp, and objcopy in action_names.bzl. |
| "coverage_files": [], |
| "dwp_files": [], |
| "linker_files": [ |
| Label("//cc/toolchains/actions:cpp_link_dynamic_library"), |
| Label("//cc/toolchains/actions:cpp_link_nodeps_dynamic_library"), |
| Label("//cc/toolchains/actions:cpp_link_executable"), |
| ], |
| "objcopy_files": [], |
| "strip_files": [ |
| Label("//cc/toolchains/actions:strip"), |
| ], |
| } |
| |
| def cc_toolchain( |
| *, |
| name, |
| tool_map = None, |
| args = [], |
| known_features = [], |
| enabled_features = [], |
| libc_top = None, |
| module_map = None, |
| dynamic_runtime_lib = None, |
| static_runtime_lib = None, |
| supports_header_parsing = False, |
| supports_param_files = False, |
| **kwargs): |
| """A C/C++ toolchain configuration. |
| |
| This rule is the core declaration of a complete C/C++ toolchain. It collects together |
| tool configuration, which arguments to pass to each tool, and how |
| [features](https://bazel.build/docs/cc-toolchain-config-reference#features) |
| (dynamically-toggleable argument lists) interact. |
| |
| A single `cc_toolchain` may support a wide variety of platforms and configurations through |
| [configurable build attributes](https://bazel.build/docs/configurable-attributes) and |
| [feature relationships](https://bazel.build/docs/cc-toolchain-config-reference#feature-relationships). |
| |
| Arguments are applied to commandline invocation of tools in the following order: |
| |
| 1. Arguments in the order they are listed in listed in [`args`](#cc_toolchain-args). |
| 2. Any legacy/built-in features that have been implicitly or explicitly enabled. |
| 3. User-defined features in the order they are listed in |
| [`known_features`](#cc_toolchain-known_features). |
| |
| When building a `cc_toolchain` configuration, it's important to understand how `select` |
| statements will be evaluated: |
| |
| * Most attributes and dependencies of a `cc_toolchain` are evaluated under the target platform. |
| This means that a `@platforms//os:linux` constraint will be satisfied when |
| the final compiled binaries are intended to be ran from a Linux machine. This means that |
| a different operating system (e.g. Windows) may be cross-compiling to linux. |
| * The `cc_tool_map` rule performs a transition to the exec platform when evaluating tools. This |
| means that a if a `@platforms//os:linux` constraint is satisfied in a |
| `select` statement on a `cc_tool`, that means the machine that will run the tool is a Linux |
| machine. This means that a Linux machine may be cross-compiling to a different OS |
| like Windows. |
| |
| Generated rules: |
| {name}: A `cc_toolchain` for this toolchain. |
| _{name}_config: A `cc_toolchain_config` for this toolchain. |
| _{name}_*_files: Generated rules that group together files for |
| "ar_files", "as_files", "compiler_files", "coverage_files", |
| "dwp_files", "linker_files", "objcopy_files", and "strip_files" |
| normally enumerated as part of the `cc_toolchain` rule. |
| |
| Args: |
| name: (str) The name of the label for the toolchain. |
| tool_map: (Label) The `cc_tool_map` that specifies the tools to use for various toolchain |
| actions. |
| args: (List[Label]) A list of `cc_args` and `cc_arg_list` to apply across this toolchain. |
| known_features: (List[Label]) A list of `cc_feature` rules that this toolchain supports. |
| Whether or not these |
| [features](https://bazel.build/docs/cc-toolchain-config-reference#features) |
| are enabled may change over the course of a build. See the documentation for |
| `cc_feature` for more information. |
| enabled_features: (List[Label]) A list of `cc_feature` rules whose initial state should |
| be `enabled`. Note that it is still possible for these |
| [features](https://bazel.build/docs/cc-toolchain-config-reference#features) |
| to be disabled over the course of a build through other mechanisms. See the |
| documentation for `cc_feature` for more information. |
| libc_top: (Label) A collection of artifacts for libc passed as inputs to compile/linking |
| actions. See |
| [`cc_toolchain.libc_top`](https://bazel.build/reference/be/c-cpp#cc_toolchain.libc_top) |
| for more information. |
| module_map: (Label) Module map artifact to be used for modular builds. See |
| [`cc_toolchain.module_map`](https://bazel.build/reference/be/c-cpp#cc_toolchain.module_map) |
| for more information. |
| dynamic_runtime_lib: (Label) Dynamic library to link when the `static_link_cpp_runtimes` |
| and `dynamic_linking_mode` |
| [features](https://bazel.build/docs/cc-toolchain-config-reference#features) are both |
| enabled. See |
| [`cc_toolchain.dynamic_runtime_lib`](https://bazel.build/reference/be/c-cpp#cc_toolchain.dynamic_runtime_lib) |
| for more information. |
| static_runtime_lib: (Label) Static library to link when the `static_link_cpp_runtimes` |
| and `static_linking_mode` |
| [features](https://bazel.build/docs/cc-toolchain-config-reference#features) are both |
| enabled. See |
| [`cc_toolchain.dynamic_runtime_lib`](https://bazel.build/reference/be/c-cpp#cc_toolchain.dynamic_runtime_lib) |
| for more information. |
| supports_header_parsing: (bool) Whether or not this toolchain supports header parsing |
| actions. See |
| [`cc_toolchain.supports_header_parsing`](https://bazel.build/reference/be/c-cpp#cc_toolchain.supports_header_parsing) |
| for more information. |
| supports_param_files: (bool) Whether or not this toolchain supports linking via param files. |
| See |
| [`cc_toolchain.supports_param_files`](https://bazel.build/reference/be/c-cpp#cc_toolchain.supports_param_files) |
| for more information. |
| **kwargs: [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) |
| that should be applied to all rules created by this macro. |
| """ |
| cc_toolchain_visibility = kwargs.pop("visibility", default = None) |
| |
| for group in _LEGACY_FILE_GROUPS: |
| if group in kwargs: |
| fail("Don't use legacy file groups such as %s. Instead, associate files with `cc_tool` or `cc_args` rules." % group) |
| |
| config_name = "_{}_config".format(name) |
| cc_toolchain_config( |
| name = config_name, |
| tool_map = tool_map, |
| args = args, |
| known_features = known_features, |
| enabled_features = enabled_features, |
| visibility = ["//visibility:private"], |
| **kwargs |
| ) |
| |
| # Provides ar_files, compiler_files, linker_files, ... |
| legacy_file_groups = {} |
| for group, actions in _LEGACY_FILE_GROUPS.items(): |
| group_name = "_{}_{}".format(name, group) |
| cc_legacy_file_group( |
| name = group_name, |
| config = config_name, |
| actions = actions, |
| visibility = ["//visibility:private"], |
| **kwargs |
| ) |
| legacy_file_groups[group] = group_name |
| |
| _cc_toolchain( |
| name = name, |
| toolchain_config = config_name, |
| all_files = config_name, |
| dynamic_runtime_lib = dynamic_runtime_lib, |
| libc_top = libc_top, |
| module_map = module_map, |
| static_runtime_lib = static_runtime_lib, |
| supports_header_parsing = supports_header_parsing, |
| supports_param_files = supports_param_files, |
| # This is required for Bazel versions <= 7.x.x. It is ignored in later versions. |
| exec_transition_for_inputs = False, |
| visibility = cc_toolchain_visibility, |
| **(kwargs | legacy_file_groups) |
| ) |