Ability to provide a custom sysroot

Also, internal reorganization into smaller .bzl files.
This commit is contained in:
Siddhartha Bagaria 2019-02-18 16:20:54 -08:00
parent 3622268bc3
commit 20773e513f
15 changed files with 484 additions and 279 deletions

View File

@ -15,5 +15,6 @@ matrix:
- env: TEST_SH=ubuntu_14_04_test.sh
- env: TEST_SH=ubuntu_16_04_test.sh
- env: TEST_SH=ubuntu_18_04_test.sh
- env: TEST_SH=linux_sysroot_test.sh
script: "tests/scripts/${TEST_SH}"

View File

@ -10,7 +10,7 @@ http_archive(
urls = ["https://github.com/grailbio/bazel-toolchain/archive/master.tar.gz"],
)
load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "llvm_toolchain")
load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "llvm_toolchain")
llvm_toolchain(
name = "llvm_toolchain",
@ -28,6 +28,9 @@ sandboxed builds, and remote execution builds will need toolchains configured
manually through the `distribution` attribute. We expect the detection logic to
grow through community contributions. We welcome PRs! :smile:
See in-code documentation in [rules.bzl](toolchain/rules.bzl) for available
attributes to `llvm_toolchain`.
For making changes to default settings for these toolchains, edit the
CROSSTOOL.tpl file. The file is in ASCII protobuf format.
@ -40,6 +43,13 @@ Notes:
and get better control of the environment in which the toolchain binaries are
run.
- A sysroot can be specified through the `sysroot` attribute. This can be either
a path on the user's system, or a bazel `filegroup` like label. One way to
create a sysroot is to use `docker export` to get a single archive of the
entire filesystem for the image you want. Another way is to use the build
scripts provided by the
[Chromium project](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux_sysroot.md).
- Sandboxing the toolchain introduces a significant overhead (100ms per
action). To overcome this, one can use
`--experimental_sandbox_base=/dev/shm`. However, not all environments might
@ -58,10 +68,6 @@ Notes:
the build actions are not reproducible across multiple workspaces, although
the build outputs can be.
- The toolchain is almost hermetic but borrows system headers and libraries
from the user's system. If needed, we can package a sysroot for our build
environment and set `builtin_sysroot` in CROSSTOOL.
Other examples of toolchain configuration:
https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain

View File

@ -16,7 +16,7 @@ workspace(
name = "com_grail_bazel_toolchain",
)
load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "llvm_toolchain")
load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "llvm_toolchain")
llvm_toolchain(
name = "llvm_toolchain",
@ -27,3 +27,28 @@ llvm_toolchain(
name = "llvm_toolchain_6_0_0",
llvm_version = "6.0.0",
)
## Toolchain example with a sysroot.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# This sysroot is used by github.com/vsco/bazel-toolchains.
http_archive(
name = "org_chromium_sysroot_linux_x64",
build_file_content = """
filegroup(
name = "sysroot",
srcs = glob(["*/**"]),
visibility = ["//visibility:public"],
)
""",
sha256 = "84656a6df544ecef62169cfe3ab6e41bb4346a62d3ba2a045dc5a0a2ecea94a3",
urls = ["https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/2202c161310ffde63729f29d27fe7bb24a0bc540/debian_stretch_amd64_sysroot.tar.xz"],
)
llvm_toolchain(
name = "llvm_toolchain_linux_sysroot",
llvm_version = "7.0.0",
sysroot = {
"linux": "@org_chromium_sysroot_linux_x64//:sysroot",
},
)

View File

@ -0,0 +1,47 @@
#!/bin/bash
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail
images=(
"ubuntu:18.04"
)
git_root=$(git rev-parse --show-toplevel)
readonly git_root
for image in "${images[@]}"; do
docker pull "${image}"
docker run --rm -it --entrypoint=/bin/bash --volume="${git_root}:/src:ro" "${image}" -c """
set -exuo pipefail
# Common setup
export DEBIAN_FRONTEND=noninteractive
apt-get -qq update
apt-get -qq -y install apt-utils curl pkg-config zip g++ zlib1g-dev unzip python >/dev/null
# The above command gives some verbose output that can not be silenced easily.
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=288778
# Install bazel
echo 'deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8' | tee /etc/apt/sources.list.d/bazel.list
curl -s https://bazel.build/bazel-release.pub.gpg | apt-key add -
apt-get -qq update
apt-get -qq -y install bazel >/dev/null
# Run tests
cd /src
tests/scripts/run_tests.sh -t llvm_toolchain_linux_sysroot
"""
done

View File

@ -13,14 +13,11 @@
# limitations under the License.
# This BUILD file exports the templates and static files needed for dynamic toolchain configuration.
# See configure.bzl for how they are used.
# See internal/configure.bzl for how they are used.
exports_files(
glob(
["*"],
exclude = [
"configure.bzl",
"BUILD.bazel",
],
exclude = ["BUILD.bazel"],
),
)

View File

@ -26,6 +26,11 @@ filegroup(
srcs = ["bin/cc_wrapper.sh"],
)
filegroup(
name = "sysroot_components",
srcs = [%{sysroot_label}],
)
cc_toolchain_suite(
name = "toolchain",
toolchains = {
@ -36,7 +41,7 @@ cc_toolchain_suite(
},
)
load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "conditional_cc_toolchain")
load("@com_grail_bazel_toolchain//toolchain:rules.bzl", "conditional_cc_toolchain")
conditional_cc_toolchain("cc-clang-linux", "k8", False, %{absolute_paths})
conditional_cc_toolchain("cc-clang-darwin", "darwin", True, %{absolute_paths})
@ -90,6 +95,7 @@ filegroup(
srcs = [
":clang",
":include",
":sysroot_components",
],
)
@ -150,6 +156,7 @@ filegroup(
":clang",
":ld",
":lib",
":sysroot_components",
],
)

