| .. _module-pw_toolchain_bazel-api: |
| |
| ============= |
| API reference |
| ============= |
| .. pigweed-module-subpage:: |
| :name: pw_toolchain_bazel |
| |
| .. py:class:: pw_cc_toolchain |
| |
| This rule is the core of a C/C++ toolchain definition. Critically, it is |
| intended to fully specify the following: |
| |
| * Which tools to use for various compile/link actions. |
| * Which `well-known features <https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features>`_ |
| are supported. |
| * Which flags to apply to various actions. |
| |
| .. py:attribute:: action_configs |
| :type: List[label] |
| |
| List of :py:class:`pw_cc_action_config` labels that bind tools to the |
| appropriate actions. This is how Bazel knows which binaries to use when |
| compiling, linking, or taking other actions like embedding data using |
| objcopy. |
| |
| .. py:attribute:: flag_sets |
| :type: List[label] |
| |
| List of flag sets to unconditionally apply to the respective |
| :py:class:`pw_cc_action_config`\s. The labels listed here will point to |
| :py:class:`pw_cc_flag_set` rules. |
| |
| .. py:attribute:: extra_action_files |
| :type: List[label] |
| |
| List of extra files to give to each different type of action. Replaces |
| all_files, ar_files, compiler_files, ... in the existing toolchain |
| definition. |
| |
| .. py:attribute:: toolchain_identifier |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: host_system_name |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: target_system_name |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: target_cpu |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: target_libc |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: compiler |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: abi_version |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: abi_libc_version |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: cc_target_os |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: builtin_sysroot |
| :type: str |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:attribute:: cxx_builtin_include_directories |
| :type: List[str] |
| |
| See `cc_common.create_cc_toolchain_config_info() <https://bazel.build/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info>`_\. |
| |
| .. py:class:: pw_cc_flag_set |
| |
| Declares an ordered set of flags bound to a set of actions. |
| |
| Flag sets can be attached to a :py:class:`pw_cc_toolchain` via |
| :py:attr:`pw_cc_toolchain.flag_sets`\. |
| |
| Examples: |
| |
| .. code-block:: py |
| |
| pw_cc_flag_set( |
| name = "warnings_as_errors", |
| flags = ["-Werror"], |
| ) |
| |
| pw_cc_flag_set( |
| name = "layering_check", |
| flag_groups = [ |
| ":strict_module_headers", |
| ":dependent_module_map_files", |
| ], |
| ) |
| |
| .. inclusive-language: disable |
| |
| Note: In the vast majority of cases, alphabetical sorting is not desirable |
| for the :py:attr:`pw_cc_flag_set.flags` and |
| :py:attr:`pw_cc_flag_set.flag_groups` attributes. |
| `Buildifier <https://github.com/bazelbuild/buildtools/blob/master/buildifier/README.md>`_ |
| shouldn't ever try to sort these, but in the off chance it starts to these |
| members should be listed as exceptions in the ``SortableDenylist``. |
| |
| .. inclusive-language: enable |
| |
| .. py:attribute:: actions |
| :type: List[str] |
| |
| A list of action names that this flag set applies to. |
| |
| .. inclusive-language: disable |
| |
| Valid choices are listed at |
| `@rules_cc//cc:action_names.bzl <https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/action_names.bzl>`_\. |
| |
| .. inclusive-language: enable |
| |
| It is possible for some needed action names to not be enumerated in this list, |
| so there is not rigid validation for these strings. Prefer using constants |
| rather than manually typing action names. |
| |
| .. py:attribute:: flags |
| :type: List[str] |
| |
| Flags that should be applied to the specified actions. |
| |
| These are evaluated in order, with earlier flags appearing earlier in the |
| invocation of the underlying tool. If you need expansion logic, prefer |
| enumerating flags in a :py:class:`pw_cc_flag_group` or create a custom |
| rule that provides ``FlagGroupInfo``. |
| |
| Note: :py:attr:`pw_cc_flag_set.flags` and |
| :py:attr:`pw_cc_flag_set.flag_groups` are mutually exclusive. |
| |
| .. py:attribute:: flag_groups |
| :type: List[label] |
| |
| Labels pointing to :py:class:`pw_cc_flag_group` rules. |
| |
| This is intended to be compatible with any other rules that provide |
| ``FlagGroupInfo``. These are evaluated in order, with earlier flag groups |
| appearing earlier in the invocation of the underlying tool. |
| |
| Note: :py:attr:`pw_cc_flag_set.flag_groups` and |
| :py:attr:`pw_cc_flag_set.flags` are mutually exclusive. |
| |
| .. py:class:: pw_cc_flag_group |
| |
| Declares an (optionally parametric) ordered set of flags. |
| |
| :py:class:`pw_cc_flag_group` rules are expected to be consumed exclusively by |
| :py:class:`pw_cc_flag_set` rules. Though simple lists of flags can be |
| expressed by populating ``flags`` on a :py:class:`pw_cc_flag_set`, |
| :py:class:`pw_cc_flag_group` provides additional power in the following two |
| ways: |
| |
| 1. Iteration and conditional expansion. Using |
| :py:attr:`pw_cc_flag_group.iterate_over`, |
| :py:attr:`pw_cc_flag_group.expand_if_available`\, and |
| :py:attr:`pw_cc_flag_group.expand_if_not_available`\, more complex |
| flag expressions can be made. This is critical for implementing things |
| like the ``libraries_to_link`` feature, where library names are |
| transformed into flags that end up in the final link invocation. |
| |
| Note: ``expand_if_equal``, ``expand_if_true``, and ``expand_if_false`` |
| are not yet supported. |
| |
| 2. Flags are tool-independent. A :py:class:`pw_cc_flag_group` expresses |
| ordered flags that may be reused across various |
| :py:class:`pw_cc_flag_set` rules. This is useful for cases where multiple |
| :py:class:`pw_cc_flag_set` rules must be created to implement a feature |
| for which flags are slightly different depending on the action (e.g. |
| compile vs link). Common flags can be expressed in a shared |
| :py:class:`pw_cc_flag_group`, and the differences can be relegated to |
| separate :py:class:`pw_cc_flag_group` instances. |
| |
| Examples: |
| |
| .. code-block:: py |
| |
| pw_cc_flag_group( |
| name = "user_compile_flag_expansion", |
| flags = ["%{user_compile_flags}"], |
| iterate_over = "user_compile_flags", |
| expand_if_available = "user_compile_flags", |
| ) |
| |
| # This flag_group might be referenced from various FDO-related |
| # `pw_cc_flag_set` rules. More importantly, the flag sets pulling this in |
| # may apply to different sets of actions. |
| pw_cc_flag_group( |
| name = "fdo_profile_correction", |
| flags = ["-fprofile-correction"], |
| expand_if_available = "fdo_profile_path", |
| ) |
| |
| .. py:attribute:: flags |
| :type: List[str] |
| |
| List of flags provided by this rule. |
| |
| For extremely complex expressions of flags that require nested flag groups |
| with multiple layers of expansion, prefer creating a custom rule in |
| `Starlark <https://bazel.build/rules/language>`_ that provides |
| ``FlagGroupInfo`` or ``FlagSetInfo``. |
| |
| |
| .. py:attribute:: iterate_over |
| :type: str |
| |
| Expands :py:attr:`pw_cc_flag_group.flags` for items in the named list. |
| |
| Toolchain actions have various variables accessible as names that can be |
| used to guide flag expansions. For variables that are lists, |
| :py:attr:`pw_cc_flag_group.iterate_over` must be used to expand the list into a series of flags. |
| |
| Note that :py:attr:`pw_cc_flag_group.iterate_over` is the string name of a |
| build variable, and not an actual list. Valid options are listed in the |
| `C++ Toolchain Configuration <https://bazel.build/docs/cc-toolchain-config-reference#cctoolchainconfiginfo-build-variables>`_ |
| reference. |
| |
| |
| |
| Note that the flag expansion stamps out the entire list of flags in |
| :py:attr:`pw_cc_flag_group.flags` once for each item in the list. |
| |
| Example: |
| |
| .. code-block:: py |
| |
| # Expands each path in ``system_include_paths`` to a series of |
| # ``-isystem`` includes. |
| # |
| # Example input: |
| # system_include_paths = ["/usr/local/include", "/usr/include"] |
| # |
| # Expected result: |
| # "-isystem /usr/local/include -isystem /usr/include" |
| pw_cc_flag_group( |
| name = "system_include_paths", |
| flags = ["-isystem", "%{system_include_paths}"], |
| iterate_over = "system_include_paths", |
| ) |
| |
| .. py:attribute:: expand_if_available |
| :type: str |
| |
| Expands the expression in :py:attr:`pw_cc_flag_group.flags` if the |
| specified build variable is set. |
| |
| .. py:attribute:: expand_if_not_available |
| :type: str |
| |
| Expands the expression in :py:attr:`pw_cc_flag_group.flags` if the |
| specified build variable is **NOT** set. |
| |
| .. py:class:: pw_cc_tool |
| |
| Declares a singular tool that can be bound to action configs. |
| |
| :py:class:`pw_cc_tool` rules are intended to be consumed exclusively by |
| :py:class:`pw_cc_action_config` rules. These rules declare an underlying tool |
| that can be used to fulfill various actions. Many actions may reuse a shared |
| tool. |
| |
| Examples: |
| |
| .. code-block:: py |
| |
| # A project-provided tool. |
| pw_cc_tool( |
| name = "clang_tool", |
| tool = "@llvm_toolchain//:bin/clang", |
| ) |
| |
| # A tool expected to be preinstalled on a user's machine. |
| pw_cc_tool( |
| name = "clang_tool", |
| path = "/usr/bin/clang", |
| ) |
| |
| .. py:attribute:: tool |
| :type: label |
| |
| The underlying tool that this rule represents. |
| |
| This attribute is a label rather than a simple file path. This means that |
| the file must be referenced relative to the BUILD file that exports it. |
| For example: |
| |
| .. code-block:: none |
| |
| @llvm_toolchain//:bin/clang |
| ^ ^ ^ |
| |
| Where: |
| |
| * ``@llvm_toolchain`` is the repository. |
| * ``//`` is the directory of the BUILD file that exports the file of |
| interest. |
| * ``bin/clang`` is the path of the actual binary relative to the BUILD |
| file of interest. |
| |
| Note: :py:attr:`pw_cc_tool.tool` and :py:attr:`pw_cc_tool.path` are |
| mutually exclusive. |
| |
| .. py:attribute:: path |
| :type: Path |
| |
| An absolute path to a binary to use for this tool. |
| |
| Relative paths are also supported, but they are relative to the |
| :py:class:`pw_cc_toolchain` that uses this tool rather than relative to |
| this :py:class:`pw_cc_tool` rule. |
| |
| Note: :py:attr:`pw_cc_tool.path` and :py:attr:`pw_cc_tool.tool` are |
| mutually exclusive. |
| |
| .. admonition:: Note |
| :class: warning |
| |
| This method of listing a tool is NOT recommended, and is provided as an |
| escape hatch for edge cases. Prefer using :py:attr:`pw_cc_tool.tool` |
| whenever possible. |
| |
| .. py:attribute:: execution_requirements |
| :type: List[str] |
| |
| A list of strings that provide hints for execution environment |
| compatibility (e.g. ``requires-darwin``). |
| |
| .. py:attribute:: requires_any_of |
| :type: List[label] |
| |
| This tool may only be enabled when at least one of the constraints are |
| met. |
| |
| If omitted, this tool will be enabled unconditionally. |
| |
| .. py:attribute:: additional_files |
| :type: List[label] |
| |
| Additional files that are required for this tool to correctly operate. |
| These files are propagated up to the :py:class:`pw_cc_toolchain` so you |
| typically won't need to explicitly specify the ``*_files`` attributes |
| on a :py:class:`pw_cc_toolchain`. |
| |
| |
| .. py:class:: pw_cc_action_config |
| |
| Declares the configuration and selection of `pw_cc_tool` rules. |
| |
| Action configs are bound to a toolchain through `action_configs`, and are the |
| driving mechanism for controlling toolchain tool invocation/behavior. |
| |
| Action configs define three key things: |
| |
| * Which tools to invoke for a given type of action. |
| * Tool features and compatibility. |
| * :py:class:`pw_cc_flag_set`\s that are unconditionally bound to a tool |
| invocation. |
| |
| Examples: |
| |
| .. code-block:: py |
| |
| pw_cc_action_config( |
| name = "ar", |
| action_names = ["@pw_toolchain//actions:all_ar_actions"], |
| implies = [ |
| "@pw_toolchain//features/legacy:archiver_flags", |
| "@pw_toolchain//features/legacy:linker_param_file", |
| ], |
| tools = [":ar_tool"], |
| ) |
| |
| pw_cc_action_config( |
| name = "clang", |
| action_names = [ |
| "@pw_toolchain//actions:all_asm_actions", |
| "@pw_toolchain//actions:all_c_compiler_actions", |
| ] |
| tools = [":clang_tool"], |
| ) |
| |
| .. py:attribute:: action_names |
| :type: List[str] |
| |
| A list of action names to apply this action to. |
| |
| .. inclusive-language: disable |
| |
| Valid choices are listed at |
| `@rules_cc//cc:action_names.bzl <https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/action_names.bzl>`_\. |
| |
| .. inclusive-language: enable |
| |
| It is possible for some needed action names to not be enumerated in this list, |
| so there is not rigid validation for these strings. Prefer using constants |
| rather than manually typing action names. |
| |
| .. py:attribute:: enabled |
| :type: bool |
| |
| Whether or not this action config is enabled by default. |
| |
| .. admonition:: Note |
| |
| This defaults to ``True`` since it's assumed that most listed action |
| configs will be enabled and used by default. This is the opposite of |
| Bazel's native default. |
| |
| .. py:attribute:: tools |
| :type: List[label] |
| |
| The tool to use for the specified actions. |
| |
| A tool can be a :py:class:`pw_cc_tool`, or a binary. |
| |
| If multiple tools are specified, the first tool that has ``with_features`` |
| that satisfy the currently enabled feature set is used. |
| |
| .. py:attribute:: flag_sets |
| :type: List[label] |
| |
| Labels that point to :py:class:`pw_cc_flag_set`\s that are unconditionally |
| bound to the specified actions. |
| |
| .. admonition:: Note |
| |
| The flags in the :py:class:`pw_cc_flag_set` are only bound to matching |
| action names. If an action is listed in this rule's |
| :py:attr:`pw_cc_action_config.action_names`, |
| but is NOT listed in the :py:class:`pw_cc_flag_set`\'s |
| :py:attr:`pw_cc_flag_set.actions`, the flag will not be applied to that |
| action. |
| |
| .. py:attribute:: implies |
| :type: List[str] |
| |
| Names of features that should be automatically enabled when this tool is |
| used. |
| |
| .. admonition:: Note |
| :class: warning |
| |
| If this action config implies an unknown feature, this action config |
| will silently be disabled. This behavior is native to Bazel itself, and |
| there's no way to detect this and emit an error instead. For this |
| reason, be very cautious when listing implied features! |
| |
| .. py:class:: pw_cc_feature |
| |
| Defines the implemented behavior of a C/C++ toolchain feature. |
| |
| |
| This rule is effectively a wrapper for the ``feature`` constructor in |
| `@rules_cc//cc:cc_toolchain_config_lib.bzl <https://github.com/bazelbuild/rules_cc/blob/main/cc/cc_toolchain_config_lib.bzl>`_. |
| |
| A feature is basically a dynamic flag set. There are a variety of |
| dependencies and compatibility requirements that must be satisfied for the |
| listed flag sets to be applied. |
| |
| A feature may be enabled or disabled through the following mechanisms:\ |
| |
| * Via command-line flags, or a |
| `.bazelrc file <https://bazel.build/run/bazelrc>`_\. |
| * Through inter-feature relationships (enabling one feature may implicitly |
| enable another). |
| * Individual rules may elect to manually enable or disable features through |
| the |
| `builtin features attribute <https://bazel.build/reference/be/common-definitions#common.features>`_\. |
| |
| Because of the dynamic nature of toolchain features, it's generally best to |
| avoid enumerating features as part of your toolchain with the following |
| exceptions: |
| |
| * You want the flags to be controllable via Bazel's CLI. For example, adding |
| ``-v`` to a compiler invocation is often too verbose to be useful for most |
| workflows, but can be instrumental when debugging obscure errors. By |
| expressing compiler verbosity as a feature, users may opt-in when |
| necessary. |
| * 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. This rule exists to |
| support those existing structures. |
| |
| For more details about how Bazel handles features, see the official Bazel |
| documentation at |
| https://bazel.build/docs/cc-toolchain-config-reference#features. |
| |
| Note: ``env_sets`` are not yet supported. |
| |
| Examples: |
| |
| .. code-block:: py |
| |
| # A feature that can be easily toggled to include extra compiler output to |
| # help debug things like include search path ordering and showing all the |
| # flags passed to the compiler. |
| # |
| # Add `--features=verbose_compiler_output` to your Bazel invocation to |
| # enable. |
| pw_cc_feature( |
| name = "verbose_compiler_output", |
| enabled = False, |
| feature_name = "verbose_compiler_output", |
| flag_sets = [":verbose_compiler_flags"], |
| ) |
| |
| # 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 |
| pw_cc_feature( |
| name = "link_object_files", |
| enabled = True, |
| feature_name = "supports_start_end_lib", |
| ) |
| |
| .. py:attribute:: feature_name |
| :type: str |
| |
| The name of the feature that this rule implements. |
| |
| Feature names are used to express feature dependencies and compatibility. |
| Because features are tracked by string names rather than labels, there's |
| great flexibility in swapping out feature implementations or overriding |
| the built-in legacy features that Bazel silently binds to every |
| toolchain. |
| |
| :py:attr:`pw_cc_feature.feature_name` is used rather than ``name`` to |
| distinguish between the rule name, and the intended final feature name. |
| This allows similar rules to exist in the same package, even if slight |
| differences are required. |
| |
| Example: |
| |
| .. code-block:: py |
| |
| pw_cc_feature( |
| name = "sysroot_macos", |
| feature_name = "sysroot", |
| ... |
| ) |
| |
| pw_cc_feature( |
| name = "sysroot_linux", |
| feature_name = "sysroot", |
| ... |
| ) |
| |
| While two features with the same :py:attr:`pw_cc_feature.feature_name` may |
| not be bound to the same toolchain, they can happily live alongside each |
| other in the same BUILD file. |
| |
| .. py:attribute:: enabled |
| :type: bool |
| |
| Whether or not this feature is enabled by default. |
| |
| .. py:attribute:: flag_sets |
| :type: List[label] |
| |
| Flag sets that, when expanded, implement this feature. |
| |
| .. py:attribute:: requires_any_of |
| :type: List[label] |
| |
| A list of feature sets that define toolchain compatibility. |
| |
| If **at least one** of the listed :py:class:`pw_cc_feature`\s or |
| :py:class:`pw_cc_feature_set`\s are satisfied (all features exist in the |
| toolchain AND are currently enabled), this feature is deemed compatible |
| and may be enabled. |
| |
| If this feature **cannot** be enabled (such as if, in the first example |
| below, thin_lto didn't exist in the toolchain), it will throw an error. |
| |
| .. code-block:: py |
| |
| pw_cc_feature( |
| name = "requires_thin_lto_and_opt", |
| feature_name = "requires_thin_lto_and_opt", |
| requires_any_of = [":thin_lto_requirements"] |
| ) |
| |
| pw_cc_feature( |
| name = "requires_thin_lto_or_opt", |
| feature_name = "requires_thin_lto_or_opt", |
| requires_any_of = [":thin_lto", ":opt"] |
| ) |
| |
| .. admonition:: Note |
| |
| Even if :py:attr:`pw_cc_feature.requires_any_of` is satisfied, a |
| feature is not enabled unless another mechanism (e.g. command-line |
| flags, :py:attr:`pw_cc_feature.implies`, or |
| :py:attr:`pw_cc_feature.enabled`\) signals that the feature should |
| actually be enabled. |
| |
| .. py:attribute:: implies |
| :type: List[label] |
| |
| List of features or action configs enabled along with this feature. |
| |
| .. admonition:: Note |
| :class: warning |
| |
| If any of the named features cannot be enabled, this feature is |
| silently disabled. |
| |
| .. py:attribute:: mutually_exclusive |
| :type: List[Label] |
| |
| A list of feature or mutually exclusive categories that this feature is |
| mutually exclusive with. |
| |
| .. admonition:: Note |
| |
| This feature cannot be enabled if another feature also provides the |
| listed feature. |
| |
| |
| .. py:class:: pw_cc_feature_set |
| |
| Defines a group of features. |
| |
| Semantically equivalent to "all of the specified features", and may be used |
| wherever you can provide multiple features. |
| |
| Example: |
| |
| .. code-block:: py |
| |
| pw_cc_feature_set( |
| name = "thin_lto_requirements", |
| all_of = [ |
| ":thin_lto", |
| ":opt", |
| ], |
| ) |
| |
| .. py:attribute:: features |
| :type: List[label] |
| |
| Features that must be enabled for this feature set to be deemed compatible |
| with the current toolchain configuration. |