• 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_tool_capability rule."""
15
16load(
17    ":cc_toolchain_info.bzl",
18    "ArgsListInfo",
19    "FeatureConstraintInfo",
20    "FeatureInfo",
21    "ToolCapabilityInfo",
22)
23
24def _cc_tool_capability_impl(ctx):
25    ft = FeatureInfo(
26        name = ctx.attr.feature_name or ctx.label.name,
27        label = ctx.label,
28        enabled = False,
29        args = ArgsListInfo(
30            label = ctx.label,
31            args = (),
32            files = depset(),
33            by_action = (),
34            allowlist_include_directories = depset(),
35        ),
36        implies = depset(),
37        requires_any_of = (),
38        mutually_exclusive = (),
39        # Mark it as external so that it doesn't complain if we say
40        # "requires" on a constraint that was never referenced elsewhere
41        # in the toolchain.
42        external = True,
43        overridable = True,
44        overrides = None,
45        allowlist_include_directories = depset(),
46    )
47    return [
48        ToolCapabilityInfo(label = ctx.label, feature = ft),
49        # Only give it a feature constraint info and not a feature info.
50        # This way you can't imply it - you can only require it.
51        FeatureConstraintInfo(label = ctx.label, all_of = depset([ft])),
52    ]
53
54cc_tool_capability = rule(
55    implementation = _cc_tool_capability_impl,
56    provides = [ToolCapabilityInfo, FeatureConstraintInfo],
57    doc = """A capability is an optional feature that a tool supports.
58
59For example, not all compilers support PIC, so to handle this, we write:
60
61```
62cc_tool(
63    name = "clang",
64    src = "@host_tools/bin/clang",
65    capabilities = [
66        "//cc/toolchains/capabilities:supports_pic",
67    ],
68)
69
70cc_args(
71    name = "pic",
72    requires = [
73        "//cc/toolchains/capabilities:supports_pic"
74    ],
75    args = ["-fPIC"],
76)
77```
78
79This ensures that `-fPIC` is added to the command-line only when we are using a
80tool that supports PIC.
81""",
82    attrs = {
83        "feature_name": attr.string(doc = "The name of the feature to generate for this capability"),
84    },
85)
86