| # 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. |
| |
| ### `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. |
| |
| ### `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. |