mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:10:13 +01:00
This removes another chunk of platform-specific feature construction and simplifies the code further. Also removes a now-stale comment about adding more platform-specific features. --------- Co-authored-by: Geoff Romer <gromer@google.com>
292 lines
10 KiB
Python
292 lines
10 KiB
Python
# 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
|
|
|
|
"""A Starlark cc_toolchain configuration rule"""
|
|
|
|
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
|
|
load(
|
|
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
|
|
"feature",
|
|
"feature_set",
|
|
"flag_group",
|
|
"flag_set",
|
|
"with_feature_set",
|
|
)
|
|
load("@rules_cc//cc:defs.bzl", "cc_toolchain")
|
|
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
|
|
load(
|
|
":cc_toolchain_actions.bzl",
|
|
"all_compile_actions",
|
|
"preprocessor_compile_actions",
|
|
)
|
|
load(
|
|
":cc_toolchain_base_features.bzl",
|
|
"base_features",
|
|
"output_flags_feature",
|
|
"user_flags_feature",
|
|
)
|
|
load(":cc_toolchain_config_features.bzl", "target_os_features")
|
|
load(
|
|
":cc_toolchain_cpp_features.bzl",
|
|
"clang_feature",
|
|
"clang_warnings_feature",
|
|
"libcxx_feature",
|
|
)
|
|
load(":cc_toolchain_debugging.bzl", "debugging_features")
|
|
load(
|
|
":cc_toolchain_linking.bzl",
|
|
"default_link_libraries_feature",
|
|
"linking_features",
|
|
"macos_link_libraries_feature",
|
|
)
|
|
load(":cc_toolchain_modules.bzl", "modules_features")
|
|
load(
|
|
":cc_toolchain_optimization.bzl",
|
|
"aarch64_cpu_flags",
|
|
"optimization_features",
|
|
"x86_64_cpu_flags",
|
|
)
|
|
load(":cc_toolchain_sanitizer_features.bzl", "sanitizer_features")
|
|
load(
|
|
":cc_toolchain_tools.bzl",
|
|
"llvm_action_configs",
|
|
"llvm_tool_paths",
|
|
)
|
|
load(
|
|
":clang_detected_variables.bzl",
|
|
"clang_bindir",
|
|
"clang_include_dirs_list",
|
|
"clang_resource_dir",
|
|
"clang_version_for_cache",
|
|
"llvm_bindir",
|
|
"sysroot_dir",
|
|
)
|
|
|
|
def _build_features(ctx):
|
|
project_flags_feature = feature(
|
|
name = "project_flags",
|
|
enabled = True,
|
|
flag_sets = [
|
|
flag_set(
|
|
actions = all_compile_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
# Don't warn on external code as we can't
|
|
# necessarily patch it easily. Note that these have
|
|
# to be initial directories in the `#include` line.
|
|
"--system-header-prefix=absl/",
|
|
"--system-header-prefix=benchmark/",
|
|
"--system-header-prefix=boost/",
|
|
"--system-header-prefix=clang-tools-extra/",
|
|
"--system-header-prefix=clang/",
|
|
"--system-header-prefix=gmock/",
|
|
"--system-header-prefix=gtest/",
|
|
"--system-header-prefix=libfuzzer/",
|
|
"--system-header-prefix=llvm/",
|
|
"--system-header-prefix=re2/",
|
|
"--system-header-prefix=tools/cpp/",
|
|
"--system-header-prefix=tree_sitter/",
|
|
])],
|
|
),
|
|
flag_set(
|
|
actions = preprocessor_compile_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
# Pass the Clang version to get better Bazel caching
|
|
# behavior with system-installed Clang binaries.
|
|
"-DCLANG_VERSION_FOR_CACHE=\"%s\"" % clang_version_for_cache,
|
|
])],
|
|
),
|
|
flag_set(
|
|
actions = [
|
|
ACTION_NAMES.c_compile,
|
|
ACTION_NAMES.cpp_compile,
|
|
ACTION_NAMES.cpp_header_parsing,
|
|
ACTION_NAMES.cpp_module_compile,
|
|
],
|
|
flag_groups = [flag_group(flags = ["-DHAVE_MALLCTL"])],
|
|
with_features = [with_feature_set(["freebsd_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.
|
|
enable_in_fastbuild = feature(
|
|
name = "enable_in_fastbuild",
|
|
enabled = True,
|
|
requires = [feature_set(["fastbuild"])],
|
|
implies = [
|
|
"asan",
|
|
"asan_min_size",
|
|
"minimal_optimization_flags",
|
|
"minimal_debug_info_flags",
|
|
],
|
|
)
|
|
|
|
# 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 += [
|
|
# We always use Clang in the toolchain and enable all of its warnings.
|
|
clang_feature,
|
|
clang_warnings_feature,
|
|
# Enable libc++ where supported.
|
|
libcxx_feature(llvm_bindir, clang_bindir),
|
|
|
|
# Include any project-specific flags, importantly after the Clang and
|
|
# warnings features so we can override as necessary here.
|
|
project_flags_feature,
|
|
]
|
|
features += sanitizer_features
|
|
|
|
features += optimization_features
|
|
|
|
# TODO: Refactor target-specific feature management to be part of
|
|
# `optimization_features`.
|
|
if ctx.attr.target_cpu in ["aarch64", "arm64"]:
|
|
features.append(aarch64_cpu_flags)
|
|
else:
|
|
features.append(x86_64_cpu_flags)
|
|
|
|
features += modules_features
|
|
features += debugging_features
|
|
|
|
# Next, add the features based on the target platform. Here too the
|
|
# features are order sensitive.
|
|
if ctx.attr.target_os == "linux":
|
|
sysroot = None
|
|
elif ctx.attr.target_os == "windows":
|
|
sysroot = None
|
|
elif ctx.attr.target_os == "macos":
|
|
sysroot = sysroot_dir
|
|
elif ctx.attr.target_os == "freebsd":
|
|
sysroot = sysroot_dir
|
|
else:
|
|
fail("Unsupported target OS!")
|
|
|
|
# Next, append the libraries to link.
|
|
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"),
|
|
]
|
|
if ctx.attr.target_os == "macos":
|
|
features.append(macos_link_libraries_feature)
|
|
else:
|
|
features.append(default_link_libraries_feature)
|
|
|
|
# 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)
|
|
|
|
# Add user flags and the output flags at the end.
|
|
features.append(user_flags_feature)
|
|
features.append(output_flags_feature)
|
|
return features
|
|
|
|
def _impl(ctx):
|
|
# TODO: See if this can be refactored into platform features.
|
|
if ctx.attr.target_os == "linux":
|
|
sysroot = None
|
|
elif ctx.attr.target_os == "windows":
|
|
sysroot = None
|
|
elif ctx.attr.target_os == "macos":
|
|
sysroot = sysroot_dir
|
|
elif ctx.attr.target_os == "freebsd":
|
|
sysroot = sysroot_dir
|
|
else:
|
|
fail("Unsupported target OS!")
|
|
|
|
identifier = "local-{0}-{1}".format(ctx.attr.target_cpu, ctx.attr.target_os)
|
|
return cc_common.create_cc_toolchain_config_info(
|
|
ctx = ctx,
|
|
features = _build_features(ctx),
|
|
action_configs = llvm_action_configs(llvm_bindir, clang_bindir),
|
|
cxx_builtin_include_directories = clang_include_dirs_list + [
|
|
# Add Clang's resource directory to the end of the builtin include
|
|
# directories to cover the use of sanitizer resource files by the
|
|
# driver.
|
|
clang_resource_dir + "/share",
|
|
],
|
|
builtin_sysroot = sysroot,
|
|
|
|
# This configuration only supports local non-cross builds so derive
|
|
# everything from the target CPU selected.
|
|
toolchain_identifier = identifier,
|
|
host_system_name = identifier,
|
|
target_system_name = identifier,
|
|
target_cpu = ctx.attr.target_cpu,
|
|
|
|
# This is used to expose a "flag" that `config_setting` rules can use to
|
|
# determine if the compiler is Clang.
|
|
compiler = "clang",
|
|
|
|
# These attributes aren't meaningful at all so just use placeholder
|
|
# values.
|
|
target_libc = "local",
|
|
abi_version = "local",
|
|
abi_libc_version = "local",
|
|
|
|
# We do have to pass in our tool paths.
|
|
tool_paths = llvm_tool_paths(llvm_bindir, clang_bindir),
|
|
)
|
|
|
|
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, configs):
|
|
"""Create a toolchain suite that uses the local Clang/LLVM install.
|
|
|
|
Args:
|
|
name: The name of the toolchain suite to produce.
|
|
configs: An array of (os, cpu) pairs to support in the toolchain.
|
|
"""
|
|
|
|
# An empty filegroup to use when stubbing out the toolchains.
|
|
native.filegroup(
|
|
name = name + "_empty",
|
|
srcs = [],
|
|
)
|
|
|
|
# Create the individual local toolchains for each CPU.
|
|
for (os, cpu) in configs:
|
|
config_name = "{0}_{1}_{2}".format(name, os, cpu)
|
|
cc_toolchain_config(
|
|
name = config_name + "_config",
|
|
target_os = os,
|
|
target_cpu = cpu,
|
|
)
|
|
cc_toolchain(
|
|
name = config_name + "_tools",
|
|
all_files = ":" + name + "_empty",
|
|
ar_files = ":" + name + "_empty",
|
|
as_files = ":" + name + "_empty",
|
|
compiler_files = ":" + name + "_empty",
|
|
dwp_files = ":" + name + "_empty",
|
|
linker_files = ":" + name + "_empty",
|
|
objcopy_files = ":" + name + "_empty",
|
|
strip_files = ":" + name + "_empty",
|
|
supports_param_files = 1,
|
|
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",
|
|
)
|