| # 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("@bazel_features//:features.bzl", "bazel_features") | |
| load("//cc/toolchains:cc_toolchain.bzl", _cc_toolchain = "cc_toolchain") | |
| load("//cc/toolchains:legacy_file_group.bzl", "LEGACY_FILE_GROUPS") | |
| load( | |
| "//cc/toolchains/impl:toolchain_config.bzl", | |
| "cc_legacy_file_group", | |
| "cc_toolchain_config", | |
| ) | |
| visibility("public") | |
| _CPU = select({ | |
| Label("//cc/toolchains/impl:darwin_aarch64"): "darwin_arm64", | |
| Label("//cc/toolchains/impl:darwin_x86_64"): "darwin_x86_64", | |
| Label("//cc/toolchains/impl:linux_aarch64"): "aarch64", | |
| Label("//cc/toolchains/impl:linux_x86_64"): "k8", | |
| Label("//cc/toolchains/impl:windows_x86_32"): "win32", | |
| Label("//cc/toolchains/impl:windows_x86_64"): "win64", | |
| "//conditions:default": "", | |
| }) | |
| def cc_toolchain( | |
| *, | |
| name, | |
| tool_map = None, | |
| args = [], | |
| artifact_name_patterns = [], | |
| make_variables = [], | |
| legacy_tools = [], | |
| known_features = [], | |
| enabled_features = [], | |
| grep_includes = None, | |
| libc_top = None, | |
| module_map = None, | |
| dynamic_runtime_lib = None, | |
| static_runtime_lib = None, | |
| supports_header_parsing = False, | |
| supports_param_files = False, | |
| compiler = "", | |
| cpu = "", | |
| target_libc = None, | |
| target_system_name = None, | |
| **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. | |
| artifact_name_patterns: (List[Label]) A list of `cc_artifact_name_pattern` defining patterns | |
| for names of artifacts created by this toolchain. | |
| make_variables: (List[Label]) A list of `cc_make_variable` defining variable substitutions. | |
| legacy_tools: (List[Label]) A list of `cc_legacy_tool` rules that specify tools by filesystem | |
| path. These are used to populate the legacy `tool_paths` parameter of the toolchain | |
| configuration, which is required by some Bazel features (e.g. coverage). | |
| 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. | |
| grep_includes: (Label) Executable used to extract include directives from C/C++ source | |
| files. | |
| 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. | |
| compiler: (str) The type of compiler used by this toolchain (e.g. "gcc", "clang"). The current | |
| toolchain's compiler is exposed to `@rules_cc//cc/private/toolchain:compiler | |
| (compiler_flag)` as a flag value. | |
| cpu: (str) DEPRECATED: CPU string (ex: "darwin_arm64", "k8") exposed | |
| through the `target_cpu` attribute of the toolchain configuration. We | |
| should not add new readers of this value, but there are many existing | |
| ones in the wild. | |
| target_libc: (str) The name of the C standard library targeted by this toolchain | |
| (e.g. "glibc", "musl"), optionally followed by a version suffix (e.g. | |
| "glibc-2.2.2"). The current toolchain's C standard library is exposed to | |
| `select()` statements via the config settings in `@rules_cc//cc/libc`. If not provided, | |
| a best effort default is selected. | |
| target_system_name: (str) The target system name for this toolchain. Bazel doesn't use this | |
| but starlark rules can read this value through `toolchain_info.target_gnu_system_name`. | |
| This string is commonly the target triple you would pass to `clang -target` (e.g. "x86_64-unknown-linux-gnu"). | |
| If not provided, a best effort default is selected. | |
| **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) | |
| target_system_name = target_system_name or select({ | |
| Label("//cc/toolchains/impl:darwin_aarch64"): "aarch64-apple-darwin", | |
| Label("//cc/toolchains/impl:darwin_x86_64"): "x86_64-apple-darwin", | |
| Label("//cc/toolchains/impl:linux_aarch64"): "aarch64-unknown-linux-gnu", | |
| Label("//cc/toolchains/impl:linux_x86_64"): "x86_64-unknown-linux-gnu", | |
| Label("//cc/toolchains/impl:windows_x86_32"): "i686-pc-windows-msvc", | |
| Label("//cc/toolchains/impl:windows_x86_64"): "x86_64-pc-windows-msvc", | |
| "//conditions:default": "", | |
| }) | |
| target_libc = target_libc or select({ | |
| Label("//cc/settings:apple_constraint"): "macosx", | |
| Label("@platforms//os:linux"): "glibc", | |
| Label("@platforms//os:windows"): "ucrt", | |
| "//conditions:default": "", | |
| }) | |
| if bazel_features.cc.supports_starlarkified_toolchains: | |
| _cc_toolchain( | |
| name = name, | |
| tool_map = tool_map, | |
| args = args, | |
| artifact_name_patterns = artifact_name_patterns, | |
| make_variables = make_variables, | |
| legacy_tools = legacy_tools, | |
| known_features = known_features, | |
| enabled_features = enabled_features, | |
| grep_includes = grep_includes, | |
| compiler = compiler, | |
| target_libc = target_libc, | |
| cpu = cpu or _CPU, | |
| target_system_name = target_system_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, | |
| visibility = cc_toolchain_visibility, | |
| **kwargs | |
| ) | |
| return | |
| config_name = "_{}_config".format(name) | |
| cc_toolchain_config( | |
| name = config_name, | |
| tool_map = tool_map, | |
| args = args, | |
| artifact_name_patterns = artifact_name_patterns, | |
| make_variables = make_variables, | |
| legacy_tools = legacy_tools, | |
| known_features = known_features, | |
| enabled_features = enabled_features, | |
| compiler = compiler, | |
| cpu = cpu or _CPU, | |
| target_libc = target_libc, | |
| target_system_name = target_system_name, | |
| 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) | |
| ) |