mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:00:11 +01:00
Introduce a Bazel-integrated build for the installed runtimes (#6872)
This shifts the Bazel toolchain configuration of our installation to build all of the Clang runtimes Carbon uses on-demand natively in Bazel. We export the information about how to build into a generated Starlark file, and emit BUILD files and Starlark logic into the installation to orchestrate the build. This requires some complex management of Bazel toolchains -- we need to first set-up a "runtimes toolchain" that doesn't have runtimes of its own, but can be used to _build_ runtimes. Then we build the runtimes using that toolchain, and assemble them into the standard layout for a Carbon runtimes tree. Finally we configure the _actual_ toolchain with this built tree. Currently, this is only setup for the installed toolchain, but I plan to factor this runtimes build into one that can be used directly as well to break up the monolithic runtimes build step into Bazel-integrated build of the runtimes. This will also serve as the foundation for adding bootstrapping support directly to our Bazel build. --------- Co-authored-by: Dana Jansens <danakj@orodu.net>
This commit is contained in:
co-authored by
Dana Jansens
parent
0a4fd2cb7e
commit
5d41529590
+12
-10
@@ -1,7 +1,7 @@
|
||||
Commit ID: 959284a466ca392a5ccd501cf1c1622d1f423c06
|
||||
Commit ID: d3b82534c2546a892a27856672ed95a7db97dba3
|
||||
Change ID: zyxuvzwmzsnorloyuupuurxkppkoplnw
|
||||
Author : Chandler Carruth <chandlerc@gmail.com> (2026-02-16 23:17:06)
|
||||
Committer: Chandler Carruth <chandlerc@gmail.com> (2026-03-08 07:43:17)
|
||||
Committer: Chandler Carruth <chandlerc@gmail.com> (2026-03-11 07:54:02)
|
||||
|
||||
Improve compiler-rt build structure and export compilation info
|
||||
|
||||
@@ -12,7 +12,7 @@ Committer: Chandler Carruth <chandlerc@gmail.com> (2026-03-08 07:43:17)
|
||||
compiling these source files.
|
||||
|
||||
diff --git a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
|
||||
index 4ded226174..0c3a7daaee 100644
|
||||
index 4ded226174..3b5b8fc787 100644
|
||||
--- a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
|
||||
+++ b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
|
||||
@@ -3,6 +3,7 @@
|
||||
@@ -98,12 +98,14 @@ index 4ded226174..0c3a7daaee 100644
|
||||
] + [
|
||||
AARCH64_OUTLINE_ATOMICS_FMT.format(pat, size, model)
|
||||
for (pat, size, model) in AARCH64_OUTLINE_ATOMICS
|
||||
@@ -328,10 +360,18 @@
|
||||
@@ -328,10 +360,20 @@
|
||||
"lib/builtins/aarch64/lse.S",
|
||||
# These files are provided by SME-specific file groups above.
|
||||
"lib/builtins/aarch64/*sme*",
|
||||
+ # This is only used with MinGW.
|
||||
+ "lib/builtins/aarch64/chkstk.S",
|
||||
+ # TODO: Remove this once we have a way of accessing `SipHash.h`.
|
||||
+ "lib/builtins/aarch64/emupac.cpp",
|
||||
],
|
||||
),
|
||||
)
|
||||
@@ -117,7 +119,7 @@ index 4ded226174..0c3a7daaee 100644
|
||||
BUILTINS_ARM_VFP_SRCS_PATTERNS = [
|
||||
"lib/builtins/arm/*vfp*.S",
|
||||
"lib/builtins/arm/*vfp*.c",
|
||||
@@ -348,9 +388,19 @@
|
||||
@@ -348,9 +390,19 @@
|
||||
),
|
||||
)
|
||||
|
||||
@@ -138,7 +140,7 @@ index 4ded226174..0c3a7daaee 100644
|
||||
srcs = glob(
|
||||
[
|
||||
"lib/builtins/arm/*.S",
|
||||
@@ -359,14 +409,52 @@
|
||||
@@ -359,14 +411,52 @@
|
||||
"lib/builtins/arm/*.h",
|
||||
],
|
||||
allow_empty = True,
|
||||
@@ -196,7 +198,7 @@ index 4ded226174..0c3a7daaee 100644
|
||||
[
|
||||
"lib/builtins/ppc/*.S",
|
||||
"lib/builtins/ppc/*.c",
|
||||
@@ -377,17 +465,64 @@
|
||||
@@ -377,17 +467,64 @@
|
||||
),
|
||||
)
|
||||
|
||||
@@ -272,7 +274,7 @@ index 4ded226174..0c3a7daaee 100644
|
||||
)
|
||||
|
||||
# Source files for the x86 architecture specific builtins (both 32-bit and
|
||||
@@ -402,8 +537,14 @@
|
||||
@@ -402,8 +539,14 @@
|
||||
|
||||
# Source files for the x86-64 architecture specific builtins.
|
||||
filegroup(
|
||||
@@ -289,7 +291,7 @@ index 4ded226174..0c3a7daaee 100644
|
||||
[
|
||||
"lib/builtins/x86_64/*.S",
|
||||
"lib/builtins/x86_64/*.c",
|
||||
@@ -411,13 +552,29 @@
|
||||
@@ -411,13 +554,29 @@
|
||||
"lib/builtins/x86_64/*.h",
|
||||
],
|
||||
allow_empty = True,
|
||||
@@ -321,7 +323,7 @@ index 4ded226174..0c3a7daaee 100644
|
||||
[
|
||||
"lib/builtins/i386/*.S",
|
||||
"lib/builtins/i386/*.c",
|
||||
@@ -429,28 +586,16 @@
|
||||
@@ -429,28 +588,16 @@
|
||||
# This file is used for both i386 and x86_64 and so included in the
|
||||
# broader x86 sources.
|
||||
"lib/builtins/i386/fp_mode.c",
|
||||
|
||||
@@ -8,6 +8,10 @@ load("runtimes_build_info.bzl", "generate_runtimes_build_info_cc_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
exports_files([
|
||||
"runtimes_build_vars.tpl.bzl",
|
||||
])
|
||||
|
||||
cc_library(
|
||||
name = "block_value_store",
|
||||
hdrs = ["block_value_store.h"],
|
||||
|
||||
@@ -19,6 +19,7 @@ Future runtimes we plan to add support for but not yet included:
|
||||
- Profiling runtimes
|
||||
"""
|
||||
|
||||
load("@llvm-project//:vars.bzl", "LLVM_VERSION_MAJOR")
|
||||
load("@llvm-project//compiler-rt:compiler-rt.bzl", "builtins_copts", "crt_copts")
|
||||
load("@llvm-project//libcxx:libcxx_library.bzl", "libcxx_and_abi_copts")
|
||||
load("@llvm-project//libunwind:libunwind_library.bzl", "libunwind_copts")
|
||||
@@ -124,6 +125,7 @@ def _get_substitutions(ctx):
|
||||
"CRT_COPTS": _format_one_per_line(crt_copts),
|
||||
"LIBCXX_AND_ABI_COPTS": _format_one_per_line(libcxx_and_abi_copts),
|
||||
"LIBUNWIND_COPTS": _format_one_per_line(libunwind_copts),
|
||||
"LLVM_VERSION_MAJOR": LLVM_VERSION_MAJOR,
|
||||
} | {
|
||||
k.upper(): _get_path(key_attr(k), _builtins_path)
|
||||
for k in CRT_FILES.keys()
|
||||
@@ -146,6 +148,20 @@ def _get_substitutions(ctx):
|
||||
)]
|
||||
}
|
||||
|
||||
_common_runtimes_rule_attrs = {
|
||||
"_" + k: attr.label(default = v, allow_single_file = True)
|
||||
for k, v in CRT_FILES.items()
|
||||
} | {
|
||||
"_" + _get_name(g): attr.label_list(default = [g], allow_files = True)
|
||||
for g in (
|
||||
BUILTINS_SRCS_FILEGROUPS +
|
||||
BUILTINS_TEXTUAL_SRCS_FILEGROUPS +
|
||||
RUNTIMES_HDRS_FILEGROUPS +
|
||||
RUNTIMES_SRCS_FILEGROUPS +
|
||||
RUNTIMES_TEXTUAL_SRCS_FILEGROUPS
|
||||
)
|
||||
}
|
||||
|
||||
def _generate_runtimes_build_info_h_rule(ctx):
|
||||
h_file = ctx.actions.declare_file(ctx.label.name)
|
||||
ctx.actions.expand_template(
|
||||
@@ -157,19 +173,7 @@ def _generate_runtimes_build_info_h_rule(ctx):
|
||||
|
||||
generate_runtimes_build_info_h = rule(
|
||||
implementation = _generate_runtimes_build_info_h_rule,
|
||||
attrs = {
|
||||
"_" + k: attr.label(default = v, allow_single_file = True)
|
||||
for k, v in CRT_FILES.items()
|
||||
} | {
|
||||
"_" + _get_name(g): attr.label_list(default = [g], allow_files = True)
|
||||
for g in (
|
||||
BUILTINS_SRCS_FILEGROUPS +
|
||||
BUILTINS_TEXTUAL_SRCS_FILEGROUPS +
|
||||
RUNTIMES_HDRS_FILEGROUPS +
|
||||
RUNTIMES_SRCS_FILEGROUPS +
|
||||
RUNTIMES_TEXTUAL_SRCS_FILEGROUPS
|
||||
)
|
||||
} | {
|
||||
attrs = _common_runtimes_rule_attrs | {
|
||||
"_template_file": attr.label(
|
||||
default = "runtimes_build_info.tpl.h",
|
||||
allow_single_file = True,
|
||||
@@ -197,3 +201,22 @@ def generate_runtimes_build_info_cc_library(name, deps = [], **kwargs):
|
||||
] + deps,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def _generate_runtimes_build_vars_rule(ctx):
|
||||
file = ctx.actions.declare_file(ctx.label.name)
|
||||
ctx.actions.expand_template(
|
||||
template = ctx.file._template_file,
|
||||
output = file,
|
||||
substitutions = _get_substitutions(ctx),
|
||||
)
|
||||
return [DefaultInfo(files = depset([file]))]
|
||||
|
||||
generate_runtimes_build_vars = rule(
|
||||
implementation = _generate_runtimes_build_vars_rule,
|
||||
attrs = _common_runtimes_rule_attrs | {
|
||||
"_template_file": attr.label(
|
||||
default = "runtimes_build_vars.tpl.bzl",
|
||||
allow_single_file = True,
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# 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 file exporting Carbon toolchain runtimes build info variables.
|
||||
|
||||
This file is a template that is expanded into a starlark file for the installed
|
||||
Carbon toolchain that provides a trivial textual definition of the relevant
|
||||
build info in variables.
|
||||
"""
|
||||
|
||||
llvm_version_major = LLVM_VERSION_MAJOR
|
||||
|
||||
crtbegin_src = CRTBEGIN_SRC
|
||||
crtend_src = CRTEND_SRC
|
||||
|
||||
crt_copts = [CRT_COPTS]
|
||||
|
||||
builtins_aarch64_srcs = [BUILTINS_AARCH64_SRCS]
|
||||
builtins_x86_64_srcs = [BUILTINS_X86_64_SRCS]
|
||||
builtins_i386_srcs = [BUILTINS_I386_SRCS]
|
||||
|
||||
builtins_aarch64_textual_srcs = [BUILTINS_AARCH64_TEXTUAL_SRCS]
|
||||
builtins_x86_64_textual_srcs = [BUILTINS_X86_64_TEXTUAL_SRCS]
|
||||
builtins_i386_textual_srcs = [BUILTINS_I386_TEXTUAL_SRCS]
|
||||
|
||||
builtins_copts = [BUILTINS_COPTS]
|
||||
|
||||
libcxx_hdrs = [LIBCXX_HDRS]
|
||||
libcxx_linux_srcs = [LIBCXX_LINUX_SRCS]
|
||||
libcxx_macos_srcs = [LIBCXX_MACOS_SRCS]
|
||||
libcxx_win32_srcs = [LIBCXX_WIN32_SRCS]
|
||||
|
||||
libc_internal_libcxx_hdrs = [LIBCXX_SHARED_HEADERS_HDRS]
|
||||
|
||||
libcxxabi_hdrs = [LIBCXXABI_HDRS]
|
||||
libcxxabi_srcs = [LIBCXXABI_SRCS]
|
||||
libcxxabi_textual_srcs = [LIBCXXABI_TEXTUAL_SRCS]
|
||||
|
||||
libcxx_copts = [LIBCXX_AND_ABI_COPTS]
|
||||
|
||||
libunwind_hdrs = [LIBUNWIND_HDRS]
|
||||
libunwind_srcs = [LIBUNWIND_SRCS]
|
||||
|
||||
libunwind_copts = [LIBUNWIND_COPTS]
|
||||
@@ -447,11 +447,6 @@ auto ClangResourceDirBuilder::CollectBuiltinsSrcFiles()
|
||||
// Only compile source files, not headers.
|
||||
llvm::erase_if(src_files,
|
||||
[](llvm::StringRef file) { return file.ends_with(".h"); });
|
||||
|
||||
// TODO: Remove this once we have a way of accessing `SipHash.h`.
|
||||
llvm::erase_if(src_files, [](llvm::StringRef file) {
|
||||
return file.ends_with("emupac.cpp");
|
||||
});
|
||||
return src_files;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ load(
|
||||
"BUILTINS_SRCS_FILEGROUPS",
|
||||
"BUILTINS_TEXTUAL_SRCS_FILEGROUPS",
|
||||
"CRT_FILES",
|
||||
"generate_runtimes_build_vars",
|
||||
)
|
||||
load("configure_cmake_file.bzl", "configure_cmake_file")
|
||||
load("install_filegroups.bzl", "install_filegroup", "install_symlink", "install_target", "make_install_filegroups")
|
||||
@@ -305,6 +306,11 @@ filegroup(
|
||||
],
|
||||
)
|
||||
|
||||
# Generate a Starlark file with all the build variables needed for our runtimes.
|
||||
generate_runtimes_build_vars(
|
||||
name = "staging_bazel/runtimes_build_vars.bzl",
|
||||
)
|
||||
|
||||
# Given a CMake-style install prefix[1], the hierarchy looks like:
|
||||
#
|
||||
# - prefix/bin: Binaries intended for direct use.
|
||||
@@ -350,7 +356,10 @@ install_dirs = {
|
||||
"lib/carbon/bazel": [
|
||||
install_target("carbon_cc_toolchain_config.bzl", "bazel/carbon_cc_toolchain_config.bzl"),
|
||||
install_target("carbon_detected_variables.tpl.bzl", "bazel/carbon_detected_variables.tpl.bzl"),
|
||||
install_target("carbon_runtimes.bzl", "bazel/carbon_runtimes.bzl"),
|
||||
install_target("carbon_toolchain.bzl", "bazel/carbon_toolchain.bzl"),
|
||||
install_target("make_include_copts.bzl", "bazel/make_include_copts.bzl"),
|
||||
install_target("runtimes_build_vars.bzl", "staging_bazel/runtimes_build_vars.bzl"),
|
||||
install_target("BUILD", "bazel/empty.BUILD"),
|
||||
],
|
||||
"lib/carbon/llvm/bin": [install_symlink(
|
||||
@@ -367,6 +376,7 @@ install_dirs = {
|
||||
install_filegroup("libcxx", ":libcxx"),
|
||||
install_filegroup("libcxxabi", ":libcxxabi"),
|
||||
install_filegroup("libunwind", ":libunwind"),
|
||||
install_target("BUILD", "bazel/runtimes.BUILD"),
|
||||
],
|
||||
"lib/carbon/runtimes/libc": [
|
||||
install_filegroup("internal", ":libc_internal"),
|
||||
@@ -379,6 +389,7 @@ install_dirs = {
|
||||
),
|
||||
],
|
||||
"lib/carbon/llvm/lib/clang/" + LLVM_VERSION_MAJOR: [
|
||||
install_target("BUILD", "bazel/clang_resource_dir.BUILD"),
|
||||
install_filegroup(
|
||||
"include",
|
||||
":clang_headers",
|
||||
|
||||
@@ -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,
|
||||
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",
|
||||
)
|
||||
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",
|
||||
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 = 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",
|
||||
)
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
# 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
|
||||
|
||||
"""Starlark rules for building a Carbon runtimes tree.
|
||||
|
||||
TODO: Currently, this produces a complete, static Carbon runtimes tree that
|
||||
mirrors the exact style of runtimes tree the Carbon toolchain would build on its
|
||||
own. However, it would be preferable to preserve the builtins, libc++, and
|
||||
libunwind `cc_library` rules as "normal" library rules (if behind a transition)
|
||||
and automatically depend on them. This would allow things like LTO and such to
|
||||
include these. However, this requires support in `@rules_cc` for this kind of
|
||||
dependency to be added.
|
||||
"""
|
||||
|
||||
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
||||
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
|
||||
|
||||
def _build_crt_file(ctx, cc_toolchain, feature_configuration, crt_file):
|
||||
_, compilation_outputs = cc_common.compile(
|
||||
name = ctx.label.name + ".compile_" + crt_file.basename,
|
||||
actions = ctx.actions,
|
||||
feature_configuration = feature_configuration,
|
||||
cc_toolchain = cc_toolchain,
|
||||
srcs = [crt_file],
|
||||
user_compile_flags = ctx.attr.crt_copts,
|
||||
)
|
||||
|
||||
# Extract the PIC object file and make sure we built one.
|
||||
obj = compilation_outputs.pic_objects[0]
|
||||
if not obj:
|
||||
fail("The toolchain failed to produce a PIC object file. Ensure your " +
|
||||
"toolchain supports PIC.")
|
||||
|
||||
return obj
|
||||
|
||||
def _removeprefix_or_fail(s, prefix):
|
||||
new_s = s.removeprefix(prefix)
|
||||
if new_s == s:
|
||||
fail("Unable to remove prefix '{0}' from '{1}'".format(prefix, s))
|
||||
return new_s
|
||||
|
||||
def _carbon_runtimes_impl(ctx):
|
||||
outputs = []
|
||||
prefix = ctx.attr.name
|
||||
|
||||
# Create a marker file in the runtimes root first. We'll use this to locate
|
||||
# the runtimes for the toolchain.
|
||||
root_out = ctx.actions.declare_file("{0}/runtimes_root".format(prefix))
|
||||
ctx.actions.write(output = root_out, content = "")
|
||||
outputs.append(root_out)
|
||||
|
||||
# Setup the C++ toolchain and configuration. We also force the `pic` feature
|
||||
# to be enabled for these actions as we always want PIC generated code --
|
||||
# this avoids the need to build two versions of the runtimes and doesn't
|
||||
# create problems with modern code generation when linking statically. This
|
||||
# also simplifies extracting the outputs as we only need to look at
|
||||
# `pic_objects`.
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
feature_configuration = cc_common.configure_features(
|
||||
ctx = ctx,
|
||||
cc_toolchain = cc_toolchain,
|
||||
requested_features = ctx.features + ["pic"],
|
||||
unsupported_features = ctx.disabled_features,
|
||||
)
|
||||
|
||||
if ctx.attr.target_triple != "":
|
||||
builtins_lib_path = "clang_resource_dir/lib/{0}".format(ctx.attr.target_triple)
|
||||
else:
|
||||
builtins_lib_path = "clang_resource_dir/lib"
|
||||
|
||||
for filename, src in [
|
||||
("crtbegin", ctx.files.crtbegin_src),
|
||||
("crtend", ctx.files.crtend_src),
|
||||
]:
|
||||
if not src:
|
||||
continue
|
||||
src = src[0]
|
||||
crt_obj = _build_crt_file(ctx, cc_toolchain, feature_configuration, src)
|
||||
crt_out = ctx.actions.declare_file("{0}/{1}/clang_rt.{2}.o".format(
|
||||
prefix,
|
||||
builtins_lib_path,
|
||||
filename,
|
||||
))
|
||||
ctx.actions.symlink(output = crt_out, target_file = crt_obj)
|
||||
outputs.append(crt_out)
|
||||
|
||||
for runtime_dir, archive_name, archive in [
|
||||
(builtins_lib_path, "libclang_rt.builtins.a", ctx.files.builtins_archive[0]),
|
||||
("libcxx/lib", "libc++.a", ctx.files.libcxx_archive[0]),
|
||||
("libunwind/lib", "libunwind.a", ctx.files.libunwind_archive[0]),
|
||||
]:
|
||||
runtime_out = ctx.actions.declare_file("{0}/{1}/{2}".format(
|
||||
prefix,
|
||||
runtime_dir,
|
||||
archive_name,
|
||||
))
|
||||
ctx.actions.symlink(output = runtime_out, target_file = archive)
|
||||
outputs.append(runtime_out)
|
||||
|
||||
for hdr in ctx.files.clang_hdrs:
|
||||
# Incrementally remove prefixes of the paths to find the `include`
|
||||
# directory we want to symlink into the output tree.
|
||||
rel_path = hdr.path
|
||||
if hdr.root.path != "":
|
||||
rel_path = _removeprefix_or_fail(rel_path, hdr.root.path + "/")
|
||||
rel_path = _removeprefix_or_fail(rel_path, hdr.owner.workspace_root + "/")
|
||||
rel_path = _removeprefix_or_fail(rel_path, hdr.owner.package + "/")
|
||||
rel_path = _removeprefix_or_fail(rel_path, "include/")
|
||||
|
||||
out_hdr = ctx.actions.declare_file(
|
||||
"{0}/clang_resource_dir/include/{1}".format(prefix, rel_path),
|
||||
)
|
||||
ctx.actions.symlink(output = out_hdr, target_file = hdr)
|
||||
outputs.append(out_hdr)
|
||||
|
||||
return [DefaultInfo(files = depset(outputs))]
|
||||
|
||||
carbon_runtimes = rule(
|
||||
implementation = _carbon_runtimes_impl,
|
||||
attrs = {
|
||||
"builtins_archive": attr.label(mandatory = True, allow_files = [".a"]),
|
||||
"clang_hdrs": attr.label_list(mandatory = True, allow_files = True),
|
||||
"crt_copts": attr.string_list(default = []),
|
||||
"crtbegin_src": attr.label(allow_files = [".c"]),
|
||||
"crtend_src": attr.label(allow_files = [".c"]),
|
||||
"libcxx_archive": attr.label(mandatory = True, allow_files = [".a"]),
|
||||
"libunwind_archive": attr.label(mandatory = True, allow_files = [".a"]),
|
||||
"target_triple": attr.string(mandatory = True),
|
||||
"_cc_toolchain": attr.label(
|
||||
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
|
||||
),
|
||||
},
|
||||
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
|
||||
fragments = ["cpp"],
|
||||
doc = """Builds a Carbon runtimes tree under the `name` directory.
|
||||
|
||||
This rule works to replicate the behavior of the Carbon toolchain building a
|
||||
runtimes tree directly in Bazel to allow it to fully benefit from Bazel's
|
||||
orchestration, caching, and even remote execution.
|
||||
|
||||
It produces a runtimes tree customized for the specific target platform,
|
||||
similar to what the Carbon toolchain does on its own when invoked outside of
|
||||
Bazel.
|
||||
|
||||
The runtimes tree includes a complete Clang resource-dir, including CRT
|
||||
begin/end objects, and the builtins library. It also includes a built libc++
|
||||
and libunwind library. These are arranged in the standard Carbon runtimes
|
||||
layout so that they are correctly found by the toolchain.
|
||||
""",
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
# 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
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
filegroup(
|
||||
name = "clang_hdrs",
|
||||
srcs = glob(["include/**"]),
|
||||
)
|
||||
@@ -6,9 +6,16 @@ load("//bazel:carbon_cc_toolchain_config.bzl", "carbon_cc_toolchain_suite")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
constraint_setting(name = "runtimes_build")
|
||||
|
||||
constraint_value(
|
||||
name = "is_runtimes_build",
|
||||
constraint_setting = ":runtimes_build",
|
||||
)
|
||||
|
||||
carbon_cc_toolchain_suite(
|
||||
name = "carbon_cc_toolchain",
|
||||
configs = [
|
||||
name = "carbon",
|
||||
platforms = [
|
||||
("linux", "aarch64"),
|
||||
("linux", "x86_64"),
|
||||
("freebsd", "x86_64"),
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 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
|
||||
|
||||
"""Workaround for lack of easy way to add private includes.
|
||||
|
||||
This is a workaround for the following Bazel issue:
|
||||
https://github.com/bazelbuild/bazel/issues/2670
|
||||
"""
|
||||
|
||||
def make_include_copts(include_dirs):
|
||||
"""Create `copts` to search the provided directories for includes."""
|
||||
copts = []
|
||||
prefix = ""
|
||||
|
||||
repo_name = native.repository_name()
|
||||
if repo_name != "@":
|
||||
prefix = "external/{}/".format(repo_name[1:])
|
||||
|
||||
package_name = native.package_name()
|
||||
for include_dir in include_dirs:
|
||||
copts.append("-I{}{}/{}".format(prefix, package_name, include_dir))
|
||||
copts.append("-I$(GENDIR)/{}{}/{}".format(prefix, package_name, include_dir))
|
||||
|
||||
return copts
|
||||
@@ -0,0 +1,196 @@
|
||||
# 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
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
load("//bazel:carbon_runtimes.bzl", "carbon_runtimes")
|
||||
load("//bazel:make_include_copts.bzl", "make_include_copts")
|
||||
load(
|
||||
"//bazel:runtimes_build_vars.bzl",
|
||||
"builtins_aarch64_srcs",
|
||||
"builtins_aarch64_textual_srcs",
|
||||
"builtins_copts",
|
||||
"builtins_i386_srcs",
|
||||
"builtins_i386_textual_srcs",
|
||||
"builtins_x86_64_srcs",
|
||||
"builtins_x86_64_textual_srcs",
|
||||
"crt_copts",
|
||||
"crtbegin_src",
|
||||
"crtend_src",
|
||||
"libc_internal_libcxx_hdrs",
|
||||
"libcxx_copts",
|
||||
"libcxx_hdrs",
|
||||
"libcxx_linux_srcs",
|
||||
"libcxx_macos_srcs",
|
||||
"libcxx_win32_srcs",
|
||||
"libcxxabi_hdrs",
|
||||
"libcxxabi_srcs",
|
||||
"libcxxabi_textual_srcs",
|
||||
"libunwind_copts",
|
||||
"libunwind_hdrs",
|
||||
"libunwind_srcs",
|
||||
"llvm_version_major",
|
||||
)
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
# Clang looks in a target-triple subdirectory of its resource directory for the
|
||||
# builtins and CRT files. Triples capture a large range of settings and aren't
|
||||
# even consistent structurally between platforms, so we expect to have roughly
|
||||
# one setting per supported target triple. By convention, we name them after the
|
||||
# target triple.
|
||||
#
|
||||
# TODO: Add constraints and other settings so we can select the correct target
|
||||
# triple for different `libc`s.
|
||||
#
|
||||
# TODO: Add other OS and CPU triples.
|
||||
config_setting(
|
||||
name = "x86_64-unknown-linux-gnu",
|
||||
constraint_values = [
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:x86_64",
|
||||
],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "aarch64-unknown-linux-gnu",
|
||||
constraint_values = [
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:aarch64",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "builtins_internal",
|
||||
hdrs_check = "strict",
|
||||
textual_hdrs = select({
|
||||
"@platforms//cpu:aarch64": builtins_aarch64_textual_srcs,
|
||||
"@platforms//cpu:i386": builtins_i386_textual_srcs,
|
||||
"@platforms//cpu:x86_64": builtins_x86_64_textual_srcs,
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "builtins",
|
||||
srcs = select({
|
||||
"@platforms//cpu:aarch64": builtins_aarch64_srcs,
|
||||
"@platforms//cpu:i386": builtins_i386_srcs,
|
||||
"@platforms//cpu:x86_64": builtins_x86_64_srcs,
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
copts = builtins_copts + make_include_copts([
|
||||
"builtins",
|
||||
]),
|
||||
hdrs_check = "strict",
|
||||
deps = [":builtins_internal"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "builtins_archive",
|
||||
srcs = [":builtins"],
|
||||
output_group = "archive",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "libunwind_hdrs",
|
||||
srcs = libunwind_hdrs,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "libunwind",
|
||||
srcs = libunwind_srcs,
|
||||
hdrs = [":libunwind_hdrs"],
|
||||
copts = libunwind_copts + [
|
||||
# We disable all warnings as upstream isn't clean with the common
|
||||
# warning flags Carbon uses by default.
|
||||
"-w",
|
||||
],
|
||||
hdrs_check = "strict",
|
||||
includes = ["libunwind/include"],
|
||||
linkstatic = 1,
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "libunwind_archive",
|
||||
srcs = [":libunwind"],
|
||||
output_group = "archive",
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "libcxxabi_internal",
|
||||
hdrs_check = "strict",
|
||||
textual_hdrs = libcxxabi_textual_srcs,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "libc_internal_libcxx",
|
||||
hdrs = libc_internal_libcxx_hdrs,
|
||||
hdrs_check = "strict",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "libcxx_hdrs",
|
||||
srcs = [
|
||||
"libcxx/include/__assertion_handler",
|
||||
"libcxx/include/__config_site",
|
||||
] + libcxx_hdrs + libcxxabi_hdrs,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "libcxx",
|
||||
srcs = select({
|
||||
"@platforms//os:macos": libcxx_macos_srcs,
|
||||
"@platforms//os:windows": libcxx_win32_srcs,
|
||||
"//conditions:default": libcxx_linux_srcs,
|
||||
}) + libcxxabi_srcs,
|
||||
hdrs = [":libcxx_hdrs"],
|
||||
copts = libcxx_copts + make_include_copts([
|
||||
"libcxx/src",
|
||||
"libc/internal",
|
||||
]) + [
|
||||
# We disable all warnings as upstream isn't clean with the common
|
||||
# warning flags Carbon uses by default.
|
||||
"-w",
|
||||
],
|
||||
hdrs_check = "strict",
|
||||
includes = [
|
||||
"libcxx/include",
|
||||
"libcxxabi/include",
|
||||
],
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
":libc_internal_libcxx",
|
||||
":libcxxabi_internal",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "libcxx_archive",
|
||||
srcs = [":libcxx"],
|
||||
output_group = "archive",
|
||||
)
|
||||
|
||||
carbon_runtimes(
|
||||
name = "carbon_runtimes",
|
||||
builtins_archive = ":builtins_archive",
|
||||
clang_hdrs = [
|
||||
"//llvm/lib/clang/{0}:clang_hdrs".format(llvm_version_major),
|
||||
],
|
||||
crt_copts = crt_copts,
|
||||
crtbegin_src = select({
|
||||
"@platforms//os:linux": crtbegin_src,
|
||||
"//conditions:default": None,
|
||||
}),
|
||||
crtend_src = select({
|
||||
"@platforms//os:linux": crtend_src,
|
||||
"//conditions:default": None,
|
||||
}),
|
||||
libcxx_archive = ":libcxx_archive",
|
||||
libunwind_archive = ":libunwind_archive",
|
||||
target_triple = select({
|
||||
":aarch64-unknown-linux-gnu": "aarch64-unknown-linux-gnu",
|
||||
":x86_64-unknown-linux-gnu": "x86_64-unknown-linux-gnu",
|
||||
"//conditions:default": "",
|
||||
}),
|
||||
)
|
||||
Reference in New Issue
Block a user