Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/extension_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ Flag and runtime attributes:
- `extra_c_compile_flags`
- `extra_cxx_compile_flags`
- `extra_link_flags`
- `extra_known_features`
- `extra_enabled_features`
- `ld_library_paths`
- `runtime_ecosystem`
- `use_base_constraints_only`
Expand All @@ -93,6 +95,21 @@ attributes are:
- `sha256`: sha256 of the archive
- `strip_prefix`: extraction prefix for packaged archives

## Feature Injection

`extra_known_features` and `extra_enabled_features` let a workspace add
rule-based `cc_feature` targets (defined outside this repository) to the
generated toolchain:

- `extra_known_features` — registers external features so they can be toggled
per target via the `features` attribute or build-wide via `--features`.
- `extra_enabled_features` — registers *and* enables external features by
default.

Sanitizers are the primary use case: they are defined by the
`score_cpp_policies` module and brought into the toolchain through these
attributes. See [Toolchain features](features.md#sanitizers-linux-opt-in).


## Activation In A Workspace

Expand Down Expand Up @@ -120,5 +137,10 @@ behavior explicitly, see the
- The extension is intended for the root module.
- When `use_default_package` is enabled, the version matrix can inject extra
include and link flags required by non-standard sysroot layouts.
- Sanitizer features are not registered automatically. They are defined by the
`score_cpp_policies` module and made available through *feature injection* —
the `extra_known_features` / `extra_enabled_features` attributes on
`gcc.toolchain(...)`. See [Toolchain features](features.md#sanitizers-linux-opt-in)
for the injected feature names.
- QNX toolchains use additional licensing and include-path parameters that do
not apply to Linux toolchains.
15 changes: 12 additions & 3 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,18 @@ Opt-in / disabled by default unless noted otherwise.
- **`warnings_as_errors`** (both) — Adds `-Werror`.

## Sanitizers (Linux, opt-in)
- **`sanitizer`** — Base sanitizer feature.
- **`asan`** / **`lsan`** / **`tsan`** / **`ubsan`** — Address / Leak / Thread /
Undefined-Behavior sanitizers; each implies `sanitizer`.
Sanitizers are **not** defined by this toolchain. They are provided as
rule-based `cc_feature` definitions by the `score_cpp_policies` module and made
available through *feature injection* — the `extra_known_features` /
`extra_enabled_features` attributes on `gcc.toolchain(...)`. Once injected they
behave like any other opt-in feature.

- **`score_asan`** — AddressSanitizer (`-fsanitize=address`).
- **`score_lsan`** — LeakSanitizer (`-fsanitize=leak`).
- **`score_tsan`** — ThreadSanitizer (`-fsanitize=thread`).
- **`score_ubsan`** — UndefinedBehaviorSanitizer (`-fsanitize=undefined`).

See the `score_cpp_policies` documentation for the authoritative list and usage.

## Threading
- **`use_pthread`** (Linux) — Links with `-pthread`.
Expand Down
18 changes: 12 additions & 6 deletions docs/migration_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,26 @@ toolchain, are summarized below.
| `gcov` | **Supported, wiring** | `tool_paths` (`gcov_wrapper`) |
| Warnings (e.g. `-Wall`) added by default | **Linux: opt-in · QNX: on by default** | `minimal_warnings` (includes `-Wall`) is enabled by default on QNX but disabled on Linux. `strict_warnings` / `all_wall_warnings` are opt-in on both. |
| `-Werror` | **Not implicit — opt-in** | `warnings_as_errors` (disabled by default) |
| Sanitizers (asan/lsan/tsan/ubsan) | **Not implicit — opt-in (Linux)** | `asan` / `lsan` / `tsan` / `ubsan` (disabled by default) |
| Sanitizers (asan/lsan/tsan/ubsan) | **Not part of this toolchain — injected (Linux)** | Defined by `score_cpp_policies` (`score_asan` / `score_lsan` / `score_tsan` / `score_ubsan`) and brought in via `extra_known_features` / `extra_enabled_features` |
| Fully static link (`-static`) | **Not implicit — opt-in** | `fully_static_link` (disabled by default) |
| `-pthread` | **Not implicit — opt-in (Linux)** | `use_pthread` (disabled by default) |
| Fission / split DWARF, linkstamps, strip, static-libgcc | **Supported, guarded** | Guarded features; no-ops until the relevant build mode is active |
| Any other Bazel legacy default not listed above | **Not available** | Must be added explicitly (see below) |

Two categories deserve special attention because they are the most frequent
Three categories deserve special attention because they are the most frequent
migration surprises:

1. **Warnings differ by platform.** On **Linux**, all warning features are
opt-in — if you expected `-Wall`-style warnings you must enable them. On
**QNX**, `minimal_warnings` (which includes `-Wall`) is enabled by default,
so those warnings do *not* disappear; `strict_warnings`,
`all_wall_warnings`, and `-Werror` remain opt-in on both platforms.
2. **`-pthread`, sanitizers, and fully-static linking are opt-in.** These emit
nothing until you enable the corresponding feature.
2. **`-pthread` and fully-static linking are opt-in.** These emit nothing until
you enable the corresponding feature.
3. **Sanitizers are not part of this toolchain.** They are defined by the
`score_cpp_policies` module and must first be injected via
`extra_known_features` / `extra_enabled_features` before they can be enabled.
See [Toolchain features](features.md#sanitizers-linux-opt-in).

For the authoritative and complete list, always refer to
[Toolchain features](features.md).
Expand Down Expand Up @@ -155,10 +159,12 @@ build:myconfig --host_features=use_pthread
### 3. Turn on an opt-in feature that already exists

Many legacy-equivalent behaviors already ship as opt-in features (warnings,
sanitizers, `fully_static_link`, `use_pthread`, `per_object_debug_info`, ...).
`fully_static_link`, `use_pthread`, `per_object_debug_info`, ...).
You do not need to modify the toolchain to use them — enable them with
mechanism 1 or 2 above. See the *Opt-in* entries in
[Toolchain features](features.md).
[Toolchain features](features.md). (Sanitizers are the exception: they are
defined by `score_cpp_policies` and must first be injected via
`extra_known_features` / `extra_enabled_features`.)

### 4. Inject raw flags through the toolchain attributes

Expand Down
24 changes: 24 additions & 0 deletions extensions/gcc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,26 @@ _attrs_tc = {
default = [],
doc = "List of additional flags to be passed to linker.",
),
"extra_enabled_features": attr.label_list(
mandatory = False,
default = [],
doc = ("Extra `cc_feature` features to add to this toolchain in an initially " +
"enabled state. This attribute has limited integration with `cc_feature`, " +
"and does not run additional correctness checks or handle things like `data` " +
"files. This is only offered as a migration bridge for projects transitioning " +
"to rule-based toolchain configurations, or sharing of simple argument sets " +
"with older toolchains."),
),
Comment thread
Copilot marked this conversation as resolved.
"extra_known_features": attr.label_list(
mandatory = False,
default = [],
doc = ("Extra `cc_feature` features to add to this toolchain in an initially " +
"disabled state. This attribute has limited integration with `cc_feature`, " +
"and does not run additional correctness checks or handle things like `data` " +
"files. This is only offered as a migration bridge for projects transitioning " +
"to rule-based toolchain configurations, or sharing of simple argument sets " +
"with older toolchains."),
),
Comment thread
Copilot marked this conversation as resolved.
"license_info_url": attr.string(
default = "",
mandatory = False,
Expand Down Expand Up @@ -197,6 +217,8 @@ def _get_toolchains(tags):
"tc_extra_compile_flags": tag.extra_compile_flags,
"tc_extra_cxx_compile_flags": tag.extra_cxx_compile_flags,
"tc_extra_link_flags": tag.extra_link_flags,
"tc_extra_known_features": tag.extra_known_features,
"tc_extra_enabled_features": tag.extra_enabled_features,
"tc_license_info_url": tag.license_info_url,
"tc_license_info_variable": tag.license_info_variable,
"tc_license_path": tag.license_path,
Expand Down Expand Up @@ -377,6 +399,8 @@ def _impl(mctx):
extra_compile_flags = toolchain_info["tc_extra_compile_flags"],
extra_c_compile_flags = toolchain_info["tc_extra_c_compile_flags"],
extra_cxx_compile_flags = toolchain_info["tc_extra_cxx_compile_flags"],
extra_known_features = toolchain_info["tc_extra_known_features"],
extra_enabled_features = toolchain_info["tc_extra_enabled_features"],
extra_link_flags = toolchain_info["tc_extra_link_flags"],
license_info_variable = toolchain_info["tc_license_info_variable"],
license_info_value = toolchain_info["tc_license_info_url"],
Expand Down
11 changes: 11 additions & 0 deletions rules/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,14 @@ def get_flag_group(flags):
),
]
return []

def label_list_to_string(input_list):
""" Small helper function to transform label list into string list

Args:
input_list (list[labels]): A list of Bazel labels.

Returns:
str: Formatted string
"""
return "[{}]".format(", ".join(["\"{}\"".format(item) for item in input_list]))
12 changes: 11 additions & 1 deletion rules/gcc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
""" Module rule for defining GCC toolchains in Bazel.
"""

load("@score_bazel_cpp_toolchains//rules:common.bzl", "SDP_VERSION_MAPPING", "get_flag_groups")
load("@score_bazel_cpp_toolchains//rules:common.bzl", "SDP_VERSION_MAPPING", "get_flag_groups", "label_list_to_string")

# Constants
_OS_QNX = "qnx"
Expand Down Expand Up @@ -71,12 +71,16 @@ cc_toolchain_config(
sysroot = "@{tc_pkg_repo}//:sysroot_dir",
target_cpu = "{tc_cpu}",
target_os = "{tc_os}",
extra_known_features = {tc_extra_known_features},
extra_enabled_features = {tc_extra_enabled_features},
visibility = ["//visibility:public"],
Comment thread
nradakovic marked this conversation as resolved.
)
""".format(
tc_pkg_repo = rctx.attr.tc_pkg_repo,
tc_cpu = rctx.attr.tc_cpu,
tc_os = rctx.attr.tc_os,
tc_extra_known_features = label_list_to_string(rctx.attr.extra_known_features),
tc_extra_enabled_features = label_list_to_string(rctx.attr.extra_enabled_features),
)

def _get_cc_config_qnx(rctx):
Expand Down Expand Up @@ -109,12 +113,16 @@ cc_toolchain_config(
cxx_builtin_include_directories = "@{tc_pkg_repo}//:cxx_builtin_include_directories",
target_cpu = "{tc_cpu}",
target_os = "{tc_os}",
extra_known_features = {tc_extra_known_features},
extra_enabled_features = {tc_extra_enabled_features},
visibility = ["//visibility:public"],
)
""".format(
tc_pkg_repo = rctx.attr.tc_pkg_repo,
tc_cpu = rctx.attr.tc_cpu,
tc_os = rctx.attr.tc_os,
tc_extra_known_features = label_list_to_string(rctx.attr.extra_known_features),
tc_extra_enabled_features = label_list_to_string(rctx.attr.extra_enabled_features),
)

def _normalize_cpu(cpu):
Expand Down Expand Up @@ -318,6 +326,8 @@ gcc_toolchain = repository_rule(
"extra_c_compile_flags": attr.string_list(doc = "Extra/Additional C-specific compile flags."),
"extra_compile_flags": attr.string_list(doc = "Extra/Additional compile flags."),
"extra_cxx_compile_flags": attr.string_list(doc = "Extra/Additional C++-specific compile flags."),
"extra_known_features": attr.label_list(doc = "Extra/Additional C++ FeatureInfo provider list"),
"extra_enabled_features": attr.label_list(doc = "Extra/Additional C++ FeatureInfo provider list enabled by default"),
"extra_link_flags": attr.string_list(doc = "Extra/Additional link flags."),
"gcc_version": attr.string(doc = "GCC version string"),
"use_base_constraints_only": attr.bool(doc = "Boolean flag to state only base constraints should be used for toolchain compatibility definition"),
Expand Down
Loading
Loading