Эх сурвалжийг харах

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.
Chandler Carruth 3 сар өмнө
parent
commit
7a203efd18

+ 1 - 1
MODULE.bazel.lock

@@ -252,7 +252,7 @@
   "moduleExtensions": {
   "moduleExtensions": {
     "//bazel/cc_toolchains:clang_configuration.bzl%clang_toolchain_extension": {
     "//bazel/cc_toolchains:clang_configuration.bzl%clang_toolchain_extension": {
       "general": {
       "general": {
-        "bzlTransitiveDigest": "bboGyUY23/USpijt9AwiA8C2A4TI3wom/e7F3b5LeCI=",
+        "bzlTransitiveDigest": "ryYQP3j7NfvoUF+l/TDK6eiWjEfXgeBQSVVL+iS6hwc=",
         "usagesDigest": "lTxkeAFhR0iBEa3dg5hWvtd2HFCr5zCJx/fl27A+IKA=",
         "usagesDigest": "lTxkeAFhR0iBEa3dg5hWvtd2HFCr5zCJx/fl27A+IKA=",
         "recordedFileInputs": {},
         "recordedFileInputs": {},
         "recordedDirentsInputs": {},
         "recordedDirentsInputs": {},

+ 34 - 0
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]

+ 42 - 11
bazel/cc_toolchains/clang_cc_toolchain_config.bzl

@@ -29,6 +29,7 @@ load(
     "output_flags_feature",
     "output_flags_feature",
     "user_flags_feature",
     "user_flags_feature",
 )
 )
+load(":cc_toolchain_config_features.bzl", "target_os_features")
 load(":cc_toolchain_debugging.bzl", "debugging_features")
 load(":cc_toolchain_debugging.bzl", "debugging_features")
 load(
 load(
     ":cc_toolchain_linking.bzl",
     ":cc_toolchain_linking.bzl",
@@ -65,12 +66,6 @@ load(
 )
 )
 
 
 def _build_features(ctx):
 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.
     # TODO: Refactor this into a reusable form in its own file.
     default_flags_feature = feature(
     default_flags_feature = feature(
         name = "default_flags",
         name = "default_flags",
@@ -92,6 +87,7 @@ def _build_features(ctx):
             flag_set(
             flag_set(
                 actions = all_compile_actions,
                 actions = all_compile_actions,
                 flag_groups = [
                 flag_groups = [
+                    # First, flags for all compiles, regardless of output.
                     flag_group(flags = [
                     flag_group(flags = [
                         "-Werror",
                         "-Werror",
                         "-Wall",
                         "-Wall",
@@ -127,6 +123,9 @@ def _build_features(ctx):
                         # Compile actions shouldn't link anything.
                         # Compile actions shouldn't link anything.
                         "-c",
                         "-c",
                     ]),
                     ]),
+
+                    # Flags controlling the production of specific outputs from
+                    # compile actions.
                     flag_group(
                     flag_group(
                         expand_if_available = "output_assembly_file",
                         expand_if_available = "output_assembly_file",
                         flags = ["-S"],
                         flags = ["-S"],
@@ -146,8 +145,11 @@ def _build_features(ctx):
                 ],
                 ],
             ),
             ),
             flag_set(
             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(
             flag_set(
                 actions = codegen_compile_actions,
                 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
     # An enabled feature that requires the `fastbuild` compilation. This is used
     # to toggle general features on by default, while allowing them to be
     # to toggle general features on by default, while allowing them to be
     # directly enabled and disabled more generally as desired.
     # directly enabled and disabled more generally as desired.
@@ -271,8 +300,6 @@ def _build_features(ctx):
                 flag_groups = [flag_group(
                 flag_groups = [flag_group(
                     flags = [
                     flags = [
                         "-fuse-ld=lld",
                         "-fuse-ld=lld",
-                        "-stdlib=libc++",
-                        "-unwindlib=libunwind",
                         # Force the C++ standard library and runtime libraries
                         # Force the C++ standard library and runtime libraries
                         # to be statically linked. This works even with libc++
                         # to be statically linked. This works even with libc++
                         # and libunwind despite the names, provided libc++ is
                         # 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.
     # The order of the features determines the relative order of flags used.
     features = []
     features = []
     features += base_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 += sanitizer_features
 
 
     features += optimization_features
     features += optimization_features

+ 1 - 0
bazel/cc_toolchains/clang_configuration.bzl

@@ -264,6 +264,7 @@ configure_clang_toolchain = repository_rule(
             default = [
             default = [
                 Label("//bazel/cc_toolchains:cc_toolchain_actions.bzl"),
                 Label("//bazel/cc_toolchains:cc_toolchain_actions.bzl"),
                 Label("//bazel/cc_toolchains:cc_toolchain_base_features.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_debugging.bzl"),
                 Label("//bazel/cc_toolchains:cc_toolchain_linking.bzl"),
                 Label("//bazel/cc_toolchains:cc_toolchain_linking.bzl"),
                 Label("//bazel/cc_toolchains:cc_toolchain_modules.bzl"),
                 Label("//bazel/cc_toolchains:cc_toolchain_modules.bzl"),