Skip to content

Commit

Permalink
Update cc_toolchain configuration to be compatible with bazel 7. (car…
Browse files Browse the repository at this point in the history
…bon-language#3496)

Co-authored-by: Jon Ross-Perkins <[email protected]>
  • Loading branch information
zygoloid and jonmeow committed Dec 12, 2023
1 parent 6cc5dc7 commit 23a02ac
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 48 deletions.
15 changes: 8 additions & 7 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
65 changes: 34 additions & 31 deletions bazel/cc_toolchains/clang_cc_toolchain_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 = [
Expand All @@ -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.
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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",
Expand All @@ -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 changes: 14 additions & 0 deletions bazel/cc_toolchains/clang_configs.bzl
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions bazel/cc_toolchains/clang_configuration.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand All @@ -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),
)
10 changes: 2 additions & 8 deletions bazel/cc_toolchains/clang_toolchain.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)

0 comments on commit 23a02ac

Please sign in to comment.