mirror of https://github.com/bazelbuild/rules_cc
Document feature-related toolchain rules
BEGIN_PUBLIC Document feature-related toolchain rules Extends the toolchain API documentation to cover all feature-related rules. END_PUBLIC PiperOrigin-RevId: 681476538 Change-Id: Icfe35e03937bdb0bc55eae24f57eafe0db7b16eb
This commit is contained in:
parent
b06d2f7d53
commit
1af2140e73
|
@ -110,22 +110,23 @@ While two features with the same `feature_name` may not be bound to the same
|
||||||
toolchain, they can happily live alongside each other in the same BUILD file.
|
toolchain, they can happily live alongside each other in the same BUILD file.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
```
|
||||||
|
cc_feature(
|
||||||
|
name = "sysroot_macos",
|
||||||
|
feature_name = "sysroot",
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
cc_feature(
|
cc_feature(
|
||||||
name = "sysroot_macos",
|
name = "sysroot_linux",
|
||||||
feature_name = "sysroot",
|
feature_name = "sysroot",
|
||||||
...
|
...
|
||||||
)
|
)
|
||||||
|
```
|
||||||
cc_feature(
|
|
||||||
name = "sysroot_linux",
|
|
||||||
feature_name = "sysroot",
|
|
||||||
...
|
|
||||||
)
|
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
"args": attr.label_list(
|
"args": attr.label_list(
|
||||||
doc = """Args that, when expanded, implement this feature.""",
|
doc = """A list of `cc_args` or `cc_args_list` labels that are expanded when this feature is enabled.""",
|
||||||
providers = [ArgsListInfo],
|
providers = [ArgsListInfo],
|
||||||
),
|
),
|
||||||
"requires_any_of": attr.label_list(
|
"requires_any_of": attr.label_list(
|
||||||
|
@ -152,7 +153,7 @@ silently disabled.
|
||||||
),
|
),
|
||||||
"mutually_exclusive": attr.label_list(
|
"mutually_exclusive": attr.label_list(
|
||||||
providers = [MutuallyExclusiveCategoryInfo],
|
providers = [MutuallyExclusiveCategoryInfo],
|
||||||
doc = """A list of things that this is mutually exclusive with.
|
doc = """A list of things that this feature is mutually exclusive with.
|
||||||
|
|
||||||
It can be either:
|
It can be either:
|
||||||
* A feature, in which case the two features are mutually exclusive.
|
* A feature, in which case the two features are mutually exclusive.
|
||||||
|
@ -171,14 +172,16 @@ In the example below, if you missed the "overrides" attribute, it would complain
|
||||||
that the feature "opt" was defined twice.
|
that the feature "opt" was defined twice.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
```
|
||||||
|
load("//cc/toolchains:feature.bzl", "cc_feature")
|
||||||
|
|
||||||
cc_feature(
|
cc_feature(
|
||||||
name = "opt",
|
name = "opt",
|
||||||
feature_name = "opt",
|
feature_name = "opt",
|
||||||
...
|
args = [":size_optimized"],
|
||||||
overrides = "@toolchain//features/well_known:opt",
|
overrides = "//cc/toolchains/features:opt",
|
||||||
)
|
)
|
||||||
|
```
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -188,53 +191,58 @@ Example:
|
||||||
FeatureConstraintInfo,
|
FeatureConstraintInfo,
|
||||||
MutuallyExclusiveCategoryInfo,
|
MutuallyExclusiveCategoryInfo,
|
||||||
],
|
],
|
||||||
doc = """Defines the implemented behavior of a C/C++ toolchain feature.
|
doc = """A dynamic set of toolchain flags that create a singular [feature](https://bazel.build/docs/cc-toolchain-config-reference#features) definition.
|
||||||
|
|
||||||
A feature is basically a toggleable list of args. There are a variety of
|
A feature is basically a dynamically toggleable `cc_args_list`. There are a variety of
|
||||||
dependencies and compatibility requirements that must be satisfied for the
|
dependencies and compatibility requirements that must be satisfied to enable a
|
||||||
listed args to be applied.
|
`cc_feature`. Once those conditions are met, the arguments in [`cc_feature.args`](#cc_feature-args)
|
||||||
|
are expanded and added to the command-line.
|
||||||
|
|
||||||
A feature may be enabled or disabled through the following mechanisms:
|
A feature may be enabled or disabled through the following mechanisms:
|
||||||
* Via command-line flags, or a `.bazelrc`.
|
* Via command-line flags, or a `.bazelrc` file via the
|
||||||
* Through inter-feature relationships (enabling one feature may implicitly
|
[`--features` flag](https://bazel.build/reference/command-line-reference#flag--features)
|
||||||
enable another).
|
* Through inter-feature relationships (via [`cc_feature.implies`](#cc_feature-implies)) where one
|
||||||
* Individual rules may elect to manually enable or disable features through the
|
feature may implicitly enable another.
|
||||||
builtin `features` attribute.
|
* Individual rules (e.g. `cc_library`) or `package` definitions may elect to manually enable or
|
||||||
|
disable features through the
|
||||||
|
[`features` attribute](https://bazel.build/reference/be/common-definitions#common.features).
|
||||||
|
|
||||||
Because of the toggleable nature of toolchain features, it's generally best to
|
Note that a feature may alternate between enabled and disabled dynamically over the course of a
|
||||||
avoid defining features as part of your toolchain with the following exceptions:
|
build. Because of their toggleable nature, it's generally best to avoid adding arguments to a
|
||||||
* You want build files to be able to configure compiler flags. For example, a
|
`cc_toolchain` as a `cc_feature` unless strictly necessary. Instead, prefer to express arguments
|
||||||
|
via [`cc_toolchain.args`](#cc_toolchain-args) whenever possible.
|
||||||
|
|
||||||
|
You should use a `cc_feature` when any of the following apply:
|
||||||
|
* You need the flags to be dynamically toggled over the course of a build.
|
||||||
|
* You want build files to be able to configure the flags in question. For example, a
|
||||||
binary might specify `features = ["optimize_for_size"]` to create a small
|
binary might specify `features = ["optimize_for_size"]` to create a small
|
||||||
binary instead of optimizing for performance.
|
binary instead of optimizing for performance.
|
||||||
* You need to carry forward Starlark toolchain behaviors. If you're migrating a
|
* You need to carry forward Starlark toolchain behaviors. If you're migrating a
|
||||||
complex Starlark-based toolchain definition to these rules, many of the
|
complex Starlark-based toolchain definition to these rules, many of the
|
||||||
workflows and flags were likely based on features. This rule exists to support
|
workflows and flags were likely based on features.
|
||||||
those existing structures.
|
|
||||||
|
|
||||||
If you want to be able to configure flags via the bazel command-line, instead
|
If you only need to configure flags via the Bazel command-line, instead
|
||||||
consider making a bool_flag, and then making your `cc_args` `select` on those
|
consider adding a
|
||||||
flags.
|
[`bool_flag`](https://github.com/bazelbuild/bazel-skylib/tree/main/doc/common_settings_doc.md#bool_flag)
|
||||||
|
paired with a [`config_setting`](https://bazel.build/reference/be/general#config_setting)
|
||||||
|
and then make your `cc_args` rule `select` on the `config_setting`.
|
||||||
|
|
||||||
For more details about how Bazel handles features, see the official Bazel
|
For more details about how Bazel handles features, see the official Bazel
|
||||||
documentation at
|
documentation at
|
||||||
https://bazel.build/docs/cc-toolchain-config-reference#features.
|
https://bazel.build/docs/cc-toolchain-config-reference#features.
|
||||||
|
|
||||||
Examples:
|
Example:
|
||||||
|
```
|
||||||
|
load("//cc/toolchains:feature.bzl", "cc_feature")
|
||||||
|
|
||||||
# A feature that can be easily toggled to optimize for size
|
# A feature that enables LTO, which may be incompatible when doing interop with various
|
||||||
cc_feature(
|
# languages (e.g. rust, go), or may need to be disabled for particular `cc_binary` rules
|
||||||
name = "optimize_for_size",
|
# for various reasons.
|
||||||
feature_name = "optimize_for_size",
|
cc_feature(
|
||||||
args = [":optimize_for_size_args"],
|
name = "lto",
|
||||||
)
|
feature_name = "lto",
|
||||||
|
args = [":lto_args"],
|
||||||
# This feature signals a capability, and doesn't have associated flags.
|
)
|
||||||
#
|
```
|
||||||
# For a list of well-known features, see:
|
|
||||||
# https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features
|
|
||||||
cc_feature(
|
|
||||||
name = "supports_pic",
|
|
||||||
overrides = "//cc/toolchains/features:supports_pic
|
|
||||||
)
|
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
|
@ -47,8 +47,26 @@ cc_feature_constraint = rule(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
provides = [FeatureConstraintInfo],
|
provides = [FeatureConstraintInfo],
|
||||||
doc = """Defines a constraint on features.
|
doc = """Defines a compound relationship between features.
|
||||||
|
|
||||||
Can be used with require_any_of to specify that something is only enabled when
|
This rule can be used with [`cc_args.require_any_of`](#cc_args-require_any_of) to specify that a set
|
||||||
a constraint is met.""",
|
of arguments are only enabled when a constraint is met. Both `all_of` and `none_of` must be
|
||||||
|
satisfied simultaneously.
|
||||||
|
|
||||||
|
This is basically a `cc_feature_set` that supports `none_of` expressions. This extra flexibility
|
||||||
|
is why this rule may only be used by [`cc_args.require_any_of`](#cc_args-require_any_of).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("//cc/toolchains:feature_constraint.bzl", "cc_feature_constraint")
|
||||||
|
|
||||||
|
# A constraint that requires a `linker_supports_thinlto` feature to be enabled,
|
||||||
|
# AND a `no_optimization` to be disabled.
|
||||||
|
cc_feature_constraint(
|
||||||
|
name = "thinlto_constraint",
|
||||||
|
all_of = [":linker_supports_thinlto"],
|
||||||
|
none_of = [":no_optimization"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
""",
|
||||||
)
|
)
|
||||||
|
|
|
@ -44,14 +44,20 @@ cc_feature_set = rule(
|
||||||
provides = [FeatureSetInfo],
|
provides = [FeatureSetInfo],
|
||||||
doc = """Defines a set of features.
|
doc = """Defines a set of features.
|
||||||
|
|
||||||
Example:
|
This may be used by both `cc_feature` and `cc_args` rules, and is effectively a way to express
|
||||||
|
a logical `AND` operation across multiple requred features.
|
||||||
|
|
||||||
cc_feature_set(
|
Example:
|
||||||
name = "thin_lto_requirements",
|
```
|
||||||
all_of = [
|
load("//cc/toolchains:feature_set.bzl", "cc_feature_set")
|
||||||
":thin_lto",
|
|
||||||
":opt",
|
cc_feature_set(
|
||||||
],
|
name = "thin_lto_requirements",
|
||||||
)
|
all_of = [
|
||||||
|
":thin_lto",
|
||||||
|
":opt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
```
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,9 +16,14 @@
|
||||||
load("//cc/toolchains:actions.bzl", _cc_action_type = "cc_action_type", _cc_action_type_set = "cc_action_type_set")
|
load("//cc/toolchains:actions.bzl", _cc_action_type = "cc_action_type", _cc_action_type_set = "cc_action_type_set")
|
||||||
load("//cc/toolchains:args.bzl", _cc_args = "cc_args")
|
load("//cc/toolchains:args.bzl", _cc_args = "cc_args")
|
||||||
load("//cc/toolchains:args_list.bzl", _cc_args_list = "cc_args_list")
|
load("//cc/toolchains:args_list.bzl", _cc_args_list = "cc_args_list")
|
||||||
|
load("//cc/toolchains:feature.bzl", _cc_feature = "cc_feature")
|
||||||
|
load("//cc/toolchains:feature_constraint.bzl", _cc_feature_constraint = "cc_feature_constraint")
|
||||||
|
load("//cc/toolchains:feature_set.bzl", _cc_feature_set = "cc_feature_set")
|
||||||
|
load("//cc/toolchains:mutually_exclusive_category.bzl", _cc_mutually_exclusive_category = "cc_mutually_exclusive_category")
|
||||||
load("//cc/toolchains:nested_args.bzl", _cc_nested_args = "cc_nested_args")
|
load("//cc/toolchains:nested_args.bzl", _cc_nested_args = "cc_nested_args")
|
||||||
load("//cc/toolchains:tool.bzl", _cc_tool = "cc_tool")
|
load("//cc/toolchains:tool.bzl", _cc_tool = "cc_tool")
|
||||||
load("//cc/toolchains:tool_map.bzl", _cc_tool_map = "cc_tool_map")
|
load("//cc/toolchains:tool_map.bzl", _cc_tool_map = "cc_tool_map")
|
||||||
|
load("//cc/toolchains/impl:external_feature.bzl", _cc_external_feature = "cc_external_feature")
|
||||||
load("//cc/toolchains/impl:variables.bzl", _cc_variable = "cc_variable")
|
load("//cc/toolchains/impl:variables.bzl", _cc_variable = "cc_variable")
|
||||||
|
|
||||||
cc_tool_map = _cc_tool_map
|
cc_tool_map = _cc_tool_map
|
||||||
|
@ -29,6 +34,11 @@ cc_args_list = _cc_args_list
|
||||||
cc_action_type = _cc_action_type
|
cc_action_type = _cc_action_type
|
||||||
cc_action_type_set = _cc_action_type_set
|
cc_action_type_set = _cc_action_type_set
|
||||||
cc_variable = _cc_variable
|
cc_variable = _cc_variable
|
||||||
|
cc_feature = _cc_feature
|
||||||
|
cc_feature_constraint = _cc_feature_constraint
|
||||||
|
cc_feature_set = _cc_feature_set
|
||||||
|
cc_mutually_exclusive_category = _cc_mutually_exclusive_category
|
||||||
|
cc_external_feature = _cc_external_feature
|
||||||
|
|
||||||
# This list is used to automatically remap instances of `foo` to [`foo`](#foo)
|
# This list is used to automatically remap instances of `foo` to [`foo`](#foo)
|
||||||
# links in the generated documentation so that maintainers don't need to manually
|
# links in the generated documentation so that maintainers don't need to manually
|
||||||
|
@ -42,4 +52,9 @@ DOCUMENTED_TOOLCHAIN_RULES = [
|
||||||
"cc_action_type",
|
"cc_action_type",
|
||||||
"cc_action_type_set",
|
"cc_action_type_set",
|
||||||
"cc_variable",
|
"cc_variable",
|
||||||
|
"cc_feature",
|
||||||
|
"cc_feature_constraint",
|
||||||
|
"cc_feature_set",
|
||||||
|
"cc_mutually_exclusive_category",
|
||||||
|
"cc_external_feature",
|
||||||
]
|
]
|
||||||
|
|
|
@ -69,5 +69,26 @@ cc_external_feature = rule(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
provides = [FeatureInfo, FeatureSetInfo, FeatureConstraintInfo],
|
provides = [FeatureInfo, FeatureSetInfo, FeatureConstraintInfo],
|
||||||
doc = "A declaration that a feature with this name is defined elsewhere.",
|
doc = """A declaration that a [feature](https://bazel.build/docs/cc-toolchain-config-reference#features) with this name is defined elsewhere.
|
||||||
|
|
||||||
|
This rule communicates that a feature has been defined externally to make it possible to reference
|
||||||
|
features that live outside the rule-based cc toolchain ecosystem. This allows various toolchain
|
||||||
|
rules to reference the external feature without accidentally re-defining said feature.
|
||||||
|
|
||||||
|
This rule is currently considered a private API of the toolchain rules to encourage the Bazel
|
||||||
|
ecosystem to migrate to properly defining their features as rules.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("//cc/toolchains:external_feature.bzl", "cc_external_feature")
|
||||||
|
|
||||||
|
# rules_rust defines a feature that is disabled whenever rust artifacts are being linked using
|
||||||
|
# the cc toolchain to signal that incompatible flags should be disabled as well.
|
||||||
|
cc_external_feature(
|
||||||
|
name = "rules_rust_unsupported_feature",
|
||||||
|
feature_name = "rules_rust_unsupported_feature",
|
||||||
|
overridable = False,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
""",
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,7 +23,40 @@ def _cc_mutually_exclusive_category_impl(ctx):
|
||||||
|
|
||||||
cc_mutually_exclusive_category = rule(
|
cc_mutually_exclusive_category = rule(
|
||||||
implementation = _cc_mutually_exclusive_category_impl,
|
implementation = _cc_mutually_exclusive_category_impl,
|
||||||
doc = "A category of features, for which only one can be enabled",
|
doc = """A rule used to categorize `cc_feature` definitions for which only one can be enabled.
|
||||||
|
|
||||||
|
This is used by [`cc_feature.mutually_exclusive`](#cc_feature-mutually_exclusive) to express groups
|
||||||
|
of `cc_feature` definitions that are inherently incompatible with each other and must be treated as
|
||||||
|
mutually exclusive.
|
||||||
|
|
||||||
|
Warning: These groups are keyed by name, so two `cc_mutually_exclusive_category` definitions of the
|
||||||
|
same name in different packages will resolve to the same logical group.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("//cc/toolchains:feature.bzl", "cc_feature")
|
||||||
|
load("//cc/toolchains:mutually_exclusive_category.bzl", "cc_mutually_exclusive_category")
|
||||||
|
|
||||||
|
cc_mutually_exclusive_category(
|
||||||
|
name = "opt_level",
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_feature(
|
||||||
|
name = "speed_optimized",
|
||||||
|
mutually_exclusive = [":opt_level"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_feature(
|
||||||
|
name = "size_optimized",
|
||||||
|
mutually_exclusive = [":opt_level"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_feature(
|
||||||
|
name = "unoptimized",
|
||||||
|
mutually_exclusive = [":opt_level"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
""",
|
||||||
attrs = {},
|
attrs = {},
|
||||||
provides = [MutuallyExclusiveCategoryInfo],
|
provides = [MutuallyExclusiveCategoryInfo],
|
||||||
)
|
)
|
||||||
|
|
|
@ -134,6 +134,247 @@ cc_args_list(
|
||||||
| <a id="cc_args_list-args"></a>args | (ordered) cc_args to include in this list. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
| <a id="cc_args_list-args"></a>args | (ordered) cc_args to include in this list. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
|
||||||
|
|
||||||
|
<a id="cc_external_feature"></a>
|
||||||
|
|
||||||
|
## cc_external_feature
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cc_external_feature(<a href="#cc_external_feature-name">name</a>, <a href="#cc_external_feature-feature_name">feature_name</a>, <a href="#cc_external_feature-overridable">overridable</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
A declaration that a [feature](https://bazel.build/docs/cc-toolchain-config-reference#features) with this name is defined elsewhere.
|
||||||
|
|
||||||
|
This rule communicates that a feature has been defined externally to make it possible to reference
|
||||||
|
features that live outside the rule-based cc toolchain ecosystem. This allows various toolchain
|
||||||
|
rules to reference the external feature without accidentally re-defining said feature.
|
||||||
|
|
||||||
|
This rule is currently considered a private API of the toolchain rules to encourage the Bazel
|
||||||
|
ecosystem to migrate to properly defining their features as rules.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("@rules_cc//cc/toolchains:external_feature.bzl", "cc_external_feature")
|
||||||
|
|
||||||
|
# rules_rust defines a feature that is disabled whenever rust artifacts are being linked using
|
||||||
|
# the cc toolchain to signal that incompatible flags should be disabled as well.
|
||||||
|
cc_external_feature(
|
||||||
|
name = "rules_rust_unsupported_feature",
|
||||||
|
feature_name = "rules_rust_unsupported_feature",
|
||||||
|
overridable = False,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**ATTRIBUTES**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Type | Mandatory | Default |
|
||||||
|
| :------------- | :------------- | :------------- | :------------- | :------------- |
|
||||||
|
| <a id="cc_external_feature-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
|
||||||
|
| <a id="cc_external_feature-feature_name"></a>feature_name | The name of the feature | String | required | |
|
||||||
|
| <a id="cc_external_feature-overridable"></a>overridable | Whether the feature can be overridden | Boolean | required | |
|
||||||
|
|
||||||
|
|
||||||
|
<a id="cc_feature"></a>
|
||||||
|
|
||||||
|
## cc_feature
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cc_feature(<a href="#cc_feature-name">name</a>, <a href="#cc_feature-args">args</a>, <a href="#cc_feature-feature_name">feature_name</a>, <a href="#cc_feature-implies">implies</a>, <a href="#cc_feature-mutually_exclusive">mutually_exclusive</a>, <a href="#cc_feature-overrides">overrides</a>, <a href="#cc_feature-requires_any_of">requires_any_of</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
A dynamic set of toolchain flags that create a singular [feature](https://bazel.build/docs/cc-toolchain-config-reference#features) definition.
|
||||||
|
|
||||||
|
A feature is basically a dynamically toggleable [`cc_args_list`](#cc_args_list). There are a variety of
|
||||||
|
dependencies and compatibility requirements that must be satisfied to enable a
|
||||||
|
[`cc_feature`](#cc_feature). Once those conditions are met, the arguments in [`cc_feature.args`](#cc_feature-args)
|
||||||
|
are expanded and added to the command-line.
|
||||||
|
|
||||||
|
A feature may be enabled or disabled through the following mechanisms:
|
||||||
|
* Via command-line flags, or a `.bazelrc` file via the
|
||||||
|
[`--features` flag](https://bazel.build/reference/command-line-reference#flag--features)
|
||||||
|
* Through inter-feature relationships (via [`cc_feature.implies`](#cc_feature-implies)) where one
|
||||||
|
feature may implicitly enable another.
|
||||||
|
* Individual rules (e.g. `cc_library`) or `package` definitions may elect to manually enable or
|
||||||
|
disable features through the
|
||||||
|
[`features` attribute](https://bazel.build/reference/be/common-definitions#common.features).
|
||||||
|
|
||||||
|
Note that a feature may alternate between enabled and disabled dynamically over the course of a
|
||||||
|
build. Because of their toggleable nature, it's generally best to avoid adding arguments to a
|
||||||
|
`cc_toolchain` as a [`cc_feature`](#cc_feature) unless strictly necessary. Instead, prefer to express arguments
|
||||||
|
via [`cc_toolchain.args`](#cc_toolchain-args) whenever possible.
|
||||||
|
|
||||||
|
You should use a [`cc_feature`](#cc_feature) when any of the following apply:
|
||||||
|
* You need the flags to be dynamically toggled over the course of a build.
|
||||||
|
* You want build files to be able to configure the flags in question. For example, a
|
||||||
|
binary might specify `features = ["optimize_for_size"]` to create a small
|
||||||
|
binary instead of optimizing for performance.
|
||||||
|
* You need to carry forward Starlark toolchain behaviors. If you're migrating a
|
||||||
|
complex Starlark-based toolchain definition to these rules, many of the
|
||||||
|
workflows and flags were likely based on features.
|
||||||
|
|
||||||
|
If you only need to configure flags via the Bazel command-line, instead
|
||||||
|
consider adding a
|
||||||
|
[`bool_flag`](https://github.com/bazelbuild/bazel-skylib/tree/main/doc/common_settings_doc.md#bool_flag)
|
||||||
|
paired with a [`config_setting`](https://bazel.build/reference/be/general#config_setting)
|
||||||
|
and then make your [`cc_args`](#cc_args) rule `select` on the `config_setting`.
|
||||||
|
|
||||||
|
For more details about how Bazel handles features, see the official Bazel
|
||||||
|
documentation at
|
||||||
|
https://bazel.build/docs/cc-toolchain-config-reference#features.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature")
|
||||||
|
|
||||||
|
# A feature that enables LTO, which may be incompatible when doing interop with various
|
||||||
|
# languages (e.g. rust, go), or may need to be disabled for particular `cc_binary` rules
|
||||||
|
# for various reasons.
|
||||||
|
cc_feature(
|
||||||
|
name = "lto",
|
||||||
|
feature_name = "lto",
|
||||||
|
args = [":lto_args"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**ATTRIBUTES**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Type | Mandatory | Default |
|
||||||
|
| :------------- | :------------- | :------------- | :------------- | :------------- |
|
||||||
|
| <a id="cc_feature-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
|
||||||
|
| <a id="cc_feature-args"></a>args | A list of [`cc_args`](#cc_args) or [`cc_args_list`](#cc_args_list) labels that are expanded when this feature is enabled. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
| <a id="cc_feature-feature_name"></a>feature_name | The name of the feature that this rule implements.<br><br>The feature name is a string that will be used in the `features` attribute of rules to enable them (eg. `cc_binary(..., features = ["opt"])`.<br><br>While two features with the same `feature_name` may not be bound to the same toolchain, they can happily live alongside each other in the same BUILD file.<br><br>Example: <pre><code>cc_feature( name = "sysroot_macos", feature_name = "sysroot", ... ) cc_feature( name = "sysroot_linux", feature_name = "sysroot", ... )</code></pre> | String | optional | `""` |
|
||||||
|
| <a id="cc_feature-implies"></a>implies | List of features enabled along with this feature.<br><br>Warning: If any of the features cannot be enabled, this feature is silently disabled. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
| <a id="cc_feature-mutually_exclusive"></a>mutually_exclusive | A list of things that this feature is mutually exclusive with.<br><br>It can be either: * A feature, in which case the two features are mutually exclusive. * A [`cc_mutually_exclusive_category`](#cc_mutually_exclusive_category), in which case all features that write `mutually_exclusive = [":category"]` are mutually exclusive with each other.<br><br>If this feature has a side-effect of implementing another feature, it can be useful to list that feature here to ensure they aren't enabled at the same time. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
| <a id="cc_feature-overrides"></a>overrides | A declaration that this feature overrides a known feature.<br><br>In the example below, if you missed the "overrides" attribute, it would complain that the feature "opt" was defined twice.<br><br>Example: <pre><code>load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature") cc_feature( name = "opt", feature_name = "opt", args = [":size_optimized"], overrides = "@rules_cc//cc/toolchains/features:opt", )</code></pre> | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
|
||||||
|
| <a id="cc_feature-requires_any_of"></a>requires_any_of | A list of feature sets that define toolchain compatibility.<br><br>If *at least one* of the listed [`cc_feature_set`](#cc_feature_set)s are fully satisfied (all features exist in the toolchain AND are currently enabled), this feature is deemed compatible and may be enabled.<br><br>Note: Even if `cc_feature.requires_any_of` is satisfied, a feature is not enabled unless another mechanism (e.g. command-line flags, `cc_feature.implies`, `cc_toolchain_config.enabled_features`) signals that the feature should actually be enabled. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
|
||||||
|
|
||||||
|
<a id="cc_feature_constraint"></a>
|
||||||
|
|
||||||
|
## cc_feature_constraint
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cc_feature_constraint(<a href="#cc_feature_constraint-name">name</a>, <a href="#cc_feature_constraint-all_of">all_of</a>, <a href="#cc_feature_constraint-none_of">none_of</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Defines a compound relationship between features.
|
||||||
|
|
||||||
|
This rule can be used with [`cc_args.require_any_of`](#cc_args-require_any_of) to specify that a set
|
||||||
|
of arguments are only enabled when a constraint is met. Both `all_of` and `none_of` must be
|
||||||
|
satisfied simultaneously.
|
||||||
|
|
||||||
|
This is basically a [`cc_feature_set`](#cc_feature_set) that supports `none_of` expressions. This extra flexibility
|
||||||
|
is why this rule may only be used by [`cc_args.require_any_of`](#cc_args-require_any_of).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("@rules_cc//cc/toolchains:feature_constraint.bzl", "cc_feature_constraint")
|
||||||
|
|
||||||
|
# A constraint that requires a `linker_supports_thinlto` feature to be enabled,
|
||||||
|
# AND a `no_optimization` to be disabled.
|
||||||
|
cc_feature_constraint(
|
||||||
|
name = "thinlto_constraint",
|
||||||
|
all_of = [":linker_supports_thinlto"],
|
||||||
|
none_of = [":no_optimization"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**ATTRIBUTES**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Type | Mandatory | Default |
|
||||||
|
| :------------- | :------------- | :------------- | :------------- | :------------- |
|
||||||
|
| <a id="cc_feature_constraint-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
|
||||||
|
| <a id="cc_feature_constraint-all_of"></a>all_of | - | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
| <a id="cc_feature_constraint-none_of"></a>none_of | - | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
|
||||||
|
|
||||||
|
<a id="cc_feature_set"></a>
|
||||||
|
|
||||||
|
## cc_feature_set
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cc_feature_set(<a href="#cc_feature_set-name">name</a>, <a href="#cc_feature_set-all_of">all_of</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Defines a set of features.
|
||||||
|
|
||||||
|
This may be used by both [`cc_feature`](#cc_feature) and [`cc_args`](#cc_args) rules, and is effectively a way to express
|
||||||
|
a logical `AND` operation across multiple requred features.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("@rules_cc//cc/toolchains:feature_set.bzl", "cc_feature_set")
|
||||||
|
|
||||||
|
cc_feature_set(
|
||||||
|
name = "thin_lto_requirements",
|
||||||
|
all_of = [
|
||||||
|
":thin_lto",
|
||||||
|
":opt",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**ATTRIBUTES**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Type | Mandatory | Default |
|
||||||
|
| :------------- | :------------- | :------------- | :------------- | :------------- |
|
||||||
|
| <a id="cc_feature_set-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
|
||||||
|
| <a id="cc_feature_set-all_of"></a>all_of | A set of features | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
|
||||||
|
|
||||||
|
|
||||||
|
<a id="cc_mutually_exclusive_category"></a>
|
||||||
|
|
||||||
|
## cc_mutually_exclusive_category
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
cc_mutually_exclusive_category(<a href="#cc_mutually_exclusive_category-name">name</a>)
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
A rule used to categorize [`cc_feature`](#cc_feature) definitions for which only one can be enabled.
|
||||||
|
|
||||||
|
This is used by [`cc_feature.mutually_exclusive`](#cc_feature-mutually_exclusive) to express groups
|
||||||
|
of [`cc_feature`](#cc_feature) definitions that are inherently incompatible with each other and must be treated as
|
||||||
|
mutually exclusive.
|
||||||
|
|
||||||
|
Warning: These groups are keyed by name, so two [`cc_mutually_exclusive_category`](#cc_mutually_exclusive_category) definitions of the
|
||||||
|
same name in different packages will resolve to the same logical group.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature")
|
||||||
|
load("@rules_cc//cc/toolchains:mutually_exclusive_category.bzl", "cc_mutually_exclusive_category")
|
||||||
|
|
||||||
|
cc_mutually_exclusive_category(
|
||||||
|
name = "opt_level",
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_feature(
|
||||||
|
name = "speed_optimized",
|
||||||
|
mutually_exclusive = [":opt_level"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_feature(
|
||||||
|
name = "size_optimized",
|
||||||
|
mutually_exclusive = [":opt_level"],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_feature(
|
||||||
|
name = "unoptimized",
|
||||||
|
mutually_exclusive = [":opt_level"],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**ATTRIBUTES**
|
||||||
|
|
||||||
|
|
||||||
|
| Name | Description | Type | Mandatory | Default |
|
||||||
|
| :------------- | :------------- | :------------- | :------------- | :------------- |
|
||||||
|
| <a id="cc_mutually_exclusive_category-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
|
||||||
|
|
||||||
|
|
||||||
<a id="cc_tool"></a>
|
<a id="cc_tool"></a>
|
||||||
|
|
||||||
## cc_tool
|
## cc_tool
|
||||||
|
@ -195,7 +436,7 @@ argument expressed in a toolchain tool invocation (e.g. `gcc`, `llvm-ar`) is dec
|
||||||
[`cc_args`](#cc_args) rule that applies an ordered list of arguments to a set of toolchain
|
[`cc_args`](#cc_args) rule that applies an ordered list of arguments to a set of toolchain
|
||||||
actions. [`cc_args`](#cc_args) rules can be added unconditionally to a
|
actions. [`cc_args`](#cc_args) rules can be added unconditionally to a
|
||||||
`cc_toolchain`, conditionally via `select()` statements, or dynamically via an
|
`cc_toolchain`, conditionally via `select()` statements, or dynamically via an
|
||||||
intermediate `cc_feature`.
|
intermediate [`cc_feature`](#cc_feature).
|
||||||
|
|
||||||
Conceptually, this is similar to the old `CFLAGS`, `CPPFLAGS`, etc. environment variables that
|
Conceptually, this is similar to the old `CFLAGS`, `CPPFLAGS`, etc. environment variables that
|
||||||
many build systems use to determine which flags to use for a given action. The significant
|
many build systems use to determine which flags to use for a given action. The significant
|
||||||
|
|
Loading…
Reference in New Issue