View File

@ -49,7 +49,7 @@ toolchain {
target_cpu: "k8"
target_system_name: "x86_64-unknown-linux-gnu"
builtin_sysroot: ""
builtin_sysroot: "%{sysroot_path}"
# Working with symlinks; anticipated to be a future default.
compiler_flag: "-no-canonical-prefixes"
@ -75,6 +75,7 @@ toolchain {
cxx_flag: "-std=c++17"
cxx_flag: "-stdlib=libc++"
# The linker has no way of knowing if there are C++ objects; so we always link C++ libraries.
linker_flag: "-L%{toolchain_path_prefix}lib"
linker_flag: "-l:libc++.a"
linker_flag: "-l:libc++abi.a"
linker_flag: "-l:libunwind.a"
@ -93,9 +94,9 @@ toolchain {
# https://github.com/bazelbuild/bazel/blob/d61a185de8582d29dda7525bb04d8ffc5be3bd11/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java#L125
cxx_builtin_include_directory: "%{toolchain_path_prefix}include/c++/v1"
cxx_builtin_include_directory: "%{toolchain_path_prefix}lib/clang/%{llvm_version}/include"
cxx_builtin_include_directory: "/include"
cxx_builtin_include_directory: "/usr/include"
cxx_builtin_include_directory: "/usr/local/include"
cxx_builtin_include_directory: "%{sysroot_prefix}/include"
cxx_builtin_include_directory: "%{sysroot_prefix}/usr/include"
cxx_builtin_include_directory: "%{sysroot_prefix}/usr/local/include"
objcopy_embed_flag: "-I"
objcopy_embed_flag: "binary"
@ -166,7 +167,7 @@ toolchain {
abi_libc_version: "darwin_x86_64"
needsPic: false
builtin_sysroot: "%{darwin_sdk_path}"
builtin_sysroot: "%{sysroot_path}"
# Working with symlinks
compiler_flag: "-no-canonical-prefixes"
@ -205,8 +206,8 @@ toolchain {
# https://github.com/bazelbuild/bazel/blob/d61a185de8582d29dda7525bb04d8ffc5be3bd11/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java#L125
cxx_builtin_include_directory: "%{toolchain_path_prefix}include/c++/v1"
cxx_builtin_include_directory: "%{toolchain_path_prefix}lib/clang/%{llvm_version}/include"
cxx_builtin_include_directory: "%sysroot%/usr/include"
cxx_builtin_include_directory: "%sysroot%/System/Library/Frameworks"
cxx_builtin_include_directory: "%{sysroot_prefix}/usr/include"
cxx_builtin_include_directory: "%{sysroot_prefix}/System/Library/Frameworks"
cxx_builtin_include_directory: "/Library/Frameworks"
objcopy_embed_flag: "-I"

View File

@ -1,260 +0,0 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# If a new LLVM version is missing from this list, please add the shasum here
# and send a PR on github. To compute the shasum block, you can use the script
# utils/llvm_checksums.sh
_sha256 = {
# 6.0.0
"clang+llvm-6.0.0-aarch64-linux-gnu.tar.xz": "69382758842f29e1f84a41208ae2fd0fae05b5eb7f5531cdab97f29dda3c2334",
"clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz": "fee8352f5dee2e38fa2bb80ab0b5ef9efef578cbc6892e5c724a1187498119b7",
"clang+llvm-6.0.0-armv7a-linux-gnueabihf.tar.xz": "4fda22e3d80994f343bfbdcae60f75e63ad44eb0998c59c559d706c11dd87b76",
"clang+llvm-6.0.0-i386-unknown-freebsd-10.tar.xz": "13414a66b680760171e04f32071396eb6e5a179ff0b5a067d48c4b23744840f1",
"clang+llvm-6.0.0-i686-linux-gnu-Fedora27.tar.xz": "2619e0a2542eec997daed3c7e597d99d5800cc3a07500b359429541a260d0207",
"clang+llvm-6.0.0-mips-linux-gnu.tar.xz": "39820007ef6b2e3a4d05ec15feb477ce6e4e6e90180d00326e6ab9982ed8fe82",
"clang+llvm-6.0.0-mipsel-linux-gnu.tar.xz": "5ff062f4838ac51a3500383faeb0731440f1c4473bf892258314a49cbaa66e61",
"clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz": "0ef8e99e9c9b262a53ab8f2821e2391d041615dd3f3ff36fdf5370916b0f4268",
"clang+llvm-6.0.0-x86_64-linux-gnu-Fedora27.tar.xz": "2aada1f1a973d5d4d99a30700c4b81436dea1a2dcba8dd965acf3318d3ea29bb",
"clang+llvm-6.0.0-x86_64-linux-gnu-debian8.tar.xz": "ff55cd0bdd0b67e22d1feee2e4c84dedc3bb053401330b64c7f6ac18e88a71f1",
"clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz": "114e78b2f6db61aaee314c572e07b0d635f653adc5d31bd1cd0bf31a3db4a6e5",
"clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz": "cc99fda45b4c740f35d0a367985a2bf55491065a501e2dd5d1ad3f97dcac89da",
"clang+llvm-6.0.0-x86_64-linux-sles11.3.tar.xz": "1d4d30ebe4a7e5579644235b46513a1855d3ece865f7cc5ccd0ac5113c461ee7",
"clang+llvm-6.0.0-x86_64-linux-sles12.2.tar.xz": "c144e17aab8dce8e8823a7a891067e27fd0686a49d8a3785cb64b0e51f08e2ee",
# 6.0.1
"clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz": "6d1f67c9e7c3481106d5c9bfcb8a75e3876eb17a446a14c59c13cafd000c21d2",
"clang+llvm-6.0.1-i386-unknown-freebsd10.tar.xz": "c6f65f2c42fa02e3b7e508664ded9b7a91ebafefae368dfa84b3d68811bcb924",
"clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz": "fa5416553ca94a8c071a27134c094a5fb736fe1bd0ecc5ef2d9bc02754e1bef0",
"clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz": "7ea204ecd78c39154d72dfc0d4a79f7cce1b2264da2551bb2eef10e266d54d91",
"clang+llvm-6.0.1-x86_64-linux-sles11.3.tar.xz": "d128e2a7ea8b42418ec58a249e886ec2c736cbbbb08b9e11f64eb281b62bc574",
"clang+llvm-6.0.1-x86_64-linux-sles12.3.tar.xz": "79c74f4764d13671285412d55da95df42b4b87064785cde3363f806dbb54232d",
# 7.0.0
"clang+llvm-7.0.0-amd64-unknown-freebsd-10.tar.xz": "95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255",
"clang+llvm-7.0.0-i386-unknown-freebsd-10.tar.xz": "35460d34a8b3d856e0d7c0b2b20d31f0d1ec05908c830a81f586721e8f8fb04f",
"clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz": "b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca",
"clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz": "5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a",
"clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz": "69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2",
"clang+llvm-7.0.0-x86_64-linux-sles11.3.tar.xz": "1a0a94a5cef357b885d02cf46b66109b6233f0af8f02be3da08e2daf646b5cf8",
"clang+llvm-7.0.0-x86_64-linux-sles12.3.tar.xz": "1c303f1a7b90f0f1988387dfab16f1eadbe2b2152d86a323502068379941dd17",
}
def _download_llvm_preconfigured(rctx):
llvm_version = rctx.attr.llvm_version
url_base = []
if rctx.attr.llvm_mirror:
url_base += [rctx.attr.llvm_mirror]
url_base += ["https://releases.llvm.org"]
if rctx.attr.distribution == "auto":
exec_result = rctx.execute([
rctx.path(rctx.attr._llvm_release_name),
llvm_version,
])
if exec_result.return_code:
fail("Failed to detect host OS version: \n%s\n%s" % (exec_result.stdout, exec_result.stderr))
if exec_result.stderr:
print(exec_result.stderr)
basename = exec_result.stdout.strip()
else:
basename = rctx.attr.distribution
if basename not in _sha256:
fail("Unknown LLVM release: %s\nPlease ensure file name is correct." % basename)
urls = [
(base + "/{0}/{1}".format(llvm_version, basename)).replace("+", "%2B")
for base in url_base
]
rctx.download_and_extract(
urls,
sha256 = _sha256[basename],
stripPrefix = basename[:(len(basename) - len(".tar.xz"))],
)
def _download_llvm(rctx):
if rctx.os.name == "linux":
urls = rctx.attr.urls["linux"]
sha256 = rctx.attr.sha256["linux"]
prefix = rctx.attr.strip_prefix["linux"]
elif rctx.os.name == "mac os x":
urls = rctx.attr.urls["darwin"]
sha256 = rctx.attr.sha256["darwin"]
prefix = rctx.attr.strip_prefix["darwin"]
rctx.download_and_extract(urls, sha256 = sha256, stripPrefix = prefix)
def _darwin_sdk_path(rctx):
if rctx.os.name != "mac os x":
return ""
exec_result = rctx.execute(["/usr/bin/xcrun", "--show-sdk-path", "--sdk", "macosx"])
if exec_result.return_code:
fail("Failed to detect OSX SDK path: \n%\n%s" % (exec_result.stdout, exec_result.stderr))
if exec_result.stderr:
print(exec_result.stderr)
return exec_result.stdout.strip()
def _makevars_ld_flags(rctx):
if rctx.os.name == "mac os x":
return ""
# lld, as of LLVM 7, is experimental for Mach-O, so we use it only on linux.
return "-fuse-ld=lld"
def _llvm_toolchain_impl(rctx):
repo_path = str(rctx.path(""))
relative_path_prefix = "external/%s/" % rctx.name
if rctx.attr.absolute_paths:
toolchain_path_prefix = (repo_path + "/")
else:
toolchain_path_prefix = relative_path_prefix
substitutions = {
"%{llvm_version}": rctx.attr.llvm_version,
"%{toolchain_path_prefix}": toolchain_path_prefix,
"%{tools_path_prefix}": (repo_path + "/") if rctx.attr.absolute_paths else "",
"%{debug_toolchain_path_prefix}": relative_path_prefix,
"%{darwin_sdk_path}": _darwin_sdk_path(rctx),
"%{absolute_toolchain_path}": repo_path,
"%{absolute_paths}": "True" if rctx.attr.absolute_paths else "False",
"%{makevars_ld_flags}": _makevars_ld_flags(rctx),
}
rctx.template(
"CROSSTOOL",
Label("@com_grail_bazel_toolchain//toolchain:CROSSTOOL.tpl"),
substitutions,
)
rctx.template(
"bin/cc_wrapper.sh", # Co-located with the linker to help rules_go.
Label("@com_grail_bazel_toolchain//toolchain:cc_wrapper.sh.tpl"),
substitutions,
)
rctx.template(
"Makevars",
Label("@com_grail_bazel_toolchain//toolchain:Makevars.tpl"),
substitutions,
)
rctx.template(
"BUILD",
Label("@com_grail_bazel_toolchain//toolchain:BUILD.tpl"),
substitutions,
)
rctx.symlink("/usr/bin/ar", "bin/ar") # For GoLink.
# For GoCompile on macOS; compiler path is set from linker path.
# It also helps clang driver sometimes for the linker to be colocated with the compiler.
rctx.symlink("/usr/bin/ld", "bin/ld")
if rctx.os.name == "linux":
rctx.symlink("/usr/bin/ld.gold", "bin/ld.gold")
else:
# Add dummy file for non-linux so we don't have to put conditional logic in BUILD.
rctx.file("bin/ld.gold")
# Repository implementation functions can be restarted, keep expensive ops at the end.
if rctx.attr.urls:
_download_llvm(rctx)
else:
_download_llvm_preconfigured(rctx)
llvm_toolchain = repository_rule(
attrs = {
"llvm_version": attr.string(
default = "6.0.0",
doc = "One of the supported versions of LLVM.",
),
"distribution": attr.string(
default = "auto",
doc = ("LLVM pre-built binary distribution filename, must be one " +
"listed on http://releases.llvm.org/download.html for the version " +
"specified in the llvm_version attribute. A special value of " +
"'auto' tries to detect the version based on host OS."),
),
"llvm_mirror": attr.string(
doc = "Mirror base for LLVM binaries if using the pre-configured URLs.",
),
"absolute_paths": attr.bool(
default = False,
doc = "Whether to use absolute paths in CROSSTOOL. Avoids sandbox overhead.",
),
"_llvm_release_name": attr.label(
default = "@com_grail_bazel_toolchain//toolchain:llvm_release_name.py",
allow_single_file = True,
doc = "Python module to output LLVM release name for the current OS.",
),
# Following attributes are needed only when using a non-standard URL scheme.
"urls": attr.string_list_dict(
mandatory = False,
doc = "URLs for each OS type (linux and darwin) if not using the pre-configured URLs.",
),
"sha256": attr.string_dict(
default = {
"linux": "",
"darwin": "",
},
doc = "sha256 of the archive for each OS type.",
),
"strip_prefix": attr.string_dict(
default = {
"linux": "",
"darwin": "",
},
doc = "Path prefix to strip from the extracted files.",
),
},
local = False,
implementation = _llvm_toolchain_impl,
)
def conditional_cc_toolchain(name, cpu, darwin, absolute_paths = False):
# Toolchain macro for BUILD file to use conditional logic.
if absolute_paths:
native.cc_toolchain(
name = name,
toolchain_identifier = "clang-darwin" if darwin else "clang-linux",
cpu = cpu,
all_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
linker_files = ":empty",
objcopy_files = ":empty",
static_runtime_libs = [":empty"],
strip_files = ":empty",
supports_param_files = 0 if darwin else 1,
)
else:
extra_files = [":cc_wrapper"] if darwin else []
native.filegroup(name = name + "-all-files", srcs = [":all_components"] + extra_files)
native.filegroup(name = name + "-compiler-files", srcs = [":compiler_components"] + extra_files)
native.filegroup(name = name + "-linker-files", srcs = [":linker_components"] + extra_files)
native.cc_toolchain(
name = name,
toolchain_identifier = "clang-darwin" if darwin else "clang-linux",
cpu = cpu,
all_files = name + "-all-files",
compiler_files = name + "-compiler-files",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
linker_files = name + "-linker-files",
objcopy_files = ":objcopy",
static_runtime_libs = [":empty"],
strip_files = ":empty",
supports_param_files = 0 if darwin else 1,
)

View File

@ -0,0 +1,13 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

View File

@ -0,0 +1,126 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load(
"@com_grail_bazel_toolchain//toolchain/internal:llvm_distributions.bzl",
_download_llvm = "download_llvm",
_download_llvm_preconfigured = "download_llvm_preconfigured",
)
load(
"@com_grail_bazel_toolchain//toolchain/internal:sysroot.bzl",
_sysroot_path = "sysroot_path",
)
def _makevars_ld_flags(rctx):
if rctx.os.name == "mac os x":
return ""
# lld, as of LLVM 7, is experimental for Mach-O, so we use it only on linux.
return "-fuse-ld=lld"
def llvm_toolchain_impl(rctx):
repo_path = str(rctx.path(""))
relative_path_prefix = "external/%s/" % rctx.name
if rctx.attr.absolute_paths:
toolchain_path_prefix = (repo_path + "/")
else:
toolchain_path_prefix = relative_path_prefix
sysroot_path, sysroot = _sysroot_path(rctx)
substitutions = {
"%{llvm_version}": rctx.attr.llvm_version,
"%{toolchain_path_prefix}": toolchain_path_prefix,
"%{tools_path_prefix}": (repo_path + "/") if rctx.attr.absolute_paths else "",
"%{debug_toolchain_path_prefix}": relative_path_prefix,
"%{sysroot_path}": sysroot_path,
"%{sysroot_prefix}": "%sysroot%" if sysroot_path else "",
"%{sysroot_label}": "\"%s\"" % str(sysroot) if sysroot else "",
"%{absolute_toolchain_path}": repo_path,
"%{absolute_paths}": "True" if rctx.attr.absolute_paths else "False",
"%{makevars_ld_flags}": _makevars_ld_flags(rctx),
}
rctx.template(
"CROSSTOOL",
Label("@com_grail_bazel_toolchain//toolchain:CROSSTOOL.tpl"),
substitutions,
)
rctx.template(
"bin/cc_wrapper.sh", # Co-located with the linker to help rules_go.
Label("@com_grail_bazel_toolchain//toolchain:cc_wrapper.sh.tpl"),
substitutions,
)
rctx.template(
"Makevars",
Label("@com_grail_bazel_toolchain//toolchain:Makevars.tpl"),
substitutions,
)
rctx.template(
"BUILD",
Label("@com_grail_bazel_toolchain//toolchain:BUILD.tpl"),
substitutions,
)
rctx.symlink("/usr/bin/ar", "bin/ar") # For GoLink.
# For GoCompile on macOS; compiler path is set from linker path.
# It also helps clang driver sometimes for the linker to be colocated with the compiler.
rctx.symlink("/usr/bin/ld", "bin/ld")
if rctx.os.name == "linux":
rctx.symlink("/usr/bin/ld.gold", "bin/ld.gold")
else:
# Add dummy file for non-linux so we don't have to put conditional logic in BUILD.
rctx.file("bin/ld.gold")
# Repository implementation functions can be restarted, keep expensive ops at the end.
if not _download_llvm(rctx):
_download_llvm_preconfigured(rctx)
def conditional_cc_toolchain(name, cpu, darwin, absolute_paths = False):
# Toolchain macro for BUILD file to use conditional logic.
if absolute_paths:
native.cc_toolchain(
name = name,
toolchain_identifier = "clang-darwin" if darwin else "clang-linux",
cpu = cpu,
all_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
linker_files = ":empty",
objcopy_files = ":empty",
static_runtime_libs = [":empty"],
strip_files = ":empty",
supports_param_files = 0 if darwin else 1,
)
else:
extra_files = [":cc_wrapper"] if darwin else []
native.filegroup(name = name + "-all-files", srcs = [":all_components"] + extra_files)
native.filegroup(name = name + "-compiler-files", srcs = [":compiler_components"] + extra_files)
native.filegroup(name = name + "-linker-files", srcs = [":linker_components"] + extra_files)
native.cc_toolchain(
name = name,
toolchain_identifier = "clang-darwin" if darwin else "clang-linux",
cpu = cpu,
all_files = name + "-all-files",
compiler_files = name + "-compiler-files",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
linker_files = name + "-linker-files",
objcopy_files = ":objcopy",
static_runtime_libs = [":empty"],
strip_files = ":empty",
supports_param_files = 0 if darwin else 1,
)

View File

@ -0,0 +1,106 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# If a new LLVM version is missing from this list, please add the shasum here
# and send a PR on github. To compute the shasum block, you can use the script
# utils/llvm_checksums.sh
_llvm_distributions = {
# 6.0.0
"clang+llvm-6.0.0-aarch64-linux-gnu.tar.xz": "69382758842f29e1f84a41208ae2fd0fae05b5eb7f5531cdab97f29dda3c2334",
"clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz": "fee8352f5dee2e38fa2bb80ab0b5ef9efef578cbc6892e5c724a1187498119b7",
"clang+llvm-6.0.0-armv7a-linux-gnueabihf.tar.xz": "4fda22e3d80994f343bfbdcae60f75e63ad44eb0998c59c559d706c11dd87b76",
"clang+llvm-6.0.0-i386-unknown-freebsd-10.tar.xz": "13414a66b680760171e04f32071396eb6e5a179ff0b5a067d48c4b23744840f1",
"clang+llvm-6.0.0-i686-linux-gnu-Fedora27.tar.xz": "2619e0a2542eec997daed3c7e597d99d5800cc3a07500b359429541a260d0207",
"clang+llvm-6.0.0-mips-linux-gnu.tar.xz": "39820007ef6b2e3a4d05ec15feb477ce6e4e6e90180d00326e6ab9982ed8fe82",
"clang+llvm-6.0.0-mipsel-linux-gnu.tar.xz": "5ff062f4838ac51a3500383faeb0731440f1c4473bf892258314a49cbaa66e61",
"clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz": "0ef8e99e9c9b262a53ab8f2821e2391d041615dd3f3ff36fdf5370916b0f4268",
"clang+llvm-6.0.0-x86_64-linux-gnu-Fedora27.tar.xz": "2aada1f1a973d5d4d99a30700c4b81436dea1a2dcba8dd965acf3318d3ea29bb",
"clang+llvm-6.0.0-x86_64-linux-gnu-debian8.tar.xz": "ff55cd0bdd0b67e22d1feee2e4c84dedc3bb053401330b64c7f6ac18e88a71f1",
"clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz": "114e78b2f6db61aaee314c572e07b0d635f653adc5d31bd1cd0bf31a3db4a6e5",
"clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz": "cc99fda45b4c740f35d0a367985a2bf55491065a501e2dd5d1ad3f97dcac89da",
"clang+llvm-6.0.0-x86_64-linux-sles11.3.tar.xz": "1d4d30ebe4a7e5579644235b46513a1855d3ece865f7cc5ccd0ac5113c461ee7",
"clang+llvm-6.0.0-x86_64-linux-sles12.2.tar.xz": "c144e17aab8dce8e8823a7a891067e27fd0686a49d8a3785cb64b0e51f08e2ee",
# 6.0.1
"clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz": "6d1f67c9e7c3481106d5c9bfcb8a75e3876eb17a446a14c59c13cafd000c21d2",
"clang+llvm-6.0.1-i386-unknown-freebsd10.tar.xz": "c6f65f2c42fa02e3b7e508664ded9b7a91ebafefae368dfa84b3d68811bcb924",
"clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz": "fa5416553ca94a8c071a27134c094a5fb736fe1bd0ecc5ef2d9bc02754e1bef0",
"clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz": "7ea204ecd78c39154d72dfc0d4a79f7cce1b2264da2551bb2eef10e266d54d91",
"clang+llvm-6.0.1-x86_64-linux-sles11.3.tar.xz": "d128e2a7ea8b42418ec58a249e886ec2c736cbbbb08b9e11f64eb281b62bc574",
"clang+llvm-6.0.1-x86_64-linux-sles12.3.tar.xz": "79c74f4764d13671285412d55da95df42b4b87064785cde3363f806dbb54232d",
# 7.0.0
"clang+llvm-7.0.0-amd64-unknown-freebsd-10.tar.xz": "95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255",
"clang+llvm-7.0.0-i386-unknown-freebsd-10.tar.xz": "35460d34a8b3d856e0d7c0b2b20d31f0d1ec05908c830a81f586721e8f8fb04f",
"clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz": "b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca",
"clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz": "5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a",
"clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz": "69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2",
"clang+llvm-7.0.0-x86_64-linux-sles11.3.tar.xz": "1a0a94a5cef357b885d02cf46b66109b6233f0af8f02be3da08e2daf646b5cf8",
"clang+llvm-7.0.0-x86_64-linux-sles12.3.tar.xz": "1c303f1a7b90f0f1988387dfab16f1eadbe2b2152d86a323502068379941dd17",
}
def download_llvm_preconfigured(rctx):
llvm_version = rctx.attr.llvm_version
url_base = []
if rctx.attr.llvm_mirror:
url_base += [rctx.attr.llvm_mirror]
url_base += ["https://releases.llvm.org"]
if rctx.attr.distribution == "auto":
exec_result = rctx.execute([
rctx.path(rctx.attr._llvm_release_name),
llvm_version,
])
if exec_result.return_code:
fail("Failed to detect host OS version: \n%s\n%s" % (exec_result.stdout, exec_result.stderr))
if exec_result.stderr:
print(exec_result.stderr)
basename = exec_result.stdout.strip()
else:
basename = rctx.attr.distribution
if basename not in _llvm_distributions:
fail("Unknown LLVM release: %s\nPlease ensure file name is correct." % basename)
urls = [
(base + "/{0}/{1}".format(llvm_version, basename)).replace("+", "%2B")
for base in url_base
]
rctx.download_and_extract(
urls,
sha256 = _llvm_distributions[basename],
stripPrefix = basename[:(len(basename) - len(".tar.xz"))],
)
# Download LLVM from the user-provided URLs and return True. If URLs were not provided, return
# False.
def download_llvm(rctx):
if rctx.os.name == "linux":
urls = rctx.attr.urls.get("linux", default = [])
sha256 = rctx.attr.sha256.get("linux", default = "")
prefix = rctx.attr.strip_prefix.get("linux", default = "")
elif rctx.os.name == "mac os x":
urls = rctx.attr.urls.get("darwin", default = [])
sha256 = rctx.attr.sha256.get("darwin", default = "")
prefix = rctx.attr.strip_prefix.get("darwin", default = "")
else:
fail("Unsupported OS: " + rctx.os.name)
if not urls:
return False
rctx.download_and_extract(urls, sha256 = sha256, stripPrefix = prefix)
return True

View File

@ -0,0 +1,51 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
def _darwin_sdk_path(rctx):
if rctx.os.name != "mac os x":
return ""
exec_result = rctx.execute(["/usr/bin/xcrun", "--show-sdk-path", "--sdk", "macosx"])
if exec_result.return_code:
fail("Failed to detect OSX SDK path: \n%\n%s" % (exec_result.stdout, exec_result.stderr))
if exec_result.stderr:
print(exec_result.stderr)
return exec_result.stdout.strip()
def _default_sysroot(rctx):
if rctx.os.name == "mac os x":
return _darwin_sdk_path(rctx)
else:
return ""
# Return the sysroot path and the label to the files, if sysroot is not a system path.
def sysroot_path(rctx):
if rctx.os.name == "linux":
sysroot = rctx.attr.sysroot.get("linux", default = "")
elif rctx.os.name == "mac os x":
sysroot = rctx.attr.sysroot.get("darwin", default = "")
else:
fail("Unsupported OS: " + rctx.os.name)
if not sysroot:
return (_default_sysroot(rctx), None)
if sysroot[0] == "/" and sysroot[1] != "/":
return (sysroot, None)
sysroot = Label(sysroot)
if sysroot.workspace_root:
return (sysroot.workspace_root + "/" + sysroot.package, sysroot)
else:
return (sysroot.package, sysroot)

70
toolchain/rules.bzl Normal file
View File

@ -0,0 +1,70 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load(
"@com_grail_bazel_toolchain//toolchain/internal:configure.bzl",
"conditional_cc_toolchain",
_llvm_toolchain_impl = "llvm_toolchain_impl",
)
llvm_toolchain = repository_rule(
attrs = {
"llvm_version": attr.string(
default = "6.0.0",
doc = "One of the supported versions of LLVM.",
),
"distribution": attr.string(
default = "auto",
doc = ("LLVM pre-built binary distribution filename, must be one " +
"listed on http://releases.llvm.org/download.html for the version " +
"specified in the llvm_version attribute. A special value of " +
"'auto' tries to detect the version based on host OS."),
),
"sysroot": attr.string_dict(
mandatory = False,
doc = ("System path or fileset for each OS type (linux and darwin) used to indicate " +
"the set of files that form the sysroot for the compiler. If the value begins " +
"with exactly one forward slash '/', then the value is assumed to be a system " +
"path. Else, the value will be assumed to be a label containing the files and " +
"the sysroot path will be taken as the path to the package of this label."),
),
"llvm_mirror": attr.string(
doc = "Mirror base for LLVM binaries if using the pre-configured URLs.",
),
"absolute_paths": attr.bool(
default = False,
doc = "Whether to use absolute paths in CROSSTOOL. Avoids sandbox overhead.",
),
"_llvm_release_name": attr.label(
default = "@com_grail_bazel_toolchain//toolchain/tools:llvm_release_name.py",
allow_single_file = True,
doc = "Python module to output LLVM release name for the current OS.",
),
# Following attributes are needed only when using a non-standard URL scheme.
"urls": attr.string_list_dict(
mandatory = False,
doc = "URLs for each OS type (linux and darwin) if not using the pre-configured URLs.",
),
"sha256": attr.string_dict(
mandatory = False,
doc = "sha256 of the archive for each OS type.",
),
"strip_prefix": attr.string_dict(
mandatory = False,
doc = "Path prefix to strip from the extracted files.",
),
},
local = False,
implementation = _llvm_toolchain_impl,
)

View File

@ -0,0 +1,15 @@
# Copyright 2018 The Bazel Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
exports_files(["llvm_release_name.py"])