mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 13:40:11 +01:00
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:
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
last_green
|
||||
@@ -3,3 +3,4 @@
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
**/__pycache__/
|
||||
/bazel-*
|
||||
|
||||
+11
@@ -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
|
||||
@@ -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/.*)$'
|
||||
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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}
|
||||
@@ -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"],
|
||||
)
|
||||
@@ -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",
|
||||
)
|
||||
@@ -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.
|
||||
@@ -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
|
||||
)
|
||||
+1
Submodule third_party/llvm-bazel added at 1536b141d6
+19
@@ -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 ..
|
||||
Reference in New Issue
Block a user