Skip to content

Commit 2c1935b

Browse files
committed
Add feature injection
Add feature injection to toolchain gcc extension. This option will allow users to add external defined features.
1 parent b91ee4a commit 2c1935b

9 files changed

Lines changed: 153 additions & 197 deletions

File tree

docs/extension_api.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ Flag and runtime attributes:
7272
- `extra_c_compile_flags`
7373
- `extra_cxx_compile_flags`
7474
- `extra_link_flags`
75+
- `extra_known_features`
76+
- `extra_enabled_features`
7577
- `ld_library_paths`
7678
- `runtime_ecosystem`
7779
- `use_base_constraints_only`
@@ -93,6 +95,21 @@ attributes are:
9395
- `sha256`: sha256 of the archive
9496
- `strip_prefix`: extraction prefix for packaged archives
9597

98+
## Feature Injection
99+
100+
`extra_known_features` and `extra_enabled_features` let a workspace add
101+
rule-based `cc_feature` targets (defined outside this repository) to the
102+
generated toolchain:
103+
104+
- `extra_known_features` — registers external features so they can be toggled
105+
per target via the `features` attribute or build-wide via `--features`.
106+
- `extra_enabled_features` — registers *and* enables external features by
107+
default.
108+
109+
Sanitizers are the primary use case: they are defined by the
110+
`score_cpp_policies` module and brought into the toolchain through these
111+
attributes. See [Toolchain features](features.md#sanitizers-linux-opt-in).
112+
96113

97114
## Activation In A Workspace
98115

@@ -120,5 +137,10 @@ behavior explicitly, see the
120137
- The extension is intended for the root module.
121138
- When `use_default_package` is enabled, the version matrix can inject extra
122139
include and link flags required by non-standard sysroot layouts.
140+
- Sanitizer features are not registered automatically. They are defined by the
141+
`score_cpp_policies` module and made available through *feature injection*
142+
the `extra_known_features` / `extra_enabled_features` attributes on
143+
`gcc.toolchain(...)`. See [Toolchain features](features.md#sanitizers-linux-opt-in)
144+
for the injected feature names.
123145
- QNX toolchains use additional licensing and include-path parameters that do
124146
not apply to Linux toolchains.

docs/features.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,18 @@ Opt-in / disabled by default unless noted otherwise.
9696
- **`warnings_as_errors`** (both) — Adds `-Werror`.
9797

9898
## Sanitizers (Linux, opt-in)
99-
- **`sanitizer`** — Base sanitizer feature.
100-
- **`asan`** / **`lsan`** / **`tsan`** / **`ubsan`** — Address / Leak / Thread /
101-
Undefined-Behavior sanitizers; each implies `sanitizer`.
99+
Sanitizers are **not** defined by this toolchain. They are provided as
100+
rule-based `cc_feature` definitions by the `score_cpp_policies` module and made
101+
available through *feature injection* — the `extra_known_features` /
102+
`extra_enabled_features` attributes on `gcc.toolchain(...)`. Once injected they
103+
behave like any other opt-in feature.
104+
105+
- **`score_asan`** — AddressSanitizer (`-fsanitize=address`).
106+
- **`score_lsan`** — LeakSanitizer (`-fsanitize=leak`).
107+
- **`score_tsan`** — ThreadSanitizer (`-fsanitize=thread`).
108+
- **`score_ubsan`** — UndefinedBehaviorSanitizer (`-fsanitize=undefined`).
109+
110+
See the `score_cpp_policies` documentation for the authoritative list and usage.
102111

103112
## Threading
104113
- **`use_pthread`** (Linux) — Links with `-pthread`.

docs/migration_guide.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,26 @@ toolchain, are summarized below.
9797
| `gcov` | **Supported, wiring** | `tool_paths` (`gcov_wrapper`) |
9898
| 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. |
9999
| `-Werror` | **Not implicit — opt-in** | `warnings_as_errors` (disabled by default) |
100-
| Sanitizers (asan/lsan/tsan/ubsan) | **Not implicit — opt-in (Linux)** | `asan` / `lsan` / `tsan` / `ubsan` (disabled by default) |
100+
| 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` |
101101
| Fully static link (`-static`) | **Not implicit — opt-in** | `fully_static_link` (disabled by default) |
102102
| `-pthread` | **Not implicit — opt-in (Linux)** | `use_pthread` (disabled by default) |
103103
| Fission / split DWARF, linkstamps, strip, static-libgcc | **Supported, guarded** | Guarded features; no-ops until the relevant build mode is active |
104104
| Any other Bazel legacy default not listed above | **Not available** | Must be added explicitly (see below) |
105105

106-
Two categories deserve special attention because they are the most frequent
106+
Three categories deserve special attention because they are the most frequent
107107
migration surprises:
108108

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

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

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

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

extensions/gcc.bzl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,26 @@ _attrs_tc = {
7878
default = [],
7979
doc = "List of additional flags to be passed to linker.",
8080
),
81+
"extra_enabled_features": attr.label_list(
82+
mandatory = False,
83+
default = [],
84+
doc = ("Extra `cc_feature` features to add to this toolchain in an initially " +
85+
"enabled state. This attribute has limited integration with `cc_feature`, " +
86+
"and does not run additional correctness checks or handle things like `data` " +
87+
"files. This is only offered as a migration bridge for projects transitioning " +
88+
"to rule-based toolchain configurations, or sharing of simple argument sets " +
89+
"with older toolchains."),
90+
),
91+
"extra_known_features": attr.label_list(
92+
mandatory = False,
93+
default = [],
94+
doc = ("Extra `cc_feature` features to add to this toolchain in an initially " +
95+
"disabled state. This attribute has limited integration with `cc_feature`, " +
96+
"and does not run additional correctness checks or handle things like `data` " +
97+
"files. This is only offered as a migration bridge for projects transitioning " +
98+
"to rule-based toolchain configurations, or sharing of simple argument sets " +
99+
"with older toolchains."),
100+
),
81101
"license_info_url": attr.string(
82102
default = "",
83103
mandatory = False,
@@ -197,6 +217,8 @@ def _get_toolchains(tags):
197217
"tc_extra_compile_flags": tag.extra_compile_flags,
198218
"tc_extra_cxx_compile_flags": tag.extra_cxx_compile_flags,
199219
"tc_extra_link_flags": tag.extra_link_flags,
220+
"tc_extra_known_features": tag.extra_known_features,
221+
"tc_extra_enabled_features": tag.extra_enabled_features,
200222
"tc_license_info_url": tag.license_info_url,
201223
"tc_license_info_variable": tag.license_info_variable,
202224
"tc_license_path": tag.license_path,
@@ -377,6 +399,8 @@ def _impl(mctx):
377399
extra_compile_flags = toolchain_info["tc_extra_compile_flags"],
378400
extra_c_compile_flags = toolchain_info["tc_extra_c_compile_flags"],
379401
extra_cxx_compile_flags = toolchain_info["tc_extra_cxx_compile_flags"],
402+
extra_known_features = toolchain_info["tc_extra_known_features"],
403+
extra_enabled_features = toolchain_info["tc_extra_enabled_features"],
380404
extra_link_flags = toolchain_info["tc_extra_link_flags"],
381405
license_info_variable = toolchain_info["tc_license_info_variable"],
382406
license_info_value = toolchain_info["tc_license_info_url"],

rules/common.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,14 @@ def get_flag_group(flags):
5151
),
5252
]
5353
return []
54+
55+
def label_list_to_string(input_list):
56+
""" Small helper function to transform label list into string list
57+
58+
Args:
59+
input_list (list[labels]): A list of Bazel labels.
60+
61+
Return:
62+
str: Formated string
63+
"""
64+
return "[{}]".format(", ".join(["\"{}\"".format(item) for item in input_list]))

rules/gcc.bzl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
""" Module rule for defining GCC toolchains in Bazel.
1515
"""
1616

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

1919
# Constants
2020
_OS_QNX = "qnx"
@@ -71,12 +71,16 @@ cc_toolchain_config(
7171
sysroot = "@{tc_pkg_repo}//:sysroot_dir",
7272
target_cpu = "{tc_cpu}",
7373
target_os = "{tc_os}",
74+
extra_known_features = {tc_extra_known_features},
75+
extra_enabled_features = {tc_extra_enabled_features},
7476
visibility = ["//visibility:public"],
7577
)
7678
""".format(
7779
tc_pkg_repo = rctx.attr.tc_pkg_repo,
7880
tc_cpu = rctx.attr.tc_cpu,
7981
tc_os = rctx.attr.tc_os,
82+
tc_extra_known_features = label_list_to_string(rctx.attr.extra_known_features),
83+
tc_extra_enabled_features = label_list_to_string(rctx.attr.extra_enabled_features),
8084
)
8185

8286
def _get_cc_config_qnx(rctx):
@@ -109,12 +113,16 @@ cc_toolchain_config(
109113
cxx_builtin_include_directories = "@{tc_pkg_repo}//:cxx_builtin_include_directories",
110114
target_cpu = "{tc_cpu}",
111115
target_os = "{tc_os}",
116+
extra_known_features = {tc_extra_known_features},
117+
extra_enabled_features = {tc_extra_enabled_features},
112118
visibility = ["//visibility:public"],
113119
)
114120
""".format(
115121
tc_pkg_repo = rctx.attr.tc_pkg_repo,
116122
tc_cpu = rctx.attr.tc_cpu,
117123
tc_os = rctx.attr.tc_os,
124+
tc_extra_known_features = label_list_to_string(rctx.attr.extra_known_features),
125+
tc_extra_enabled_features = label_list_to_string(rctx.attr.extra_enabled_features),
118126
)
119127

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

0 commit comments

Comments
 (0)