rules_cc/docs/toolchain_api.md

39 KiB

This is a list of rules/macros that should be exported as documentation.

cc_action_type

cc_action_type(name, action_name)

A type of action (eg. c_compile, assemble, strip).

cc_action_type rules are used to associate arguments and tools together to perform a specific action. Bazel prescribes a set of known action types that are used to drive typical C/C++/ObjC actions like compiling, linking, and archiving. The set of well-known action types can be found in @rules_cc//cc/toolchains/actions:BUILD.

It's possible to create project-specific action types for use in toolchains. Be careful when doing this, because every toolchain that encounters the action will need to be configured to support the custom action type. If your project is a library, avoid creating new action types as it will reduce compatibility with existing toolchains and increase setup complexity for users.

Example:

load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
load("@rules_cc//cc/toolchains:actions.bzl", "cc_action_type")

cc_action_type(
    name = "cpp_compile",
    action_name =  = ACTION_NAMES.cpp_compile,
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
action_name - String required

cc_action_type_set

cc_action_type_set(name, actions, allow_empty)

Represents a set of actions.

This is a convenience rule to allow for more compact representation of a group of action types. Use this anywhere a cc_action_type is accepted.

Example:

load("@rules_cc//cc/toolchains:actions.bzl", "cc_action_type_set")

cc_action_type_set(
    name = "link_executable_actions",
    actions = [
        "@rules_cc//cc/toolchains/actions:cpp_link_executable",
        "@rules_cc//cc/toolchains/actions:lto_index_for_executable",
    ],
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
actions A list of cc_action_type or cc_action_type_set List of labels required
allow_empty - Boolean optional False

cc_args_list

cc_args_list(name, args)

An ordered list of cc_args.

This is a convenience rule to allow you to group a set of multiple cc_args into a single list. This particularly useful for toolchain behaviors that require different flags for different actions.

Note: The order of the arguments in args is preserved to support order-sensitive flags.

Example usage:

load("@rules_cc//cc/toolchains:cc_args.bzl", "cc_args")
load("@rules_cc//cc/toolchains:args_list.bzl", "cc_args_list")

cc_args(
    name = "gc_sections",
    actions = [
        "@rules_cc//cc/toolchains/actions:link_actions",
    ],
    args = ["-Wl,--gc-sections"],
)

cc_args(
    name = "function_sections",
    actions = [
        "@rules_cc//cc/toolchains/actions:compile_actions",
        "@rules_cc//cc/toolchains/actions:link_actions",
    ],
    args = ["-ffunction-sections"],
)

cc_args_list(
    name = "gc_functions",
    args = [
        ":function_sections",
        ":gc_sections",
    ],
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
args (ordered) cc_args to include in this list. List of labels optional []

cc_external_feature

cc_external_feature(name, feature_name, overridable)

A declaration that a feature 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
name A unique name for this target. Name required
feature_name The name of the feature String required
overridable Whether the feature can be overridden Boolean required

cc_feature

cc_feature(name, args, feature_name, implies, mutually_exclusive, overrides, requires_any_of)

A dynamic set of toolchain flags that create a singular feature definition.

A feature is basically a dynamically toggleable cc_args_list. There are a variety of dependencies and compatibility requirements that must be satisfied to enable a cc_feature. Once those conditions are met, the arguments in 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
  • Through inter-feature relationships (via 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.

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 unless strictly necessary. Instead, prefer to express arguments via 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 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 paired with a 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 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
name A unique name for this target. Name required
args A list of cc_args or cc_args_list labels that are expanded when this feature is enabled. List of labels optional []
feature_name The name of the feature that this rule implements.

The feature name is a string that will be used in the features attribute of rules to enable them (eg. cc_binary(..., features = ["opt"]).

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.

Example:
cc_feature(
    name = "sysroot_macos",
    feature_name = "sysroot",
    ...
)

cc_feature(
    name = "sysroot_linux",
    feature_name = "sysroot",
    ...
)
String optional ""
implies List of features enabled along with this feature.

Warning: If any of the features cannot be enabled, this feature is silently disabled.
List of labels optional []
mutually_exclusive A list of things that this feature is mutually exclusive with.

It can be either: * A feature, in which case the two features are mutually exclusive. * A cc_mutually_exclusive_category, in which case all features that write mutually_exclusive = [":category"] are mutually exclusive with each other.

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.
List of labels optional []
overrides A declaration that this feature overrides a known feature.

In the example below, if you missed the "overrides" attribute, it would complain that the feature "opt" was defined twice.

Example:
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",
)
Label optional None
requires_any_of A list of feature sets that define toolchain compatibility.

If at least one of the listed cc_feature_sets are fully satisfied (all features exist in the toolchain AND are currently enabled), this feature is deemed compatible and may be enabled.

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.
List of labels optional []

cc_feature_constraint

cc_feature_constraint(name, all_of, none_of)

Defines a compound relationship between features.

This rule can be used with 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 that supports none_of expressions. This extra flexibility is why this rule may only be used by 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
name A unique name for this target. Name required
all_of - List of labels optional []
none_of - List of labels optional []

cc_feature_set

cc_feature_set(name, all_of)

Defines a set of features.

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.

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
name A unique name for this target. Name required
all_of A set of features List of labels optional []

cc_mutually_exclusive_category

cc_mutually_exclusive_category(name)

A rule used to categorize cc_feature definitions for which only one can be enabled.

This is used by 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("@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
name A unique name for this target. Name required

cc_tool

cc_tool(name, src, data, allowlist_include_directories, capabilities)

Declares a tool for use by toolchain actions.

cc_tool rules are used in a cc_tool_map rule to ensure all files and metadata required to run a tool are available when constructing a cc_toolchain.

In general, include all files that are always required to run a tool (e.g. libexec/** and cross-referenced tools in bin/*) in the data attribute. If some files are only required when certain flags are passed to the tool, consider using a cc_args rule to bind the files to the flags that require them. This reduces the overhead required to properly enumerate a sandbox with all the files required to run a tool, and ensures that there isn't unintentional leakage across configurations and actions.

Example:

load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool")

cc_tool(
    name = "clang_tool",
    executable = "@llvm_toolchain//:bin/clang",
    # Suppose clang needs libc to run.
    data = ["@llvm_toolchain//:lib/x86_64-linux-gnu/libc.so.6"]
    tags = ["requires-network"],
    capabilities = ["@rules_cc//cc/toolchains/capabilities:supports_pic"],
)

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
src The underlying binary that this tool represents.

Usually just a single prebuilt (eg. @toolchain//:bin/clang), but may be any executable label.
Label optional None
data Additional files that are required for this tool to run.

Frequently, clang and gcc require additional files to execute as they often shell out to other binaries (e.g. cc1).
List of labels optional []
allowlist_include_directories Include paths implied by using this tool.

Compilers may include a set of built-in headers that are implicitly available unless flags like -nostdinc are provided. Bazel checks that all included headers are properly provided by a dependency or allowlisted through this mechanism.

As a rule of thumb, only use this if Bazel is complaining about absolute paths in your toolchain and you've ensured that the toolchain is compiling with the -no-canonical-prefixes and/or -fno-canonical-system-headers arguments.

This can help work around errors like: the source file 'main.c' includes the following non-builtin files with absolute paths (if these are builtin files, make sure these paths are in your toolchain).
List of labels optional []
capabilities Declares that a tool is capable of doing something.

For example, @rules_cc//cc/toolchains/capabilities:supports_pic.
List of labels optional []

cc_tool_capability

cc_tool_capability(name, feature_name)

A capability is an optional feature that a tool supports.

For example, not all compilers support PIC, so to handle this, we write:

cc_tool(
    name = "clang",
    src = "@host_tools/bin/clang",
    capabilities = [
        "@rules_cc//cc/toolchains/capabilities:supports_pic",
    ],
)

cc_args(
    name = "pic",
    requires = [
        "@rules_cc//cc/toolchains/capabilities:supports_pic"
    ],
    args = ["-fPIC"],
)

This ensures that -fPIC is added to the command-line only when we are using a tool that supports PIC.

ATTRIBUTES

Name Description Type Mandatory Default
name A unique name for this target. Name required
feature_name The name of the feature to generate for this capability String optional ""

cc_args

cc_args(name, actions, allowlist_include_directories, args, data, env, format, iterate_over, nested,
        requires_not_none, requires_none, requires_true, requires_false, requires_equal,
        requires_equal_value, requires_any_of, kwargs)

Action-specific arguments for use with a cc_toolchain.

This rule is the fundamental building building block for every toolchain tool invocation. Each argument expressed in a toolchain tool invocation (e.g. gcc, llvm-ar) is declared in a cc_args rule that applies an ordered list of arguments to a set of toolchain actions. cc_args rules can be added unconditionally to a cc_toolchain, conditionally via select() statements, or dynamically via an intermediate cc_feature.

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 difference is that cc_args rules are declared in a structured way that allows for significantly more powerful and sharable toolchain configurations. Also, due to Bazel's more granular action types, it's possible to bind flags to very specific actions (e.g. LTO indexing for an executable vs a dynamic library) multiple different actions (e.g. C++ compile and link simultaneously).

Example usage:

load("@rules_cc//cc/toolchains:args.bzl", "cc_args")

# Basic usage: a trivial flag.
#
# An example of expressing `-Werror` as a [`cc_args`](#cc_args) rule.
cc_args(
    name = "warnings_as_errors",
    actions = [
        # Applies to all C/C++ compile actions.
        "@rules_cc//cc/toolchains/actions:compile_actions",
    ],
    args = ["-Werror"],
)

# Basic usage: ordered flags.
#
# An example of linking against libc++, which uses two flags that must be applied in order.
cc_args(
    name = "link_libcxx",
    actions = [
        # Applies to all link actions.
        "@rules_cc//cc/toolchains/actions:link_actions",
    ],
    # On tool invocation, this appears as `-Xlinker -lc++`. Nothing will ever end up between
    # the two flags.
    args = [
        "-Xlinker",
        "-lc++",
    ],
)

# Advanced usage: built-in variable expansions.
#
# Expands to `-L/path/to/search_dir` for each directory in the built-in variable
# `library_search_directories`. This variable is managed internally by Bazel through inherent
# behaviors of Bazel and the interactions between various C/C++ build rules.
cc_args(
    name = "library_search_directories",
    actions = [
        "@rules_cc//cc/toolchains/actions:link_actions",
    ],
    args = ["-L{search_dir}"],
    iterate_over = "@rules_cc//cc/toolchains/variables:library_search_directories",
    requires_not_none = "@rules_cc//cc/toolchains/variables:library_search_directories",
    format = {
        "search_dir": "@rules_cc//cc/toolchains/variables:library_search_directories",
    },
)

For more extensive examples, see the usages here: https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/args

PARAMETERS

Name Description Default Value
name (str) The name of the target. none
actions (List[Label]) A list of labels of cc_action_type or cc_action_type_set rules that dictate which actions these arguments should be applied to. None
allowlist_include_directories (List[Label]) A list of include paths that are implied by using this rule. These must point to a skylib directory or subdirectory rule. Some flags (e.g. --sysroot) imply certain include paths are available despite not explicitly specifying a normal include path flag (-I, -isystem, etc.). Bazel checks that all included headers are properly provided by a dependency or allowlisted through this mechanism.

As a rule of thumb, only use this if Bazel is complaining about absolute paths in your toolchain and you've ensured that the toolchain is compiling with the -no-canonical-prefixes and/or -fno-canonical-system-headers arguments.

This can help work around errors like: the source file 'main.c' includes the following non-builtin files with absolute paths (if these are builtin files, make sure these paths are in your toolchain).
None
args (List[str]) The command-line arguments that are applied by using this rule. This is mutually exclusive with nested. None
data (List[Label]) A list of runtime data dependencies that are required for these arguments to work as intended. None
env (Dict[str, str]) Environment variables that should be set when the tool is invoked. None
format (Dict[str, Label]) A mapping of format strings to the label of the corresponding cc_variable that the value should be pulled from. All instances of {variable_name} will be replaced with the expanded value of variable_name in this dictionary. The complete list of possible variables can be found in https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/variables/BUILD. It is not possible to declare custom variables--these are inherent to Bazel itself. {}
iterate_over (Label) The label of a cc_variable that should be iterated over. This is intended for use with built-in variables that are lists. None
nested (List[Label]) A list of cc_nested_args rules that should be expanded to command-line arguments when this rule is used. This is mutually exclusive with args. None
requires_not_none (Label) The label of a cc_variable that should be checked for existence before expanding this rule. If the variable is None, this rule will be ignored. None
requires_none (Label) The label of a cc_variable that should be checked for non-existence before expanding this rule. If the variable is not None, this rule will be ignored. None
requires_true (Label) The label of a cc_variable that should be checked for truthiness before expanding this rule. If the variable is false, this rule will be ignored. None
requires_false (Label) The label of a cc_variable that should be checked for falsiness before expanding this rule. If the variable is true, this rule will be ignored. None
requires_equal (Label) The label of a cc_variable that should be checked for equality before expanding this rule. If the variable is not equal to (requires_equal_value)[#cc_args-requires_equal_value], this rule will be ignored. None
requires_equal_value (str) The value to compare (requires_equal)[#cc_args-requires_equal] against. None
requires_any_of (List[Label]) These arguments will be used in a tool invocation when at least one of the cc_feature_constraint entries in this list are satisfied. If omitted, this flag set will be enabled unconditionally. None
kwargs common attributes that should be applied to this rule. none

cc_nested_args

cc_nested_args(name, args, data, format, iterate_over, nested, requires_not_none, requires_none,
               requires_true, requires_false, requires_equal, requires_equal_value, kwargs)

Nested arguments for use in more complex cc_args expansions.

While this rule is very similar in shape to cc_args, it is intended to be used as a dependency of cc_args to provide additional arguments that should be applied to the same actions as defined by the parent cc_args rule. The key motivation for this rule is to allow for more complex variable-based argument expensions.

Prefer expressing collections of arguments as cc_args and cc_args_list rules when possible.

For living examples of how this rule is used, see the usages here: https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/args/runtime_library_search_directories/BUILD https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/args/libraries_to_link/BUILD

Note: These examples are non-trivial, but they illustrate when it is absolutely necessary to use this rule.

PARAMETERS

Name Description Default Value
name (str) The name of the target. none
args (List[str]) The command-line arguments that are applied by using this rule. This is mutually exclusive with nested. None
data (List[Label]) A list of runtime data dependencies that are required for these arguments to work as intended. None
format (Dict[str, Label]) A mapping of format strings to the label of the corresponding cc_variable that the value should be pulled from. All instances of {variable_name} will be replaced with the expanded value of variable_name in this dictionary. The complete list of possible variables can be found in https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/variables/BUILD. It is not possible to declare custom variables--these are inherent to Bazel itself. {}
iterate_over (Label) The label of a cc_variable that should be iterated over. This is intended for use with built-in variables that are lists. None
nested (List[Label]) A list of cc_nested_args rules that should be expanded to command-line arguments when this rule is used. This is mutually exclusive with args. None
requires_not_none (Label) The label of a cc_variable that should be checked for existence before expanding this rule. If the variable is None, this rule will be ignored. None
requires_none (Label) The label of a cc_variable that should be checked for non-existence before expanding this rule. If the variable is not None, this rule will be ignored. None
requires_true (Label) The label of a cc_variable that should be checked for truthiness before expanding this rule. If the variable is false, this rule will be ignored. None
requires_false (Label) The label of a cc_variable that should be checked for falsiness before expanding this rule. If the variable is true, this rule will be ignored. None
requires_equal (Label) The label of a cc_variable that should be checked for equality before expanding this rule. If the variable is not equal to (requires_equal_value)[#cc_nested_args-requires_equal_value], this rule will be ignored. None
requires_equal_value (str) The value to compare (requires_equal)[#cc_nested_args-requires_equal] against. None
kwargs common attributes that should be applied to this rule. none

cc_tool_map

cc_tool_map(name, tools, kwargs)

A toolchain configuration rule that maps toolchain actions to tools.

A cc_tool_map aggregates all the tools that may be used for a given toolchain and maps them to their corresponding actions. Conceptually, this is similar to the CXX=/path/to/clang++ environment variables that most build systems use to determine which tools to use for a given action. To simplify usage, some actions have been grouped together (for example, @rules_cc//cc/toolchains/actions:cpp_compile_actions) to logically express "all the C++ compile actions".

In Bazel, there is a little more granularity to the mapping, so the mapping doesn't follow the traditional CXX, AR, etc. naming scheme. For a comprehensive list of all the well-known actions, see @rules_cc//cc/toolchains/actions:BUILD.

Example usage:

load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map")

cc_tool_map(
    name = "all_tools",
    tools = {
        "@rules_cc//cc/toolchains/actions:assembly_actions": ":asm",
        "@rules_cc//cc/toolchains/actions:c_compile": ":clang",
        "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":clang++",
        "@rules_cc//cc/toolchains/actions:link_actions": ":lld",
        "@rules_cc//cc/toolchains/actions:objcopy_embed_data": ":llvm-objcopy",
        "@rules_cc//cc/toolchains/actions:strip": ":llvm-strip",
        "@rules_cc//cc/toolchains/actions:ar_actions": ":llvm-ar",
    },
)

Note: Due to an implementation limitation, if you need to map the same tool to multiple actions, you will need to create an intermediate alias for the tool for each set of actions. See https://github.com/bazelbuild/rules_cc/issues/235 for more details.

PARAMETERS

Name Description Default Value
name (str) The name of the target. none
tools (Dict[Label, Label]) A mapping between cc_action_type/cc_action_type_set targets and the cc_tool or executable target that implements that action. none
kwargs common attributes that should be applied to this rule. none

cc_variable

cc_variable(name, type, kwargs)

Exposes a toolchain variable to use in toolchain argument expansions.

This internal rule exposes toolchain variables that may be expanded in cc_args or cc_nested_args rules. Because these varaibles merely expose variables inherrent to Bazel, it's not possible to declare custom variables.

For a full list of available variables, see @rules_cc//cc/toolchains/varaibles:BUILD.

Example:

load("@rules_cc//cc/toolchains/impl:variables.bzl", "cc_variable")

# Defines two targets, ":foo" and ":foo.bar"
cc_variable(
    name = "foo",
    type = types.list(types.struct(bar = types.string)),
)

PARAMETERS

Name Description Default Value
name (str) The name of the outer variable, and the rule. none
type The type of the variable, constructed using types factory in @rules_cc//cc/toolchains/impl:variables.bzl. none
kwargs common attributes that should be applied to this rule. none