|
|
@@ -9,20 +9,86 @@ load(
|
|
|
"clang_include_dirs",
|
|
|
"clang_sysroot",
|
|
|
)
|
|
|
+load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
|
|
|
+load(
|
|
|
+ "@rules_cc//cc:cc_toolchain_config_lib.bzl",
|
|
|
+ "action_config",
|
|
|
+ "flag_group",
|
|
|
+ "flag_set",
|
|
|
+ "tool",
|
|
|
+)
|
|
|
load(
|
|
|
"@rules_cc//cc:defs.bzl",
|
|
|
"CcToolchainConfigInfo",
|
|
|
"cc_toolchain",
|
|
|
)
|
|
|
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
|
|
|
+load("//bazel:runtimes_build_vars.bzl", "llvm_version_major")
|
|
|
+load(
|
|
|
+ ":cc_toolchain_actions.bzl",
|
|
|
+ "all_c_compile_actions",
|
|
|
+ "all_cpp_compile_actions",
|
|
|
+ "all_link_actions",
|
|
|
+)
|
|
|
load(":cc_toolchain_features.bzl", "clang_cc_toolchain_features")
|
|
|
load(
|
|
|
":cc_toolchain_tools.bzl",
|
|
|
- "llvm_action_configs",
|
|
|
"llvm_tool_paths",
|
|
|
)
|
|
|
|
|
|
-def _impl(ctx):
|
|
|
+def _make_action_configs(runtimes_path = None):
|
|
|
+ runtimes_flag = "--no-build-runtimes"
|
|
|
+ if runtimes_path:
|
|
|
+ runtimes_flag = "--prebuilt-runtimes={0}".format(runtimes_path)
|
|
|
+
|
|
|
+ return [
|
|
|
+ action_config(
|
|
|
+ action_name = name,
|
|
|
+ enabled = True,
|
|
|
+ tools = [tool(path = "llvm/bin/clang")],
|
|
|
+ )
|
|
|
+ for name in all_c_compile_actions
|
|
|
+ ] + [
|
|
|
+ action_config(
|
|
|
+ action_name = name,
|
|
|
+ enabled = True,
|
|
|
+ tools = [tool(path = "llvm/bin/clang++")],
|
|
|
+ )
|
|
|
+ for name in all_cpp_compile_actions
|
|
|
+ ] + [
|
|
|
+ action_config(
|
|
|
+ action_name = name,
|
|
|
+ enabled = True,
|
|
|
+ tools = [tool(path = "carbon-busybox")],
|
|
|
+ flag_sets = [flag_set(flag_groups = [flag_group(flags = [
|
|
|
+ runtimes_flag,
|
|
|
+ "link",
|
|
|
+ # We want to allow Bazel to intermingle linked object files and
|
|
|
+ # Clang-spelled link flags. The first `--` starts the list of
|
|
|
+ # initial object files by ending flags to the `link` subcommand,
|
|
|
+ # and the second `--` switches to Clang-spelled flags.
|
|
|
+ "--",
|
|
|
+ "--",
|
|
|
+ ])])],
|
|
|
+ )
|
|
|
+ for name in all_link_actions
|
|
|
+ ] + [
|
|
|
+ action_config(
|
|
|
+ action_name = name,
|
|
|
+ enabled = True,
|
|
|
+ tools = [tool(path = "llvm/bin/llvm-ar")],
|
|
|
+ )
|
|
|
+ for name in [ACTION_NAMES.cpp_link_static_library]
|
|
|
+ ] + [
|
|
|
+ action_config(
|
|
|
+ action_name = name,
|
|
|
+ enabled = True,
|
|
|
+ tools = [tool(path = "llvm/bin/llvm-strip")],
|
|
|
+ )
|
|
|
+ for name in [ACTION_NAMES.strip]
|
|
|
+ ]
|
|
|
+
|
|
|
+def _carbon_cc_toolchain_config_impl(ctx):
|
|
|
# Hard code the the repository-relative path of the LLVM (and Clang)
|
|
|
# binaries as it is a fixed aspect of the install structure.
|
|
|
llvm_bindir = "llvm/bin"
|
|
|
@@ -32,14 +98,28 @@ def _impl(ctx):
|
|
|
if clang_sysroot != "None" and clang_sysroot != "/":
|
|
|
builtin_sysroot = clang_sysroot
|
|
|
|
|
|
- identifier = "carbon-toolchain-{0}-{1}".format(ctx.attr.target_cpu, ctx.attr.target_os)
|
|
|
+ runtimes_path = None
|
|
|
+ if ctx.attr.runtimes:
|
|
|
+ for f in ctx.files.runtimes:
|
|
|
+ if f.basename == "runtimes_root":
|
|
|
+ runtimes_path = f.dirname
|
|
|
+ break
|
|
|
+ if not runtimes_path:
|
|
|
+ fail("Unable to compute the runtimes path for: {0}".format(
|
|
|
+ ctx.attr.runtimes,
|
|
|
+ ))
|
|
|
+
|
|
|
+ identifier = "carbon-toolchain-{0}-{1}".format(
|
|
|
+ ctx.attr.target_cpu,
|
|
|
+ ctx.attr.target_os,
|
|
|
+ )
|
|
|
return cc_common.create_cc_toolchain_config_info(
|
|
|
ctx = ctx,
|
|
|
features = clang_cc_toolchain_features(
|
|
|
target_os = ctx.attr.target_os,
|
|
|
target_cpu = ctx.attr.target_cpu,
|
|
|
),
|
|
|
- action_configs = llvm_action_configs(llvm_bindir),
|
|
|
+ action_configs = _make_action_configs(runtimes_path),
|
|
|
cxx_builtin_include_directories = clang_include_dirs,
|
|
|
builtin_sysroot = builtin_sysroot,
|
|
|
|
|
|
@@ -56,56 +136,184 @@ def _impl(ctx):
|
|
|
)
|
|
|
|
|
|
carbon_cc_toolchain_config = rule(
|
|
|
- implementation = _impl,
|
|
|
+ implementation = _carbon_cc_toolchain_config_impl,
|
|
|
attrs = {
|
|
|
+ "runtimes": attr.label(mandatory = False),
|
|
|
"target_cpu": attr.string(mandatory = True),
|
|
|
"target_os": attr.string(mandatory = True),
|
|
|
},
|
|
|
provides = [CcToolchainConfigInfo],
|
|
|
)
|
|
|
|
|
|
-def carbon_cc_toolchain_suite(name, configs):
|
|
|
+def _runtimes_transition_impl(_, attr):
|
|
|
+ # Adjust the platform to the runtimes platform across the transition.
|
|
|
+ return {"//command_line_option:platforms": [str(attr.runtimes_platform)]}
|
|
|
+
|
|
|
+runtimes_transition = transition(
|
|
|
+ inputs = [],
|
|
|
+ outputs = ["//command_line_option:platforms"],
|
|
|
+ implementation = _runtimes_transition_impl,
|
|
|
+)
|
|
|
+
|
|
|
+def _runtimes_filegroup_impl(ctx):
|
|
|
+ return [DefaultInfo(files = depset(ctx.files.srcs))]
|
|
|
+
|
|
|
+runtimes_filegroup = rule(
|
|
|
+ implementation = _runtimes_filegroup_impl,
|
|
|
+ attrs = {
|
|
|
+ # The platform to use when building the runtimes.
|
|
|
+ "runtimes_platform": attr.label(mandatory = True),
|
|
|
+
|
|
|
+ # Mark that our dependencies are built through a transition.
|
|
|
+ "srcs": attr.label_list(mandatory = True, cfg = runtimes_transition),
|
|
|
+
|
|
|
+ # Enable transitions in this rule.
|
|
|
+ "_allowlist_function_transition": attr.label(
|
|
|
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
|
|
|
+ ),
|
|
|
+ },
|
|
|
+)
|
|
|
+
|
|
|
+def carbon_cc_toolchain_suite(name, platforms):
|
|
|
"""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.
|
|
|
+ platforms: An array of (os, cpu) pairs to support in the toolchain.
|
|
|
"""
|
|
|
|
|
|
+ # Our base filegroup for the toolchain just includes the busybox and the
|
|
|
+ # LLVM symlinks. Importantly, this _doesn't_ include the install digest that
|
|
|
+ # would cause cache misses as-if every file in the toolchain were an input
|
|
|
+ # to every action.
|
|
|
native.filegroup(
|
|
|
- name = name + "_files",
|
|
|
- srcs = native.glob([
|
|
|
- "**",
|
|
|
+ name = name + "_base_files",
|
|
|
+ srcs = ["carbon-busybox", "carbon_install.txt"] + native.glob([
|
|
|
+ "llvm/bin/*",
|
|
|
]),
|
|
|
)
|
|
|
|
|
|
- # Create the individual local toolchains for each CPU.
|
|
|
- for (os, cpu) in configs:
|
|
|
- config_name = "{0}_{1}_{2}".format(name, os, cpu)
|
|
|
+ # We also need a compile-specific filegroup for use when _building_
|
|
|
+ # runtimes. This needs to include the dedicated Clang headers, but we
|
|
|
+ # require the runtimes themselves to provide the relevant headers and
|
|
|
+ # dependencies.
|
|
|
+ native.filegroup(
|
|
|
+ name = name + "_runtimes_compile_files",
|
|
|
+ srcs = [
|
|
|
+ ":" + name + "_base_files",
|
|
|
+ "//llvm/lib/clang/{0}:clang_hdrs".format(llvm_version_major),
|
|
|
+ ],
|
|
|
+ )
|
|
|
+
|
|
|
+ # We can build a single common compile filegroup regardless of CPU and OS.
|
|
|
+ # This needs to include all the headers of the runtimes, but those are
|
|
|
+ # architecture independent.
|
|
|
+ native.filegroup(
|
|
|
+ name = name + "_compile_files",
|
|
|
+ srcs = [
|
|
|
+ ":" + name + "_runtimes_compile_files",
|
|
|
+ "//runtimes:libunwind_hdrs",
|
|
|
+ "//runtimes:libcxx_hdrs",
|
|
|
+ ],
|
|
|
+ )
|
|
|
+
|
|
|
+ # Create the actual toolchains for each OS and CPU.
|
|
|
+ for (os, cpu) in platforms:
|
|
|
+ platform_name = "{0}_{1}_{2}".format(name, os, cpu)
|
|
|
+ platform_constraints = [
|
|
|
+ "@platforms//os:" + os,
|
|
|
+ "@platforms//cpu:" + cpu,
|
|
|
+ ]
|
|
|
+
|
|
|
+ # First, configure a platform and toolchain for building runtimes. This
|
|
|
+ # toolchain will only have the Clang headers and no runtime libraries
|
|
|
+ # included.
|
|
|
+ native.platform(
|
|
|
+ name = platform_name + "_runtimes_platform",
|
|
|
+ constraint_values = [":is_runtimes_build"] + platform_constraints,
|
|
|
+ )
|
|
|
carbon_cc_toolchain_config(
|
|
|
- name = config_name + "_config",
|
|
|
+ name = platform_name + "_runtimes_toolchain_config",
|
|
|
target_cpu = cpu,
|
|
|
target_os = os,
|
|
|
)
|
|
|
cc_toolchain(
|
|
|
- name = config_name + "_tools",
|
|
|
- all_files = ":" + name + "_files",
|
|
|
- ar_files = ":" + name + "_files",
|
|
|
- as_files = ":" + name + "_files",
|
|
|
- compiler_files = ":" + name + "_files",
|
|
|
- dwp_files = ":" + name + "_files",
|
|
|
- linker_files = ":" + name + "_files",
|
|
|
- objcopy_files = ":" + name + "_files",
|
|
|
- strip_files = ":" + name + "_files",
|
|
|
- supports_param_files = 1,
|
|
|
- toolchain_config = ":" + config_name + "_config",
|
|
|
- toolchain_identifier = config_name,
|
|
|
- )
|
|
|
- compatible_with = ["@platforms//cpu:" + cpu, "@platforms//os:" + os]
|
|
|
+ name = platform_name + "_runtimes_cc_toolchain",
|
|
|
+ all_files = ":" + name + "_runtimes_compile_files",
|
|
|
+ ar_files = ":" + name + "_base_files",
|
|
|
+ as_files = ":" + name + "_runtimes_compile_files",
|
|
|
+ compiler_files = ":" + name + "_runtimes_compile_files",
|
|
|
+ dwp_files = ":" + name + "_base_files",
|
|
|
+ linker_files = ":" + name + "_base_files",
|
|
|
+ objcopy_files = ":" + name + "_base_files",
|
|
|
+ strip_files = ":" + name + "_base_files",
|
|
|
+ toolchain_config = ":" + platform_name + "_runtimes_toolchain_config",
|
|
|
+ toolchain_identifier = platform_name + "_runtimes",
|
|
|
+ )
|
|
|
+ native.toolchain(
|
|
|
+ name = platform_name + "_runtimes_toolchain",
|
|
|
+ exec_compatible_with = platform_constraints,
|
|
|
+ target_compatible_with = [":is_runtimes_build"] + platform_constraints,
|
|
|
+ toolchain = platform_name + "_runtimes_cc_toolchain",
|
|
|
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
|
|
|
+ )
|
|
|
+
|
|
|
+ # Now we can use the runtimes platform to build the runtimes on-demand.
|
|
|
+ runtimes_filegroup(
|
|
|
+ name = platform_name + "_runtimes",
|
|
|
+ srcs = ["//runtimes:carbon_runtimes"],
|
|
|
+ runtimes_platform = ":" + platform_name + "_runtimes_platform",
|
|
|
+ )
|
|
|
+
|
|
|
+ # Finally, we can build the main platform and toolchain.
|
|
|
+ native.platform(
|
|
|
+ name = platform_name + "_platform",
|
|
|
+ constraint_values = platform_constraints,
|
|
|
+ )
|
|
|
+
|
|
|
+ # Build the main config with runtimes passed in. This allows the
|
|
|
+ # configuration to use these built runtimes where needed.
|
|
|
+ carbon_cc_toolchain_config(
|
|
|
+ name = platform_name + "_toolchain_config",
|
|
|
+ target_cpu = cpu,
|
|
|
+ target_os = os,
|
|
|
+ runtimes = ":" + platform_name + "_runtimes",
|
|
|
+ )
|
|
|
+
|
|
|
+ # We also include the runtimes in the linker files. We have to do this
|
|
|
+ # in addition to the config parameter as the config can't carry the
|
|
|
+ # actual dependency.
|
|
|
+ native.filegroup(
|
|
|
+ name = platform_name + "_linker_files",
|
|
|
+ srcs = [
|
|
|
+ ":" + name + "_base_files",
|
|
|
+ ":" + platform_name + "_runtimes",
|
|
|
+ ],
|
|
|
+ )
|
|
|
+ native.filegroup(
|
|
|
+ name = platform_name + "_all_files",
|
|
|
+ srcs = [
|
|
|
+ ":" + name + "_compile_files",
|
|
|
+ ":" + platform_name + "_linker_files",
|
|
|
+ ],
|
|
|
+ )
|
|
|
+ cc_toolchain(
|
|
|
+ name = platform_name + "_cc_toolchain",
|
|
|
+ all_files = ":" + platform_name + "_all_files",
|
|
|
+ ar_files = ":" + name + "_base_files",
|
|
|
+ as_files = ":" + name + "_compile_files",
|
|
|
+ compiler_files = ":" + name + "_compile_files",
|
|
|
+ dwp_files = ":" + platform_name + "_linker_files",
|
|
|
+ linker_files = ":" + platform_name + "_linker_files",
|
|
|
+ objcopy_files = ":" + name + "_base_files",
|
|
|
+ strip_files = ":" + name + "_base_files",
|
|
|
+ toolchain_config = ":" + platform_name + "_toolchain_config",
|
|
|
+ toolchain_identifier = platform_name,
|
|
|
+ )
|
|
|
native.toolchain(
|
|
|
- name = config_name,
|
|
|
- exec_compatible_with = compatible_with,
|
|
|
- target_compatible_with = compatible_with,
|
|
|
- toolchain = config_name + "_tools",
|
|
|
+ name = platform_name + "_toolchain",
|
|
|
+ exec_compatible_with = platform_constraints,
|
|
|
+ target_compatible_with = platform_constraints,
|
|
|
+ toolchain = platform_name + "_cc_toolchain",
|
|
|
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
|
|
|
)
|