Просмотр исходного кода

Update cc_toolchain configuration to be compatible with bazel 7. (#3496)

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Richard Smith 2 лет назад
Родитель
Сommit
23a02ac0d9

+ 8 - 7
.bazelrc

@@ -2,17 +2,10 @@
 # Exceptions. See /LICENSE for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-# TODO: Get a better toolchain fix for
-# https://github.com/bazelbuild/bazel/issues/7260
-build --noincompatible_enable_cc_toolchain_resolution
-
 # TODO: https://bazel.build/external/migration for
 # https://github.com/bazelbuild/bazel/issues/18958
 build --noenable_bzlmod
 
-build --crosstool_top=@bazel_cc_toolchain
-build --host_crosstool_top=@bazel_cc_toolchain
-
 # Default to using a disk cache to minimize re-building LLVM and Clang which we
 # try to avoid updating too frequently to minimize rebuild cost. The location
 # here can be overridden in the user configuration where needed.
@@ -35,8 +28,16 @@ build --experimental_guard_against_concurrent_changes
 #
 # Bazel bug tracking undoing the default here:
 # https://github.com/bazelbuild/bazel/issues/13315
+#
+# TODO: Remove this once we require at least Bazel version 7, where
+# --incompatible_use_host_features is the default.
 build --incompatible_dont_enable_host_nonhost_crosstool_features=false
 
+# Opt into the new Bazel toolchain resolution mechanism.
+# TODO: Remove this once we require at least Bazel version 7, where it is the
+# default.
+build --incompatible_enable_cc_toolchain_resolution
+
 # Disable warnings for all external compilations. These involve code that isn't
 # developed as part of Carbon and may be difficult or impossible to patch, so
 # warnings aren't likely to be actionable.

+ 2 - 2
WORKSPACE

@@ -62,10 +62,10 @@ install_deps()
 # Configure the bootstrapped Clang and LLVM toolchain for Bazel.
 load(
     "//bazel/cc_toolchains:clang_configuration.bzl",
-    "configure_clang_toolchain",
+    "clang_register_toolchains",
 )
 
-configure_clang_toolchain(name = "bazel_cc_toolchain")
+clang_register_toolchains(name = "bazel_cc_toolchain")
 
 ###############################################################################
 # Abseil libraries

+ 34 - 31
bazel/cc_toolchains/clang_cc_toolchain_config.bzl

@@ -17,7 +17,7 @@ load(
     "variable_with_value",
     "with_feature_set",
 )
-load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite")
+load("@rules_cc//cc:defs.bzl", "cc_toolchain")
 load(
     ":clang_detected_variables.bzl",
     "clang_bindir",
@@ -103,7 +103,7 @@ def _impl(ctx):
     std_compile_flags = ["-std=c++17"]
 
     # libc++ is only used on non-Windows platforms.
-    if ctx.attr.target_cpu != "x64_windows":
+    if ctx.attr.target_os != "windows":
         std_compile_flags.append("-stdlib=libc++")
 
     # TODO: Regression that warns on anonymous unions; remove depending on fix.
@@ -977,10 +977,7 @@ def _impl(ctx):
     )
 
     # Now that we have built up the constituent feature definitions, compose
-    # them, including configuration based on the target platform. Currently,
-    # the target platform is configured with the "cpu" attribute for legacy
-    # reasons. Further, for legacy reasons the default is a Linux OS target and
-    # the x88-64 CPU name is "k8".
+    # them, including configuration based on the target platform.
 
     # First, define features that are simply used to configure others.
     features = [
@@ -990,9 +987,9 @@ def _impl(ctx):
         feature(name = "no_legacy_features"),
         feature(name = "nonhost"),
         feature(name = "opt"),
-        feature(name = "supports_dynamic_linker", enabled = ctx.attr.target_cpu == "k8"),
+        feature(name = "supports_dynamic_linker", enabled = ctx.attr.target_os == "linux"),
         feature(name = "supports_pic", enabled = True),
-        feature(name = "supports_start_end_lib", enabled = ctx.attr.target_cpu == "k8"),
+        feature(name = "supports_start_end_lib", enabled = ctx.attr.target_os == "linux"),
     ]
 
     # The order of the features determines the relative order of flags used.
@@ -1017,38 +1014,39 @@ def _impl(ctx):
 
     # Next, add the features based on the target platform. Here too the
     # features are order sensitive. We also setup the sysroot here.
-    if ctx.attr.target_cpu in ["aarch64", "k8"]:
+    if ctx.attr.target_os == "linux":
         features.append(sanitizer_static_lib_flags)
         features.append(linux_flags_feature)
         sysroot = None
-    elif ctx.attr.target_cpu == "x64_windows":
+    elif ctx.attr.target_os == "windows":
         # TODO: Need to figure out if we need to add windows specific features
         # I think the .pdb debug files will need to be handled differently,
         # so that might be an example where a feature must be added.
         sysroot = None
-    elif ctx.attr.target_cpu in ["darwin", "darwin_arm64"]:
+    elif ctx.attr.target_os == "macos":
         features.append(macos_asan_workarounds)
         features.append(macos_flags_feature)
         sysroot = sysroot_dir
-    elif ctx.attr.target_cpu == "freebsd":
+    elif ctx.attr.target_os == "freebsd":
         features.append(sanitizer_static_lib_flags)
         features.append(freebsd_flags_feature)
         sysroot = sysroot_dir
     else:
-        fail("Unsupported target platform!")
+        fail("Unsupported target OS!")
 
-    if ctx.attr.target_cpu in ["aarch64", "darwin_arm64"]:
+    if ctx.attr.target_cpu in ["aarch64", "arm64"]:
         features.append(aarch64_cpu_flags)
     else:
         features.append(x86_64_cpu_flags)
 
     # Finally append the libraries to link and any final flags.
-    if ctx.attr.target_cpu in ["darwin", "darwin_arm64"]:
+    if ctx.attr.target_os == "macos":
         features.append(macos_link_libraries_feature)
     else:
         features.append(default_link_libraries_feature)
     features.append(final_flags_feature)
 
+    identifier = "local-{0}-{1}".format(ctx.attr.target_cpu, ctx.attr.target_os)
     return cc_common.create_cc_toolchain_config_info(
         ctx = ctx,
         features = features,
@@ -1062,9 +1060,9 @@ def _impl(ctx):
 
         # This configuration only supports local non-cross builds so derive
         # everything from the target CPU selected.
-        toolchain_identifier = "local-" + ctx.attr.target_cpu,
-        host_system_name = "local-" + ctx.attr.target_cpu,
-        target_system_name = "local-" + ctx.attr.target_cpu,
+        toolchain_identifier = identifier,
+        host_system_name = identifier,
+        target_system_name = identifier,
         target_cpu = ctx.attr.target_cpu,
 
         # These attributes aren't meaningful at all so just use placeholder
@@ -1082,16 +1080,17 @@ cc_toolchain_config = rule(
     implementation = _impl,
     attrs = {
         "target_cpu": attr.string(mandatory = True),
+        "target_os": attr.string(mandatory = True),
     },
     provides = [CcToolchainConfigInfo],
 )
 
-def cc_local_toolchain_suite(name, cpus):
+def cc_local_toolchain_suite(name, configs):
     """Create a toolchain suite that uses the local Clang/LLVM install.
 
     Args:
         name: The name of the toolchain suite to produce.
-        cpus: An array of CPU strings to support in the toolchain.
+        configs: An array of (os, cpu) pairs to support in the toolchain.
     """
 
     # An empty filegroup to use when stubbing out the toolchains.
@@ -1101,13 +1100,15 @@ def cc_local_toolchain_suite(name, cpus):
     )
 
     # Create the individual local toolchains for each CPU.
-    for cpu in cpus:
+    for (os, cpu) in configs:
+        config_name = "{0}_{1}_{2}".format(name, os, cpu)
         cc_toolchain_config(
-            name = name + "_local_config_" + cpu,
+            name = config_name + "_config",
+            target_os = os,
             target_cpu = cpu,
         )
         cc_toolchain(
-            name = name + "_local_" + cpu,
+            name = config_name + "_tools",
             all_files = ":" + name + "_empty",
             ar_files = ":" + name + "_empty",
             as_files = ":" + name + "_empty",
@@ -1117,12 +1118,14 @@ def cc_local_toolchain_suite(name, cpus):
             objcopy_files = ":" + name + "_empty",
             strip_files = ":" + name + "_empty",
             supports_param_files = 1,
-            toolchain_config = ":" + name + "_local_config_" + cpu,
-            toolchain_identifier = name + "_local_" + cpu,
+            toolchain_config = ":" + config_name + "_config",
+            toolchain_identifier = config_name,
+        )
+        compatible_with = ["@platforms//cpu:" + cpu, "@platforms//os:" + os]
+        native.toolchain(
+            name = config_name,
+            exec_compatible_with = compatible_with,
+            target_compatible_with = compatible_with,
+            toolchain = config_name + "_tools",
+            toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
         )
-
-    # Now build the suite, associating each CPU with its toolchain.
-    cc_toolchain_suite(
-        name = name,
-        toolchains = {cpu: ":" + name + "_local_" + cpu for cpu in cpus},
-    )

+ 14 - 0
bazel/cc_toolchains/clang_configs.bzl

@@ -0,0 +1,14 @@
+# 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
+
+"""Lists (os, cpu) combinations supported by the Carbon build system."""
+
+clang_configs = [
+    ("linux", "aarch64"),
+    ("linux", "x86_64"),
+    ("freebsd", "x86_64"),
+    ("macos", "arm64"),
+    ("macos", "x86_64"),
+    ("windows", "x86_64"),
+]

+ 18 - 0
bazel/cc_toolchains/clang_configuration.bzl

@@ -9,6 +9,8 @@ configured values into a `clang_detected_variables.bzl` file that can be used
 by the actual toolchain configuration.
 """
 
+load(":clang_configs.bzl", "clang_configs")
+
 def _run(repository_ctx, cmd):
     """Runs the provided `cmd`, checks for failure, and returns the result."""
     exec_result = repository_ctx.execute(cmd)
@@ -168,6 +170,10 @@ def _configure_clang_toolchain_impl(repository_ctx):
         repository_ctx.attr._clang_cc_toolchain_config,
         "cc_toolchain_config.bzl",
     )
+    repository_ctx.symlink(
+        repository_ctx.attr._clang_configs,
+        "clang_configs.bzl",
+    )
 
     # Find a Clang C++ compiler, and where it lives. We need to walk symlinks
     # here as the other LLVM tools may not be symlinked into the PATH even if
@@ -237,6 +243,10 @@ configure_clang_toolchain = repository_rule(
             ),
             allow_single_file = True,
         ),
+        "_clang_configs": attr.label(
+            default = Label("//bazel/cc_toolchains:clang_configs.bzl"),
+            allow_single_file = True,
+        ),
         "_clang_detected_variables_template": attr.label(
             default = Label(
                 "//bazel/cc_toolchains:clang_detected_variables.tpl.bzl",
@@ -250,3 +260,11 @@ configure_clang_toolchain = repository_rule(
     },
     environ = ["CC"],
 )
+
+def clang_register_toolchains(name):
+    configure_clang_toolchain(name = name)
+
+    for os, cpu in clang_configs:
+        native.register_toolchains(
+            "@{0}//:bazel_cc_toolchain_{1}_{2}".format(name, os, cpu),
+        )

+ 2 - 8
bazel/cc_toolchains/clang_toolchain.BUILD

@@ -6,15 +6,9 @@
 # root `BUILD` file for that repository.
 
 load(":cc_toolchain_config.bzl", "cc_local_toolchain_suite")
+load(":clang_configs.bzl", "clang_configs")
 
 cc_local_toolchain_suite(
     name = "bazel_cc_toolchain",
-    cpus = [
-        "aarch64",
-        "darwin",
-        "darwin_arm64",
-        "freebsd",
-        "k8",
-        "x64_windows",
-    ],
+    configs = clang_configs,
 )