| # CC Toolchain Features | |
| NOTE: It's possible this document has drifted, please file issues or | |
| submit PRs for any inaccuracies you find | |
| ## Toolchain features | |
| CC toolchains are configured by creating features. Features are | |
| arbitrary strings for enabling or disabling behavior in the toolchain. | |
| Semantically there are 3 types of features: | |
| 1. Features whose names are arbitrary, and are only used to carry | |
| command line flags. | |
| 2. Features with special names which are markers to bazel / `rules_cc` | |
| that some behavior should be enabled or is supported by the toolchain | |
| 3. Features with special names, that are also expected to pass the | |
| various compiler / linker flags to enable some behavior. | |
| With all features, even though the feature name may have special meaning | |
| to `rules_cc`, it is still up to your toolchain to provide the correct | |
| compiler flags for your situation. | |
| Depending on how bazel / `rules_cc` read the features, you might need to | |
| define them differently. | |
| In some cases `rules_cc` checks if a feature is *supported*, or it | |
| automatically _enables_ it when it's relevant. In this case that means a | |
| feature with that name is defined in the toolchain. For example: | |
| ```bzl | |
| return [ | |
| cc_common.create_cc_toolchain_config_info( | |
| features = [ | |
| feature(name = "dbg"), # Supported by the toolchain but off by default | |
| ], | |
| ... | |
| ), | |
| ] | |
| ``` | |
| This is separate from if a feature is *enabled*, which either means a | |
| feature is defined in the toolchain _and_ automatically enabled: | |
| This is separate from when a feature is *enabled*, which means one of | |
| the following: | |
| - The feature is defined in the toolchain _and_ enabled by default in | |
| its definition: | |
| ```bzl | |
| feature( | |
| name = "archive_param_file", | |
| enabled = True, # Enabled by default when defined | |
| ), | |
| ``` | |
| - the feature is enabled by a user passing | |
| `--features=archive_param_file`, setting `features = | |
| ["archive_param_file"]` or through other mechanisms in the toolchain | |
| definition (not covered here). | |
| This distinction is important for when `rules_cc` checks if a feature is | |
| enabled, without automatically enabling it. This is common for "marker" | |
| features. If `rules_cc` checks for a feature being enabled, it not | |
| existing in the toolchain will be treated the same as it being disabled. | |
| This means a toolchain that does not want to support a feature can omit | |
| it. | |
| In some cases `rules_cc` bases behavior on the presence of a feature, | |
| but doesn't require it to be enabled. This is rare but mentioned for the | |
| relevant features below. | |
| NOTE: Feature names aren't really considered public API, and are subject | |
| to change more frequently than the rest of the API (even though their | |
| behavior likely doesn't change often). | |
| NOTE: While this document attempts to cover `rules_cc` behavior, it is | |
| possible for any custom rule to read the features of the toolchain and | |
| change its behavior based on them. | |
| ## Legacy features | |
| By default, unless you add the | |
| [`no_legacy_features`](#no_legacy_features) feature to your toolchain, | |
| you will automatically inherit the features (and action configurations) | |
| defined in | |
| [`legacy_features.bzl`](../cc/private/toolchain_config/legacy_features.bzl). | |
| It is recommended that you override all features to avoid this | |
| potentially confusing behavior. You can read that file to see the | |
| current defaults. | |
| If you do not add a `no_legacy_features` feature, any features you add | |
| with the same name as a legacy feature will override the default | |
| behavior, but any that you omit will be added to your toolchain | |
| implicitly. | |
| ## All features | |
| Below are all of the features names that currently have special meaning | |
| for bazel / `rules_cc`, or are commonly used directly by users. | |
| ### `archive_param_file` | |
| A marker feature indicating that the archiver supports reading arguments | |
| from a `@params` file. | |
| This feature must be enabled if desired. | |
| ### `compiler_param_file` | |
| A marker feature indicating that bazel / `rules_cc` should pass | |
| arguments to the compiler with a `@params` file. | |
| This feature must be enabled if desired. | |
| ### `compiler_param_file_on_demand` | |
| A marker feature indicating that bazel / `rules_cc` should pass | |
| arguments to the compiler with a `@params` file only when it seems like | |
| it will be needed based on command length. | |
| This feature must be enabled if desired. | |
| ### `compile_all_modules` | |
| A marker feature that causes all headers in the generated `modulemap`s | |
| for [`layering_check`](#layering_check) to be written as compilable | |
| `header` instead of `textual header`, which causes `clang` to attempt | |
| to build a compiled module from them. This is required for actually | |
| building modules from the generated `modulemap`s, which isn't | |
| necessary for common `layering_check` uses. | |
| Expected to be supported for Swift interop. | |
| This feature must be enabled if desired. | |
| ### `copy_dynamic_libraries_to_binary` | |
| A marker feature that causes bazel to copy dependent shared libraries to | |
| the output directory of a `cc_binary` when linking against them. This is | |
| commonly used on Windows. | |
| This feature must be enabled if desired. | |
| ### `coverage` / `gcc_coverage_map_format` / `llvm_coverage_map_format` | |
| Bazel / `rules_cc` automatically enables the `coverage` feature when | |
| using `bazel coverage` or `bazel build --collect_code_coverage`. It then | |
| either enables `gcc_coverage_map_format` (default) or | |
| `llvm_coverage_map_format` (if `--experimental_use_llvm_covmap` is set). | |
| At this point it is up to the toolchain to pass the correct compiler / | |
| linker flags to produce the instrumented binaries. | |
| These features are all off by default. Toolchains should make the format | |
| features dependent on `coverage` being enabled. | |
| ### `coverage_enabled` / `coverage_instrumented` | |
| `coverage_enabled` is requested whenever `coverage` is, that is, whenever | |
| coverage collection is generally enabled for the build. | |
| `coverage_instrumented` is requested in addition to it, but only for those | |
| targets that are actually instrumented for coverage, either because they | |
| match | |
| [`--instrumentation_filter`](https://bazel.build/reference/command-line-reference#flag--instrumentation_filter) | |
| themselves or because one of their direct `deps` or `implementation_deps` | |
| does and may thus provide instrumented headers. | |
| Toolchains should use these features instead of `coverage` to restrict | |
| instrumentation flags to the compile actions that actually need them, which | |
| is considerably cheaper than instrumenting every target in the build. Link | |
| actions still need the coverage runtime whenever `coverage_enabled` is | |
| requested, as an uninstrumented binary can link in instrumented libraries. | |
| These features are off by default and requested as described above. Older | |
| versions of Bazel and `rules_cc` only request `coverage`, so toolchains | |
| that support those as well should keep their `coverage` flag sets and guard | |
| them with `with_feature_set(not_features = ["coverage_enabled"])`. | |
| ### `cpp_modules` | |
| A marker feature for enabling C++20 modules. This also depends on | |
| `--experimental_cpp_modules` being passed. | |
| This feature must be enabled if desired. | |
| ### `dbg` / `fastbuild` / `opt` | |
| These features are requested based on | |
| [`--compilation_mode`](https://bazel.build/reference/command-line-reference#flag--compilation_mode) | |
| and primarily useful for customizing other features in the toolchain. | |
| These features are mutually exclusive and one is always enabled. By | |
| default they are all disabled in a toolchain definition. | |
| ### `dead_strip` | |
| This feature is requested based on | |
| [`--objc_enable_binary_stripping`](https://bazel.build/reference/command-line-reference#flag--objc_enable_binary_stripping) | |
| and commonly correlates with the `-dead_strip` linker flag. | |
| This feature should be off by default. | |
| ### `disable_whole_archive_for_static_lib` | |
| Disable allowing `alwayslink = True` usage on a library. | |
| This feature should be off by default. | |
| ### `dynamic_link_test_srcs` | |
| A marker feature that affects linking behavior of `cc_test` targets. See | |
| the source for details. | |
| This feature should be off by default. | |
| ### `exclude_private_headers_in_module_maps` | |
| A marker feature for excluding private headers from the generated | |
| `modulemap`s for [`layering_check`](#layering_check). Otherwise private | |
| headers are included with `private header`. | |
| Expected to be supported for Swift interop. | |
| This feature should be off by default. | |
| ### `external_include_paths` | |
| A marker feature indicating that all external bazel modules' include | |
| paths should be passed through `-isystem` instead of `-I`. This is still | |
| up to the toolchain to configure correctly, but this affects the | |
| toolchain variables the include paths are passed through. | |
| This feature should be off by default. | |
| ### `force_no_whole_archive` / `legacy_whole_archive` | |
| Deprecated marker features to disable linking shared libraries with | |
| `--whole-archive` by default. | |
| These features should be off by default. | |
| ### `fully_static_link` | |
| `fully_static_link` is not used by `rules_cc` directly but is | |
| recommended in the `cc_binary` documentation for producing fully | |
| statically linked binaries. If you want to support this it should be | |
| implemented in your toolchain. For example the default implementation is | |
| to pass `-static` to the linker when this feature is enabled. | |
| This feature is off by default. | |
| ### `gcc_quoting_for_param_files` / `windows_quoting_for_param_files` | |
| Marker features to configure the quoting style of arguments in `@params` | |
| files. If neither are enabled, no quoting is applied. | |
| These features must be enabled if desired. | |
| ### `generate_submodules` | |
| A marker feature for generating submodules for each header in the | |
| generated `modulemap`s for [`layering_check`](#layering_check). | |
| This feature should be off by default. | |
| ### `has_configured_linker_path` | |
| A marker feature indicating that when creating an interface shared | |
| library, the toolchain calls the default configured linker. In this case | |
| it's up to the default linker and toolchain to correctly emit both the | |
| normal shared library, and the interface library. If this is not set | |
| `rules_cc` uses the `@bazel_tools//tools/cpp:link_dynamic_library` | |
| helper instead (which might not work with all toolchain configurations). | |
| This feature should be enabled if desired. | |
| ### `header_module_codegen` / `header_modules` / `use_header_modules` | |
| Use `clang` modules for some cases. Read the source for details. | |
| These features should be off by default. | |
| ### `generate_dsym_file` / `no_generate_debug_symbols` | |
| `generate_dsym_file` is requested based on | |
| [`--apple_generate_dsym`](https://bazel.build/reference/command-line-reference#flag--apple_generate_dsym) | |
| and indicates that the toolchain should generate a dsym file for | |
| debugging on Apple platforms. `no_generate_debug_symbols` is set in the opposite case. | |
| These features should be off by default. | |
| ### `generate_linkmap` | |
| This feature is requested based on | |
| [`--objc_generate_linkmap`](https://bazel.build/reference/command-line-reference#flag--objc_generate_linkmap) | |
| and commonly correlates with the `-map` linker flag. | |
| This feature should be off by default. | |
| ### `generate_pdb_file` | |
| This feature indicates a Windows `pdb` file should be created when | |
| linking a binary. This must be enabled by the user or the toolchain. | |
| This feature must be enabled if desired. | |
| ### `lang_objc` | |
| A marker feature indicating that Objective-C or Objective-C++ is being | |
| built. | |
| This feature should be off by default. | |
| ### `layering_check` | |
| Enable validation that a library directly depends on everything it uses. | |
| This is implemented using `clang`'s `modulemap` features. See the | |
| default toolchains for implementation examples. `rules_cc` does not | |
| reference this feature directly, but the name `layering_check` is used | |
| by users to enable this behavior, and disable it for incompatible | |
| targets. | |
| This feature should be off by default and turned on at the project / | |
| target level. | |
| ### LTO features | |
| Bazel / `rules_cc` have many special features for LTO behavior: | |
| - `thin_lto` top level feature that is also used by users | |
| - `thin_lto_all_linkstatic_use_shared_nonlto_backends` read the source | |
| - `thin_lto_linkstatic_tests_use_shared_nonlto_backends` read the source | |
| - `no_use_lto_indexing_bitcode_file` read the source | |
| - `use_lto_native_object_directory` read the source | |
| These features must be enabled if desired. | |
| ### `module_maps` | |
| A marker feature that should always be enabled if supported indicating | |
| that the compiler supports `modulemap` files (`clang`). This is required | |
| for `layering_check`. | |
| This feature should be enabled by default if supported. | |
| ### `module_map_home_cwd` | |
| Whether a `modulemap` used with [`layering_check`](#layering_check) | |
| should use its current directory as the `cwd`. This affects relative | |
| paths in the generated `modulemap`s. This is only useful if you need to | |
| also pass the related `clang` flags. | |
| This feature should be off by default. | |
| ### `module_map_without_extern_module` | |
| A marker feature to disable writing `extern module` declarations in the | |
| generated `modulemap`s for [`layering_check`](#layering_check). | |
| Expected to be supported for Swift interop. | |
| This feature should be off by default. | |
| ### `no_dotd_file` | |
| A marker feature for disabling `.d` file generating and parsing by | |
| bazel. Dotd file parsing is also dependent on | |
| [`--cc_dotd_files`](https://bazel.build/reference/command-line-reference#flag--cc_dotd_files) | |
| and | |
| [`--objc_use_dotd_pruning`](https://bazel.build/reference/command-line-reference#flag--objc_use_dotd_pruning) | |
| This feature should be off by default. | |
| ### `no_legacy_features` | |
| Disable `rules_cc` automatically adding the legacy features to the | |
| toolchain (discussed above). | |
| This feature should be added if possible, but its enabled state does no | |
| matter. | |
| ### `no_stripping` | |
| When enabled `rules_cc` does not strip a `cc_binary` to create the | |
| implicit `binary.stripped`, instead it is only symlinked. | |
| This feature should be off by default. | |
| ### `only_doth_headers_in_module_maps` | |
| A marker feature for only including `.h` files in the generated | |
| `modulemap`s for [`layering_check`](#layering_check). Otherwise public | |
| headers with any extension are included. | |
| Expected to be supported for Swift interop. | |
| This should be off by default. | |
| ### `parse_headers` | |
| This feature is used alongside | |
| [`--process_headers_in_dependencies`](https://bazel.build/reference/command-line-reference#flag--process_headers_in_dependencies) | |
| to run a separate action that validates header files are valid on their | |
| own. This feature is special to `rules_cc` but is also used by users to | |
| enable this behavior, and disable it for incompatible targets. | |
| See also [`layering_check`](#layering_check) | |
| This should be off by default and turned on at the project / target | |
| level. | |
| ### `parse_headers_as_c` | |
| This feature is used alongside `parse_headers` to parse headers as C | |
| instead of C++. This is useful headers that are not valid C++. | |
| This should be off by default and turned on at the project / target | |
| level. | |
| ### `parse_showincludes` | |
| A marker feature for enabling parsing of the output of `/showIncludes` | |
| to generate `.d` for parsing by bazel. Dotd file parsing is also | |
| dependent on | |
| [`--cc_dotd_files`](https://bazel.build/reference/command-line-reference#flag--cc_dotd_files) | |
| and | |
| [`--objc_use_dotd_pruning`](https://bazel.build/reference/command-line-reference#flag--objc_use_dotd_pruning) | |
| This feature should be enabled by default if supported. | |
| ### `per_object_debug_info` | |
| This feature name, alongside the value of | |
| [`--fission`](https://bazel.build/reference/command-line-reference#flag--fission) | |
| is used to determine if debug info should be produced in a separate file | |
| from the object file. | |
| This feature is off by default. | |
| ### `pic` / `supports_pic` | |
| Bazel / `rules_cc` checks if your toolchain has an enabled feature named | |
| `supports_pic` to determine if position independent code is supported at | |
| all. If so it also expects an enabled feature named `pic` which actually | |
| adds the relevant compiler flags in the correct cases (only when the | |
| `pic` variable is enabled). You should also add another feature that | |
| respects the `force_pic` variable, which reacts to the `--force_pic` | |
| flag. | |
| See also [`prefer_pic_for_opt_binaries`](#prefer_pic_for_opt_binaries) | |
| `pic`, `supports_pic`, and the optional `force_pic` feature, should all | |
| be enabled by default if PIC is supported. The implementation of these | |
| features should be contingent on the relevant variables being set. See | |
| the default toolchains for an example. | |
| ### `prefer_pic_for_opt_binaries` | |
| A marker feature to automatically enable position independent code when | |
| using `--compilation_mode=opt`. | |
| This feature must be enabled if desired. | |
| ### Profile guided optimization features | |
| `rules_cc` has quite a few PGO/FDO features, which are all automatically | |
| enabled based on various [`--fdo_*`](https://bazel.build/reference/command-line-reference#flag--fdo_instrument) | |
| flags it supports. To get the most up to date information on how all of | |
| these fit together it's best to look at the code. The combination of all | |
| of these features likely isn't well tested today. | |
| The current list of features (not all of these are provided by the | |
| legacy features) is: | |
| - `autofdo` | |
| - `cs_fdo_instrument` | |
| - `cs_fdo_optimize` | |
| - `enable_afdo_thinlto` | |
| - `enable_autofdo_memprof_optimize` | |
| - `enable_fdo_memprof_optimize` | |
| - `enable_fdo_split_functions` | |
| - `enable_fdo_thinlto` | |
| - `enable_fsafdo` | |
| - `enable_xbinaryfdo_thinlto` | |
| - `fdo_instrument` | |
| - `fdo_optimize` | |
| - `fdo_prefetch_hints` | |
| - `propeller_optimize_thinlto_compile_actions` | |
| - `propeller_optimize` | |
| - `xbinary_fdo` | |
| - `xbinaryfdo` (yes both of these exist) | |
| All of these features are off by default. | |
| ### `no_copts_tokenization` | |
| A marker feature to disable shell tokenization of `copts` in the toolchain. | |
| This can be used by users to make sure special characters that are | |
| expected in `defines` / `copts` are not processed. This is required in | |
| some cases when you have quoted arguments. | |
| This feature takes effect even if the toolchain doesn't define it. There | |
| is no purpose in adding it to your toolchain unless you want to enable | |
| it everywhere. | |
| ### `sanitize_pwd` | |
| A marker feature indicating the toolchain has sanitized the `PWD` from | |
| the outputs. Otherwise `rules_cc` will set `PWD=/proc/self/cwd` (unless | |
| on macOS) when linking a binary. This is commonly used when | |
| `-fdebug-prefix-map` is supported by the compiler. | |
| This feature must be enabled by default if supported. | |
| ### `set_soname` | |
| A marker feature that causes interface libraries to respect the `soname` | |
| they have. Otherwise `-soname` is passed when creating interface libraries. | |
| This feature must be enabled by default if supported. | |
| ### `serialized_diagnostics_file` | |
| A marker feature for enabling generating a serialized diagnostics file | |
| from the compiler. Commonly used with the `--serialize-diagonostics` | |
| `clang` flag. | |
| This feature should be off by default and requested through `--features` | |
| when desired. | |
| ### `shorten_virtual_includes` | |
| A marker feature that causes virtual include paths generated by | |
| `strip_include_prefix` and friends to use a shorter path. This is useful | |
| on Windows to avoid long path issues. | |
| This feature must be enabled by default if desired. | |
| ### `skip_virtual_includes` | |
| A marker feature that avoids creating `_virtual_includes` symlinks when | |
| headers only need a `strip_include_prefix` (without an | |
| `include_prefix`). Instead, `rules_cc` adds the stripped directory to | |
| the include paths directly and uses the original headers. This reduces | |
| path lengths and can help avoid long path issues on Windows. | |
| The only downside of this feature is that if you disable sandboxing | |
| non-declared headers can be included that are in the same directory as | |
| the one being added to the include path. This would still be caught by | |
| [`layering_check`](#layering_check) if enabled. | |
| See also [`shorten_virtual_includes`](#shorten_virtual_includes). | |
| This feature must be enabled if desired. | |
| ### `static_link_cpp_runtimes` | |
| A marker feature used by `rules_cc` to determine if the toolchain | |
| should statically link the C++ runtime libraries. | |
| This feature must be enabled if desired. | |
| ### `supports_dynamic_linker` | |
| A marker feature that indicates 2 things: | |
| 1. That `cc_library` targets can create "nodeps" shared libraries for | |
| use with | |
| [`--dynamic_mode`](https://bazel.build/reference/command-line-reference#flag--dynamic_mode). | |
| This requires shared libraries can be created without seeing their | |
| dependencies' symbols, which can lead to runtime crashes, but can | |
| reduce large static links for small changes. | |
| 2. Whether a `cc_binary` prefers linking static over shared libraries | |
| when both are available for a target. | |
| This feature must be enabled if supported. Otherwise it should be | |
| omitted from the toolchain. | |
| ### `supports_interface_shared_libraries` | |
| A marker feature indicating that the toolchain supports creating | |
| interface libraries for a shared libraries. This can be used to reduce | |
| input tree size of downstream linking actions. | |
| This feature must be enabled if supported. | |
| ### `supports_start_end_lib` | |
| Whether the toolchain supports using the `--start-lib` / `--end-lib` | |
| linker flags. This is required for use with `LTO`. | |
| This feature must be enabled if supported. | |
| ### `symbol_check` | |
| A feature automatically requested by `cc_static_library` that enables | |
| the toolchain to enable optional validation around the symbols in the | |
| produced static library. | |
| This feature should be off by default and is automatically requested by | |
| `cc_static_library`. | |
| ### `system_include_paths` | |
| A marker feature indicating that include paths from the `includes` | |
| attribute of a target should be passed with `-isystem` instead of `-I`. | |
| This is still up to the toolchain to configure correctly, but this | |
| affects the toolchain variables the include paths are passed through. | |
| This is expected to be set by users when necessary (hopefully rarely). | |
| This feature takes effect even if the toolchain doesn't define it. There | |
| is no purpose in adding it to your toolchain unless you want to enable | |
| it everywhere. | |
| ### `targets_windows` | |
| This is used by `rules_cc` to change the behavior in various places only | |
| when building for Windows. If your toolchain targets Windows this should | |
| be enabled. | |
| This feature must be enabled if targeting Windows. | |
| ### `treat_warnings_as_errors` | |
| A user-enabled feature requesting that warnings are treated as errors. | |
| This is not special to `rules_cc`. This is commonly used with the | |
| `-Werror` compiler flag. | |
| This feature should be off by default. | |
| ### `validates_layering_check_in_textual_hdrs` | |
| Whether `layering_check` should also apply to the `textual_hdrs` | |
| attribute of targets. | |
| See also [`layering_check`](#layering_check) | |
| This feature must be enabled if desired. | |
| ### `windows_export_all_symbols` / `no_windows_export_all_symbols` | |
| Marker features to configure whether a `.def` should be created. The | |
| negating feature wins if both are enabled. | |
| This feature must be enabled if desired. | |
| ### `warn_backrefs_defined` | |
| A marker feature indicating `-Wl,--warn-backrefs-exclude` should be | |
| passed when linking static libraries downstream of a `cc_import` | |
| This feature must be enabled if desired. |