Use OS features for Bazel controlling features (#6613)

This requires re-working our config features to be usable in
feature-level `requires` clauses in addition to `with_feature_set` by
always including all of the features, but controlling whether the
features are enabled or disabled based on the target.

This is a little more verbose in the config features, but lets us use
them more widely and is a bit more principled.
This commit is contained in:
Chandler Carruth
2026-01-16 09:26:12 +00:00
committed by GitHub
parent cd605e5ad4
commit 94d9bff541
3 changed files with 48 additions and 36 deletions
@@ -7,6 +7,7 @@
load(
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
"feature",
"feature_set",
"flag_group",
"flag_set",
)
@@ -26,6 +27,17 @@ opt_feature = feature(name = "opt")
no_legacy_features_feature = feature(name = "no_legacy_features")
supports_pic_feature = feature(name = "supports_pic", enabled = True)
supports_dynamic_linker_feature = feature(
name = "supports_dynamic_linker",
enabled = True,
requires = [feature_set(["linux_target"])],
)
supports_start_end_lib_feature = feature(
name = "supports_start_end_lib",
enabled = True,
requires = [feature_set(["linux_target"])],
)
user_flags_feature = feature(
name = "user_flags",
enabled = True,
@@ -87,4 +99,6 @@ base_features = [
no_legacy_features_feature,
opt_feature,
supports_pic_feature,
supports_dynamic_linker_feature,
supports_start_end_lib_feature,
]
@@ -15,35 +15,40 @@ load(
"feature",
)
freebsd_target_feature = feature(name = "freebsd_target", enabled = True)
linux_target_feature = feature(name = "linux_target", enabled = True)
macos_target_feature = feature(name = "macos_target", enabled = True)
windows_target_feature = feature(name = "windows_target", enabled = True)
os_names = [
"freebsd",
"linux",
"macos",
"windows",
]
os_target_features = {
"freebsd": [freebsd_target_feature],
"linux": [linux_target_feature],
"macos": [macos_target_feature],
"windows": [windows_target_feature],
def target_os_features(target_os):
if target_os not in os_names:
fail("Unsupported target OS: %s" % target_os)
return [
feature(name = os_name + "_target", enabled = os_name == target_os)
for os_name in os_names
]
cpu_names = [
"aarch64",
"x86_64",
]
# Also support canonicalizing different spellings of CPUs to one of the above
# names.
cpu_canonical_name_map = {
"aarch64": "aarch64",
"arm64": "aarch64",
"x86_64": "x86_64",
}
def target_os_features(os):
if os not in os_target_features:
fail("Unsupported target OS: %s" % os)
def target_cpu_features(target_cpu):
if target_cpu not in cpu_canonical_name_map:
fail("Unsupported target CPU: %s" % target_cpu)
target_cpu = cpu_canonical_name_map[target_cpu]
return os_target_features[os]
aarch64_target_feature = feature(name = "aarch64_target", enabled = True)
x86_64_target_feature = feature(name = "x86_64_target", enabled = True)
cpu_target_features = {
"aarch64": [aarch64_target_feature],
"arm64": [aarch64_target_feature],
"x86_64": [x86_64_target_feature],
}
def target_cpu_features(cpu):
if cpu not in cpu_target_features:
fail("Unsupported target CPU: %s" % cpu)
return cpu_target_features[cpu]
return [
feature(name = cpu_name + "_target", enabled = cpu_name == target_cpu)
for cpu_name in cpu_names
]
@@ -120,9 +120,9 @@ def _build_features(ctx):
# The order of the features determines the relative order of flags used.
features = []
features += base_features
features += target_os_features(ctx.attr.target_os)
features += target_cpu_features(ctx.attr.target_cpu)
features += base_features
features += [
# We always use Clang in the toolchain and enable all of its warnings.
clang_feature,
@@ -140,13 +140,6 @@ def _build_features(ctx):
features += debugging_features
features += linking_features
# TODO: Refactor the target-specific feature management here to be part of
# building `linking_features`.
features += [
feature(name = "supports_dynamic_linker", enabled = ctx.attr.target_os == "linux"),
feature(name = "supports_start_end_lib", enabled = ctx.attr.target_os == "linux"),
]
# Lastly, we add a feature that enables others in the default `fastbuild`
# mode. This is also a good place to add any project-specific features.
features.append(enable_in_fastbuild)