• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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