From 7a203efd18a06d9d76874441b3a4ece07ef69558 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 15 Jan 2026 00:07:23 -0800 Subject: [PATCH] Refactor handling of -std and -stdlib in toolchain (#6601) This introduces the first pieces of a cleaner way to configure toolchain components on target dimensions: dedicated features for those target dimensions. With that, we extract a `libcxx_feature` that can always be present but disables its flags on unsupported targets. With `-stdlib` in its own feature, move `-std=c++20` to not require a variable but directly live in the flags. This should enable us to extract the largest remaining feature into its own file cleanly by removing dynamic configuration of it, along with libcxx. Further refactoring of target-specific logic will follow in its footsteps. --- MODULE.bazel.lock | 2 +- .../cc_toolchain_config_features.bzl | 34 ++++++++++++ .../clang_cc_toolchain_config.bzl | 53 +++++++++++++++---- bazel/cc_toolchains/clang_configuration.bzl | 1 + 4 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 bazel/cc_toolchains/cc_toolchain_config_features.bzl diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index d760687ebc6a..bd6120a3b2fa 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -252,7 +252,7 @@ "moduleExtensions": { "//bazel/cc_toolchains:clang_configuration.bzl%clang_toolchain_extension": { "general": { - "bzlTransitiveDigest": "bboGyUY23/USpijt9AwiA8C2A4TI3wom/e7F3b5LeCI=", + "bzlTransitiveDigest": "ryYQP3j7NfvoUF+l/TDK6eiWjEfXgeBQSVVL+iS6hwc=", "usagesDigest": "lTxkeAFhR0iBEa3dg5hWvtd2HFCr5zCJx/fl27A+IKA=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, diff --git a/bazel/cc_toolchains/cc_toolchain_config_features.bzl b/bazel/cc_toolchains/cc_toolchain_config_features.bzl new file mode 100644 index 000000000000..1341b31d58df --- /dev/null +++ b/bazel/cc_toolchains/cc_toolchain_config_features.bzl @@ -0,0 +1,34 @@ +# Part of the Carbon Language project, under the Apache License v2.0 with LLVM +# Exceptions. See /LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +"""Configuration features for other features in a `cc_toolchain_config`. + +These features are designed to be used by other features in a +`cc_toolchain_config` that need to configure their behavior in some way. This +can be configuration based on either the target or host of the build, and along +multiple dimensions of each. +""" + +load( + "@rules_cc//cc:cc_toolchain_config_lib.bzl", + "feature", +) + +freebsd_target_feature = feature(name = "freebsd_target") +linux_target_feature = feature(name = "linux_target") +macos_target_feature = feature(name = "macos_target") +windows_target_feature = feature(name = "windows_target") + +os_target_features = { + "freebsd": [freebsd_target_feature], + "linux": [linux_target_feature], + "macos": [macos_target_feature], + "windows": [windows_target_feature], +} + +def target_os_features(os): + if os not in os_target_features: + fail("Unsupported target OS: %s" % os) + + return os_target_features[os] diff --git a/bazel/cc_toolchains/clang_cc_toolchain_config.bzl b/bazel/cc_toolchains/clang_cc_toolchain_config.bzl index 78563b454ff2..fee451f48997 100644 --- a/bazel/cc_toolchains/clang_cc_toolchain_config.bzl +++ b/bazel/cc_toolchains/clang_cc_toolchain_config.bzl @@ -29,6 +29,7 @@ load( "output_flags_feature", "user_flags_feature", ) +load(":cc_toolchain_config_features.bzl", "target_os_features") load(":cc_toolchain_debugging.bzl", "debugging_features") load( ":cc_toolchain_linking.bzl", @@ -65,12 +66,6 @@ load( ) def _build_features(ctx): - std_compile_flags = ["-std=c++20"] - - # libc++ is only used on non-Windows platforms. - if ctx.attr.target_os != "windows": - std_compile_flags.append("-stdlib=libc++") - # TODO: Refactor this into a reusable form in its own file. default_flags_feature = feature( name = "default_flags", @@ -92,6 +87,7 @@ def _build_features(ctx): flag_set( actions = all_compile_actions, flag_groups = [ + # First, flags for all compiles, regardless of output. flag_group(flags = [ "-Werror", "-Wall", @@ -127,6 +123,9 @@ def _build_features(ctx): # Compile actions shouldn't link anything. "-c", ]), + + # Flags controlling the production of specific outputs from + # compile actions. flag_group( expand_if_available = "output_assembly_file", flags = ["-S"], @@ -146,8 +145,11 @@ def _build_features(ctx): ], ), flag_set( - actions = all_cpp_compile_actions + all_link_actions, - flag_groups = [flag_group(flags = std_compile_flags)], + # Flags specific to compiling C++ source. + actions = all_cpp_compile_actions, + flag_groups = [flag_group(flags = [ + "-std=c++20", + ])], ), flag_set( actions = codegen_compile_actions, @@ -232,6 +234,33 @@ def _build_features(ctx): ], ) + libcxx_feature = feature( + name = "libcxx", + enabled = True, + flag_sets = [ + flag_set( + actions = all_cpp_compile_actions + all_link_actions, + flag_groups = [flag_group(flags = [ + "-stdlib=libc++", + ])], + with_features = [ + # libc++ is only used on non-Windows platforms. + with_feature_set(not_features = ["windows_target"]), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = [ + "-unwindlib=libunwind", + ])], + with_features = [ + # libc++ is only used on non-Windows platforms. + with_feature_set(not_features = ["windows_target"]), + ], + ), + ], + ) + # An enabled feature that requires the `fastbuild` compilation. This is used # to toggle general features on by default, while allowing them to be # directly enabled and disabled more generally as desired. @@ -271,8 +300,6 @@ def _build_features(ctx): flag_groups = [flag_group( flags = [ "-fuse-ld=lld", - "-stdlib=libc++", - "-unwindlib=libunwind", # Force the C++ standard library and runtime libraries # to be statically linked. This works even with libc++ # and libunwind despite the names, provided libc++ is @@ -360,7 +387,11 @@ def _build_features(ctx): # The order of the features determines the relative order of flags used. features = [] features += base_features - features.append(default_flags_feature) + features += target_os_features(ctx.attr.target_os) + features += [ + default_flags_feature, + libcxx_feature, + ] features += sanitizer_features features += optimization_features diff --git a/bazel/cc_toolchains/clang_configuration.bzl b/bazel/cc_toolchains/clang_configuration.bzl index 1a55293c6eec..2703ae100a69 100644 --- a/bazel/cc_toolchains/clang_configuration.bzl +++ b/bazel/cc_toolchains/clang_configuration.bzl @@ -264,6 +264,7 @@ configure_clang_toolchain = repository_rule( default = [ Label("//bazel/cc_toolchains:cc_toolchain_actions.bzl"), Label("//bazel/cc_toolchains:cc_toolchain_base_features.bzl"), + Label("//bazel/cc_toolchains:cc_toolchain_config_features.bzl"), Label("//bazel/cc_toolchains:cc_toolchain_debugging.bzl"), Label("//bazel/cc_toolchains:cc_toolchain_linking.bzl"), Label("//bazel/cc_toolchains:cc_toolchain_modules.bzl"),