Merge LLVM and Bazel infra from the toolchain repository. (#207)

The Bazel bits are collected into a directory and given less confusing
names (I hope). Other than names, everything is a direct copy from the
toolchain repository without any edits.

A few files needed to be merged in:
- `.gitignore`
- `.pre-commit-config.yaml`

Subsequent commits will add relevant C++ infrastructure and then the
source code itself.
This commit is contained in:
Chandler Carruth
2020-12-04 19:26:07 -08:00
committed by GitHub
parent e3584dce01
commit 6aae31b65b
16 changed files with 1109 additions and 1 deletions
+8
View File
@@ -0,0 +1,8 @@
# 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
build --crosstool_top=@bazel_cc_toolchain
build --host_crosstool_top=@bazel_cc_toolchain
build:fuzzer --features=fuzzer
+1
View File
@@ -0,0 +1 @@
last_green
+1
View File
@@ -3,3 +3,4 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
**/__pycache__/
/bazel-*
+11
View File
@@ -0,0 +1,11 @@
# 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
[submodule "third_party/llvm-bazel"]
path = third_party/llvm-bazel
url = https://github.com/google/llvm-bazel.git
fetchRecurseSubmodules = false
[submodule "third_party/llvm-project"]
path = third_party/llvm-project
url = https://github.com/llvm/llvm-project.git
+4 -1
View File
@@ -34,7 +34,7 @@ repos:
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
exclude: '^website/(firebase/.firebaserc|jekyll/(Gemfile.lock|theme/.*))$'
exclude: '^(website/(firebase/.firebaserc|jekyll/(Gemfile.lock|theme/.*))|.bazelversion|compile_flags.txt|.*\.def)$'
- id: check-google-doc-style
- id: markdown-toc
- repo: https://github.com/codespell-project/codespell
@@ -67,3 +67,6 @@ repos:
rev: 3.8.4
hooks:
- id: flake8
# We fully exclude fuzzer corpus directories as they are generated binary data.
exclude: '^(.*/fuzzer_corpus/.*)$'
+3
View File
@@ -0,0 +1,3 @@
# 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
+48
View File
@@ -0,0 +1,48 @@
# 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
workspace(name = "carbon")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# We want to use LLVM via an external CMake build, so pull in the Bazel
# infrastructure that provides direct CMake interfacing support.
http_archive(
name = "rules_foreign_cc",
strip_prefix = "rules_foreign_cc-master",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/master.zip",
)
# Set up necessary dependencies for working with the foreign C++ rules.
load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies")
rules_foreign_cc_dependencies()
# Detect and configure a Clang and LLVM based toolchain.
load("//bazel/cc_toolchains:clang_detection.bzl", "detect_clang_toolchain")
detect_clang_toolchain(name = "bazel_cc_toolchain")
local_repository(
name = "llvm_bazel",
path = "third_party/llvm-bazel/llvm-bazel",
)
load("@llvm_bazel//:configure.bzl", "llvm_configure")
llvm_configure(
name = "llvm-project",
src_path = "third_party/llvm-project",
src_workspace = "@carbon//:WORKSPACE",
)
load("@llvm_bazel//:terminfo.bzl", "llvm_terminfo_system")
# We require successful detection and use of a system terminfo library.
llvm_terminfo_system(name = "llvm_terminfo")
load("@llvm_bazel//:zlib.bzl", "llvm_zlib_system")
# We require successful detection and use of a system zlib library.
llvm_zlib_system(name = "llvm_zlib")
+6
View File
@@ -0,0 +1,6 @@
# 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
# Empty `BUILD` file as this package just provides repository rule inputs to
# configure a Clang toolchain.
@@ -0,0 +1,725 @@
# 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(
"@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
"action_config",
"feature",
"feature_set",
"flag_group",
"flag_set",
"tool",
"tool_path",
"variable_with_value",
"with_feature_set",
)
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load(
":clang_detected_variables.bzl",
"clang_include_dirs_list",
"clang_resource_dir",
"llvm_bindir",
)
all_compile_actions = [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.cpp_module_codegen,
]
all_cpp_compile_actions = [
ACTION_NAMES.cpp_compile,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.cpp_module_codegen,
]
preprocessor_compile_actions = [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
]
codegen_compile_actions = [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.cpp_module_codegen,
]
all_link_actions = [
ACTION_NAMES.cpp_link_executable,
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
]
def _impl(ctx):
tool_paths = [
tool_path(name = "ar", path = llvm_bindir + "/llvm-ar"),
tool_path(name = "ld", path = llvm_bindir + "/ld.lld"),
tool_path(name = "cpp", path = llvm_bindir + "/clang-cpp"),
tool_path(name = "gcc", path = llvm_bindir + "/clang"),
tool_path(name = "dwp", path = llvm_bindir + "/llvm-dwp"),
tool_path(name = "gcov", path = llvm_bindir + "/llvm-cov"),
tool_path(name = "nm", path = llvm_bindir + "/llvm-nm"),
tool_path(name = "objcopy", path = llvm_bindir + "/llvm-objcopy"),
tool_path(name = "objdump", path = llvm_bindir + "/llvm-objdump"),
tool_path(name = "strip", path = llvm_bindir + "/llvm-strip"),
]
action_configs = [
action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/clang")])
for name in [ACTION_NAMES.c_compile]
] + [
action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/clang++")])
for name in all_cpp_compile_actions
] + [
action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/clang++")])
for name in all_link_actions
] + [
action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/llvm-ar")])
for name in [ACTION_NAMES.cpp_link_static_library]
] + [
action_config(action_name = name, enabled = True, tools = [tool(path = llvm_bindir + "/llvm-strip")])
for name in [ACTION_NAMES.strip]
]
default_compile_flags_feature = feature(
name = "default_compile_flags",
enabled = True,
flag_sets = [
flag_set(
actions = all_compile_actions,
flag_groups = ([
flag_group(
flags = [
"-Wall",
"-Wextra",
"-Wthread-safety",
"-Wself-assign",
# Unfortunately, LLVM isn't clean for this warning.
"-Wno-unused-parameter",
# We use partial sets of designated initializers in
# test code.
"-Wno-missing-field-initializers",
"-fcolor-diagnostics",
],
),
]),
),
flag_set(
actions = [
ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.cpp_header_parsing,
],
flag_groups = [
flag_group(
flags = ["-MD", "-MF", "%{dependency_file}"],
expand_if_available = "dependency_file",
),
],
),
flag_set(
actions = [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_module_codegen,
ACTION_NAMES.cpp_module_compile,
],
flag_groups = [
flag_group(
flags = ["-frandom-seed=%{output_file}"],
expand_if_available = "output_file",
),
],
),
flag_set(
actions = [
ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_module_codegen,
ACTION_NAMES.cpp_module_compile,
],
flag_groups = [
flag_group(flags = ["-fPIC"], expand_if_available = "pic"),
],
),
flag_set(
actions = [
ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_module_codegen,
],
flag_groups = [
flag_group(
flags = ["-gsplit-dwarf"],
expand_if_available = "per_object_debug_info_file",
),
],
),
flag_set(
actions = [
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
],
flag_groups = [
flag_group(
flags = ["-D%{preprocessor_defines}"],
iterate_over = "preprocessor_defines",
),
],
),
flag_set(
actions = [
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
],
flag_groups = [
flag_group(
flags = ["-include", "%{includes}"],
iterate_over = "includes",
expand_if_available = "includes",
),
],
),
flag_set(
actions = [
ACTION_NAMES.preprocess_assemble,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
],
flag_groups = [
flag_group(
flags = ["-iquote", "%{quote_include_paths}"],
iterate_over = "quote_include_paths",
),
flag_group(
flags = ["-I%{include_paths}"],
iterate_over = "include_paths",
),
flag_group(
flags = ["-isystem", "%{system_include_paths}"],
iterate_over = "system_include_paths",
),
],
),
flag_set(
actions = all_compile_actions,
flag_groups = ([
flag_group(
flags = ["-g"],
),
]),
with_features = [with_feature_set(features = ["dbg"])],
),
flag_set(
actions = all_compile_actions,
flag_groups = ([
flag_group(
flags = [
"-g0",
"-O3",
"-DNDEBUG",
"-ffunction-sections",
"-fdata-sections",
# Even when optimizing, preserve frame pointers for profiling.
"-fno-omit-frame-pointer",
"-mno-omit-leaf-frame-pointer",
],
),
]),
with_features = [with_feature_set(features = ["opt"])],
),
flag_set(
actions = all_cpp_compile_actions,
flag_groups = ([
flag_group(
flags = [
"-std=c++17",
"-stdlib=libc++",
],
),
]),
),
flag_set(
actions = all_compile_actions,
flag_groups = [
flag_group(
flags = ["%{user_compile_flags}"],
iterate_over = "user_compile_flags",
expand_if_available = "user_compile_flags",
),
],
),
flag_set(
actions = all_compile_actions,
flag_groups = ([
flag_group(
flags = [
"-no-canonical-prefixes",
"-Wno-builtin-macro-redefined",
"-D__DATE__=\"redacted\"",
"-D__TIMESTAMP__=\"redacted\"",
"-D__TIME__=\"redacted\"",
],
),
]),
),
flag_set(
actions = all_compile_actions,
flag_groups = [
flag_group(
expand_if_available = "source_file",
flags = ["-c", "%{source_file}"],
),
flag_group(
expand_if_available = "output_assembly_file",
flags = ["-S"],
),
flag_group(
expand_if_available = "output_preprocess_file",
flags = ["-E"],
),
flag_group(
expand_if_available = "output_file",
flags = ["-o", "%{output_file}"],
),
],
),
],
)
default_link_flags_feature = feature(
name = "default_link_flags",
enabled = True,
flag_sets = [
flag_set(
actions = [
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
],
flag_groups = [flag_group(flags = ["-shared"])],
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
flags = ["%{linkstamp_paths}"],
iterate_over = "linkstamp_paths",
expand_if_available = "linkstamp_paths",
),
],
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
flags = ["-o", "%{output_execpath}"],
expand_if_available = "output_execpath",
),
],
),
flag_set(
actions = [
ACTION_NAMES.cpp_link_executable,
],
flag_groups = [
flag_group(
flags = ["-pie"],
expand_if_available = "force_pic",
),
],
),
flag_set(
actions = all_link_actions,
flag_groups = ([
flag_group(
flags = [
"-fuse-ld=lld",
"-Wl,-no-as-needed",
# Force the C++ standard library to be statically
# linked. This works even with libc++ despite the
# name, however we have to manually link the ABI
# library and libunwind.
"-static-libstdc++",
# Link with libc++.
"-stdlib=libc++",
# Force static linking with libc++abi as well.
"-l:libc++abi.a",
# Link with Clang's runtime library. This is always
# linked statically.
#"-rtlib=compiler-rt",
],
),
]),
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
flags = ["-L%{library_search_directories}"],
iterate_over = "library_search_directories",
expand_if_available = "library_search_directories",
),
],
),
flag_set(
flag_groups = [
flag_group(
iterate_over = "runtime_library_search_directories",
flags = [
"-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
],
expand_if_available =
"runtime_library_search_directories",
),
],
actions = all_link_actions,
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
flags = ["-Wl,--gdb-index"],
expand_if_available = "is_using_fission",
),
],
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
flags = ["-Wl,-S"],
expand_if_available = "strip_debug_symbols",
),
],
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
iterate_over = "libraries_to_link",
flag_groups = [
flag_group(
flags = ["-Wl,--start-lib"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
flag_group(
flags = ["-Wl,-whole-archive"],
expand_if_true =
"libraries_to_link.is_whole_archive",
),
flag_group(
flags = ["%{libraries_to_link.object_files}"],
iterate_over = "libraries_to_link.object_files",
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file",
),
),
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "interface_library",
),
),
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "static_library",
),
),
flag_group(
flags = ["-l%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "dynamic_library",
),
),
flag_group(
flags = ["-l:%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "versioned_dynamic_library",
),
),
flag_group(
flags = ["-Wl,-no-whole-archive"],
expand_if_true = "libraries_to_link.is_whole_archive",
),
flag_group(
flags = ["-Wl,--end-lib"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
],
expand_if_available = "libraries_to_link",
),
],
),
flag_set(
actions = all_link_actions,
flag_groups = [
flag_group(
flags = ["%{user_link_flags}"],
iterate_over = "user_link_flags",
expand_if_available = "user_link_flags",
),
],
),
flag_set(
actions = [
ACTION_NAMES.cpp_link_static_library,
] + all_link_actions,
flag_groups = [
flag_group(
expand_if_available = "linker_param_file",
flags = ["@%{linker_param_file}"],
),
],
),
],
)
sysroot_feature = feature(
name = "sysroot",
enabled = True,
flag_sets = [
flag_set(
actions = all_compile_actions + all_link_actions,
flag_groups = [
flag_group(
flags = ["--sysroot=%{sysroot}"],
expand_if_available = "sysroot",
),
],
),
],
)
default_archiver_flags_feature = feature(
name = "default_archiver_flags",
enabled = True,
flag_sets = [
flag_set(
actions = [ACTION_NAMES.cpp_link_static_library],
flag_groups = [
flag_group(flags = ["rcsD"]),
flag_group(
flags = ["%{output_execpath}"],
expand_if_available = "output_execpath",
),
],
),
flag_set(
actions = [ACTION_NAMES.cpp_link_static_library],
flag_groups = [
flag_group(
iterate_over = "libraries_to_link",
flag_groups = [
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file",
),
),
flag_group(
flags = ["%{libraries_to_link.object_files}"],
iterate_over = "libraries_to_link.object_files",
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
],
expand_if_available = "libraries_to_link",
),
],
),
],
)
use_module_maps = feature(
name = "use_module_maps",
requires = [feature_set(features = ["module_maps"])],
flag_sets = [
flag_set(
actions = [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_compile,
],
flag_groups = [
# These flag groups are separate so they do not expand to
# the cross product of the variables.
flag_group(flags = ["-fmodule-name=%{module_name}"]),
flag_group(
flags = ["-fmodule-map-file=%{module_map_file}"],
),
],
),
],
)
# Tell bazel we support module maps in general, so they will be generated
# for all c/c++ rules.
# Note: not all C++ rules support module maps; thus, do not imply this
# feature from other features - instead, require it.
module_maps = feature(
name = "module_maps",
enabled = True,
implies = [
# "module_map_home_cwd",
# "module_map_without_extern_module",
# "generate_submodules",
],
)
layering_check = feature(
name = "layering_check",
implies = ["use_module_maps"],
flag_sets = [
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 = [
"-fmodules-strict-decluse",
"-Wprivate-header",
]),
flag_group(
iterate_over = "dependent_module_map_files",
flags = [
"-fmodule-map-file=%{dependent_module_map_files}",
],
),
],
),
],
)
fuzzer = feature(
name = "fuzzer",
flag_sets = [
flag_set(
actions = all_compile_actions + all_link_actions,
flag_groups = [
flag_group(
flags = ["-fsanitize=fuzzer,address"],
),
],
),
flag_set(
actions = all_link_actions,
flag_groups = ([
flag_group(
flags = [
"-static-libsan",
],
),
]),
),
],
)
features = [
feature(
name = "no_legacy_features",
),
feature(
name = "supports_pic",
enabled = True,
),
feature(
name = "supports_start_end_lib",
enabled = True,
),
default_compile_flags_feature,
default_archiver_flags_feature,
default_link_flags_feature,
feature(name = "supports_dynamic_linker", enabled = True),
feature(name = "dbg"),
feature(name = "opt"),
sysroot_feature,
fuzzer,
module_maps,
layering_check,
use_module_maps,
]
return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
features = features,
action_configs = action_configs,
cxx_builtin_include_directories = clang_include_dirs_list + [
# Append the share directory for sanitizer data files.
clang_resource_dir + "/share",
],
toolchain_identifier = "local",
host_system_name = "local",
target_system_name = "local",
target_cpu = "k8",
target_libc = "local",
compiler = "local",
abi_version = "local",
abi_libc_version = "local",
tool_paths = tool_paths,
)
cc_toolchain_config = rule(
implementation = _impl,
provides = [CcToolchainConfigInfo],
)
@@ -0,0 +1,13 @@
# 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 detected Clang configuration variables.
This file gets processed by a repository rule, substituting the
`{VARIABLE}`s with values detected by invoking Clang.
"""
llvm_bindir = "{LLVM_BINDIR}"
clang_resource_dir = "{CLANG_RESOURCE_DIR}"
clang_include_dirs_list = {CLANG_INCLUDE_DIRS_LIST}
+169
View File
@@ -0,0 +1,169 @@
# 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 repository rules to detect and configure Clang (and LLVM) toolchain.
These rules should be run from the `WORKSPACE` file to substitute appropriate
configured values into a `clang_detected_variables.bzl` file that can be used
by the actual toolchain configuration.
"""
# Tools that we verify are present as part of the detected Clang & LLVM toolchain.
_CLANG_LLVM_TOOLS = [
"llvm-ar",
"ld.lld",
"clang-cpp",
"clang",
"clang++",
"llvm-dwp",
"llvm-cov",
"llvm-nm",
"llvm-objcopy",
"llvm-strip",
]
def _run(repository_ctx, cmd):
"""Runs the provided `cmd`, checks for failure, and returns the result."""
exec_result = repository_ctx.execute(cmd, timeout = 10)
if exec_result.return_code != 0:
fail("Unable to run command successfully: %s" % str(cmd))
return exec_result
def _find_clang(repository_ctx):
"""Returns the path to a Clang executable if it can find one.
This assumes the `CC` environment variable points to a Clang binary or
looks for one on the path.
"""
cc_env = repository_ctx.os.environ.get("CC")
if not cc_env:
# Without a specified `CC` name, simply look for `clang`.
clang = repository_ctx.which("clang")
elif "/" not in cc_env:
# Lookup relative `CC` names according to the system `PATH`.
clang = repository_ctx.which(cc_env)
else:
# An absolute `CC` path is simply be used directly.
clang = repository_ctx.path(cc_env)
if not clang.exists:
fail(("The `CC` environment variable is set to a path (`%s`) " +
"that doesn't exist.") % cc_env)
# Check if either of the `which` invocations fail.
if not clang:
missing = "`clang`"
if cc_env:
missing = "`%s` (from the `CC` environment variable)" % cc_env
fail("Unable to find the %s executable on the PATH." % missing)
version_output = _run(repository_ctx, [clang, "--version"]).stdout
if "clang" not in version_output:
fail(("Selected Clang executable (`%s`) does not appear to actually " +
"be Clang.") % clang)
# Make sure this is part of a complete Clang and LLVM toolchain.
for tool in _CLANG_LLVM_TOOLS:
if not clang.dirname.get_child(tool).exists:
fail(("Couldn't find executable `%s` that is expected to be part " +
"of the Clang and LLVM toolchain detected with `%s`.") %
(tool, clang))
return clang
def _compute_clang_resource_dir(repository_ctx, clang):
"""Runs the `clang` binary to get its resource dir."""
output = _run(
repository_ctx,
[clang, "-no-canonical-prefixes", "--print-resource-dir"],
).stdout
# The only line printed is this path.
return output.splitlines()[0]
def _compute_clang_cpp_include_search_paths(repository_ctx, clang):
"""Runs the `clang` binary and extracts the include search paths.
Returns the resulting paths as a list of strings.
"""
# The only way to get this out of Clang currently is to parse the verbose
# output of the compiler when it is compiling C++ code.
cmd = [
clang,
# Avoid canonicalizing away symlinks.
"-no-canonical-prefixes",
# Extract verbose output.
"-v",
# Just parse the input, don't generate outputs.
"-fsyntax-only",
# Use libc++ rather than any other standard library.
"-stdlib=libc++",
# Force the language to be C++.
"-x",
"c++",
# Read in an empty input file.
"/dev/null",
]
# Note that verbose output is on stderr, not stdout!
output = _run(repository_ctx, cmd).stderr.splitlines()
# Return the list of directories printed for system headers. These are the
# only ones that Bazel needs us to manually provide. We find these by
# searching for a begin and end marker. We also have to strip off a leading
# space from each path.
include_begin = output.index("#include <...> search starts here:") + 1
include_end = output.index("End of search list.", include_begin)
return [
repository_ctx.path(s.lstrip(" "))
for s in output[include_begin:include_end]
]
def _detect_clang_toolchain_impl(repository_ctx):
# First just symlink in the untemplated parts of the toolchain repo.
repository_ctx.symlink(repository_ctx.attr._clang_toolchain_build, "BUILD")
repository_ctx.symlink(
repository_ctx.attr._clang_cc_toolchain_config,
"cc_toolchain_config.bzl",
)
clang = _find_clang(repository_ctx)
resource_dir = _compute_clang_resource_dir(repository_ctx, clang)
include_dirs = _compute_clang_cpp_include_search_paths(
repository_ctx,
clang,
)
repository_ctx.template(
"clang_detected_variables.bzl",
repository_ctx.attr._clang_detected_variables_template,
substitutions = {
"{LLVM_BINDIR}": str(clang.dirname),
"{CLANG_RESOURCE_DIR}": resource_dir,
"{CLANG_INCLUDE_DIRS_LIST}": str([str(path) for path in include_dirs]),
},
executable = False,
)
detect_clang_toolchain = repository_rule(
implementation = _detect_clang_toolchain_impl,
configure = True,
local = True,
attrs = {
"_clang_toolchain_build": attr.label(
default = Label("//bazel/cc_toolchains:clang_toolchain.BUILD"),
allow_single_file = True,
),
"_clang_cc_toolchain_config": attr.label(
default = Label("//bazel/cc_toolchains:clang_cc_toolchain_config.bzl"),
allow_single_file = True,
),
"_clang_detected_variables_template": attr.label(
default = Label("//bazel/cc_toolchains:clang_detected_variables.tpl.bzl"),
allow_single_file = True,
),
},
environ = ["CC"],
)
+44
View File
@@ -0,0 +1,44 @@
# 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
# This file is symlinked into a configured Clang toolchain repository as the
# root `BUILD` file for that repository.
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_toolchain", "cc_toolchain_suite")
load(":cc_toolchain_config.bzl", "cc_toolchain_config")
cc_library(
name = "malloc",
)
filegroup(
name = "empty",
srcs = [],
)
cc_toolchain_suite(
name = "bazel_cc_toolchain",
toolchains = {
"k8": ":cc-compiler-k8",
},
)
cc_toolchain(
name = "cc-compiler-k8",
all_files = ":empty",
ar_files = ":empty",
as_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
linker_files = ":empty",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 1,
toolchain_config = ":local",
toolchain_identifier = "local",
)
cc_toolchain_config(
name = "local",
)
+5
View File
@@ -0,0 +1,5 @@
# 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
# Empty BUILD file to allow access to Bazel extensions.
+51
View File
@@ -0,0 +1,51 @@
# 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
"""Rules for building fuzz tests."""
load("@rules_cc//cc:defs.bzl", "cc_test")
def cc_fuzz_test(
name,
corpus = None,
args = [],
data = [],
features = [],
tags = [],
**kwargs):
"""Macro for C++ fuzzing test.
Args:
name: The main fuzz test rule name.
corpus: List of files to use as a fuzzing corpus.
args: Will have the locations of the corpus files added and passed down
to the fuzz test.
data: Will have the corpus added and passed down to the fuzz test.
features: Will have the "fuzzer" feature added and passed down to the
fuzz test.
tags: Will have "fuzz_test" added and passed down to the fuzz test.
**kwargs: Remaining arguments passed down to the fuzz test.
"""
# Add relevant tag and feature if necessary.
if "fuzz_test" not in tags:
tags = tags + ["fuzz_test"]
if "fuzzer" not in features:
features = features + ["fuzzer"]
# Append the corpus files to the test arguments. When run on a list of
# files rather than a directory, libFuzzer-based fuzzers will perform a
# regression test against the corpus.
if corpus:
data = data + corpus
args = args + ["$(location %s)" % file for file in corpus]
cc_test(
name = name,
args = args,
data = data,
features = features,
tags = tags,
**kwargs
)
Vendored Submodule
+1
Submodule third_party/llvm-bazel added at 1536b141d6
Vendored Executable
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash -eux
# 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
# Ensure the working directory is the script's directory.
cd "$(dirname "$0")"
# Update the `llvm-bazel` project first by just pulling from its HEAD.
git submodule update --remote llvm-bazel
# Find the current LLVM commit in the `llvm-bazel` project.
llvm_commit=$(cd llvm-bazel; git submodule status third_party/llvm-project | awk '/-[0-9a-f]+ / { print substr($1, 2) }')
# Fetch and checkout this commit of LLVM
cd llvm-project
git fetch
git checkout $llvm_commit
cd ..