Skip to content

Commit 806f50b

Browse files
authored
Use source directories for toolchain includes and wrapper tools (#580)
Compile and linker action inputs should now be fully optimized: ``` ➜ tests git:(zbarsky/toolchain) bazel cquery --output=files @llvm_toolchain_with_sysroot//:compiler-files-aarch64-darwin INFO: Found 1 target... external/toolchains_llvm++llvm+llvm_toolchain_llvm/include/c++ external/toolchains_llvm++llvm+llvm_toolchain_llvm/lib/clang/16/include external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/clang external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/clang++ external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/clang-cpp external/toolchains_llvm++llvm+llvm_toolchain_with_sysroot/bin INFO: Elapsed time: 0.308s, Critical Path: 0.00s INFO: 0 processes. INFO: Build completed successfully, 0 total actions ``` I'm not sure why `ar` is in the linker files, perhaps it can be removed. ``` ➜ tests git:(zbarsky/toolchain) bazel cquery --output=files @llvm_toolchain_with_sysroot//:linker-files-aarch64-darwin INFO: Found 1 target... ➜ tests git:(zbarsky/toolchain) ✗ bazel cquery --output=files @llvm_toolchain_with_sysroot//:linker-files-aarch64-darwin INFO: Invocation ID: d6b673ec-b86d-413d-808b-1e8eda884ad0 INFO: Analyzed target @@toolchains_llvm++llvm+llvm_toolchain_with_sysroot//:linker-files-aarch64-darwin (0 packages loaded, 0 targets configured). INFO: Found 1 target... external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/clang external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/clang++ external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/clang-cpp external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/ld.lld external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/ld64.lld external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/wasm-ld external/toolchains_llvm++llvm+llvm_toolchain_llvm/bin/llvm-ar external/toolchains_llvm++llvm+llvm_toolchain_llvm/lib/clang/16/lib external/toolchains_llvm++llvm+llvm_toolchain_llvm/lib/libc++.a external/toolchains_llvm++llvm+llvm_toolchain_llvm/lib/libc++abi.a external/toolchains_llvm++llvm+llvm_toolchain_llvm/lib/libc++experimental.a external/toolchains_llvm++llvm+llvm_toolchain_llvm/lib/libunwind.a external/toolchains_llvm++llvm+llvm_toolchain_with_sysroot/bin INFO: Elapsed time: 0.108s, Critical Path: 0.00s ```
1 parent 61ab025 commit 806f50b

File tree

9 files changed

+106
-58
lines changed

9 files changed

+106
-58
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @rrbutani @jsharpe @fmeum @helly25
1+
* @rrbutani @jsharpe @fmeum @helly25 @dzbarsky

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module(
1919
compatibility_level = 0,
2020
)
2121

22-
bazel_dep(name = "bazel_features", version = "1.36.0")
22+
bazel_dep(name = "bazel_features", version = "1.38.0")
2323
bazel_dep(name = "bazel_skylib", version = "1.5.0")
2424
bazel_dep(name = "aspect_bazel_lib", version = "2.0.0")
2525
bazel_dep(name = "rules_cc", version = "0.2.2")

tests/WORKSPACE

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ local_repository(
2121

2222
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2323

24+
http_archive(
25+
name = "bazel_features",
26+
sha256 = "07271d0f6b12633777b69020c4cb1eb67b1939c0cf84bb3944dc85cc250c0c01",
27+
strip_prefix = "bazel_features-1.38.0",
28+
url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.38.0/bazel_features-v1.38.0.tar.gz",
29+
)
30+
31+
load("@bazel_features//:deps.bzl", "bazel_features_deps")
32+
33+
bazel_features_deps()
34+
2435
http_archive(
2536
name = "aspect_bazel_lib",
2637
sha256 = "6fd3b1e1a38ca744f9664be4627ced80895c7d2ee353891c172f1ab61309c933",
@@ -337,10 +348,6 @@ load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_depende
337348

338349
rules_foreign_cc_dependencies()
339350

340-
load("@bazel_features//:deps.bzl", "bazel_features_deps")
341-
342-
bazel_features_deps()
343-
344351
load("@rules_cc//cc:extensions.bzl", "compatibility_proxy_repo")
345352

346353
compatibility_proxy_repo()

toolchain/BUILD.llvm_repo renamed to toolchain/BUILD.llvm_repo.tpl

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,49 @@ filegroup(
6161
),
6262
)
6363

64+
# This filegroup should only have source directories, not individual files.
65+
# We rely on this assumption in system_module_map.bzl.
66+
filegroup(
67+
name = "cxx_builtin_include",
68+
srcs = [
69+
"include/c++",
70+
"lib/clang/{LLVM_VERSION}/include",
71+
],
72+
)
73+
74+
filegroup(
75+
name = "extra_config_site",
76+
srcs = glob(["include/*/c++/v1/__config_site"], allow_empty = True)
77+
)
78+
6479
filegroup(
6580
name = "bin",
6681
srcs = glob(["bin/**"]),
6782
)
6883

6984
filegroup(
7085
name = "lib",
71-
srcs = glob(
72-
[
73-
"lib/**/libc++*.a",
74-
"lib/**/libunwind.a",
75-
# TODO(zbarsky): `lib/clang/<VERSION>` can be a source directory
76-
"lib/clang/*/lib/**",
77-
# clang_rt.*.o supply crtbegin and crtend sections.
78-
"lib/**/clang_rt.*.o",
79-
],
80-
allow_empty = True,
81-
),
82-
# Include the .dylib files in the linker sandbox even though they will
83-
# not be available at runtime to allow sanitizers to work locally.
84-
# Any library linked from the toolchain to be released should be linked statically.
86+
srcs = [
87+
# Include the .dylib files in the linker sandbox even though they will
88+
# not be available at runtime to allow sanitizers to work locally.
89+
# Any library linked from the toolchain to be released should be linked statically.
90+
"lib/clang/{LLVM_VERSION}/lib",
91+
] + glob([
92+
"lib/**/libc++*.a",
93+
"lib/**/libunwind.a",
94+
]),
95+
)
96+
97+
filegroup(
98+
name = "lib_legacy",
99+
srcs = glob([
100+
# Include the .dylib files in the linker sandbox even though they will
101+
# not be available at runtime to allow sanitizers to work locally.
102+
# Any library linked from the toolchain to be released should be linked statically.
103+
"lib/clang/{LLVM_VERSION}/lib/**",
104+
"lib/**/libc++*.a",
105+
"lib/**/libunwind.a",
106+
]),
85107
)
86108

87109
filegroup(

toolchain/BUILD.toolchain.tpl

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,20 @@ load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite")
1919
load("@toolchains_llvm//toolchain/internal:system_module_map.bzl", "system_module_map")
2020
load("%{cc_toolchain_config_bzl}", "cc_toolchain_config")
2121

22-
# Following filegroup targets are used when not using absolute paths and shared
22+
# This filegroup target is used when not using absolute paths and shared
2323
# between different toolchains.
2424

25-
# Tools symlinked through this repo. This target is for internal use in the toolchain only.
25+
# Tools wrapped and symlinked through this repo. This target is for internal use in the toolchain only.
2626
filegroup(
27-
name = "internal-use-symlinked-tools",
28-
srcs = [%{symlinked_tools}
29-
],
30-
visibility = ["//visibility:private"],
31-
)
32-
33-
# Tools wrapped through this repo. This target is for internal use in the toolchain only.
34-
filegroup(
35-
name = "internal-use-wrapped-tools",
36-
srcs = [
37-
"%{wrapper_bin_prefix}cc_wrapper.sh",
38-
],
27+
name = "internal-use-tools",
28+
srcs = ["%{tools_dir}"],
3929
visibility = ["//visibility:private"],
4030
)
4131

42-
# All internal use files.
4332
filegroup(
44-
name = "internal-use-files",
45-
srcs = [
46-
":internal-use-symlinked-tools",
47-
":internal-use-wrapped-tools",
33+
name = "internal-use-tools-legacy",
34+
srcs = [%{symlinked_tools}
35+
"%{tools_dir}/cc_wrapper.sh",
4836
],
4937
visibility = ["//visibility:private"],
5038
)

toolchain/cc_toolchain_config.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ def cc_toolchain_config(
339339
# https://github.com/llvm/llvm-project/commit/0556138624edf48621dd49a463dbe12e7101f17d
340340
cxx_flags.append("-Xclang")
341341
cxx_flags.append("-fno-cxx-modules")
342+
cxx_flags.append("-Wno-module-import-in-extern-c")
342343

343344
opt_link_flags = ["-Wl,--gc-sections"] if target_os == "linux" else []
344345

toolchain/internal/configure.bzl

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
load("@bazel_features//:features.bzl", "bazel_features")
1516
load("@bazel_skylib//lib:paths.bzl", "paths")
1617
load(
1718
"//toolchain:aliases.bzl",
@@ -76,11 +77,11 @@ def llvm_config_impl(rctx):
7677
if not rctx.attr.toolchain_roots:
7778
toolchain_root = ("@" if BZLMOD_ENABLED else "") + "@%s_llvm//" % rctx.attr.name
7879
else:
79-
(_key, toolchain_root) = _exec_os_arch_dict_value(rctx, "toolchain_roots")
80+
_, toolchain_root = _exec_os_arch_dict_value(rctx, "toolchain_roots")
8081

8182
if not toolchain_root:
8283
fail("LLVM toolchain root missing for ({}, {})".format(os, arch))
83-
(_key, llvm_version) = _exec_os_arch_dict_value(rctx, "llvm_versions")
84+
_, llvm_version = _exec_os_arch_dict_value(rctx, "llvm_versions")
8485
if is_requirement(llvm_version):
8586
llvm_version, distribution, error = required_llvm_release_name_rctx(rctx, llvm_version)
8687
if error:
@@ -231,7 +232,7 @@ def llvm_config_impl(rctx):
231232
"%{cc_toolchain_config_bzl}": str(rctx.attr._cc_toolchain_config_bzl),
232233
"%{cc_toolchains}": cc_toolchains_str,
233234
"%{symlinked_tools}": symlinked_tools_str,
234-
"%{wrapper_bin_prefix}": wrapper_bin_prefix,
235+
"%{tools_dir}": wrapper_bin_prefix.removesuffix("/"),
235236
"%{convenience_targets}": convenience_targets_str,
236237
},
237238
)
@@ -335,7 +336,7 @@ def _cc_toolchain_str(
335336
# TODO: Are there other situations where we can continue?
336337
return ""
337338

338-
extra_files_str = "\":internal-use-files\""
339+
extra_files_str = repr(":internal-use-tools" if bazel_features.rules.merkle_cache_v2 else ":internal-use-tools-legacy")
339340

340341
# C++ built-in include directories.
341342
# This contains both the includes shipped with the compiler as well as the sysroot (or host)
@@ -360,17 +361,24 @@ def _cc_toolchain_str(
360361
"wasip1-wasm32": "wasm32-wasip1",
361362
"wasip1-wasm64": "wasm64-wasip1",
362363
}[target_pair]
364+
363365
cxx_builtin_include_directories = [
364366
toolchain_path_prefix + "include/c++/v1",
367+
toolchain_path_prefix + "lib/clang/{}/include".format(
368+
major_llvm_version if major_llvm_version >= 16 else llvm_version,
369+
),
370+
# Note(zbarsky): We could avoid this path if we renamed `include/{target_system_name}/c++/v1/__config_site` to `include/c++/v1/__config_site` in the LLVM repo.
371+
# However, that would preclude sharing it across multiple toolchain definitions.
365372
toolchain_path_prefix + "include/{}/c++/v1".format(target_system_name),
366-
toolchain_path_prefix + "lib/clang/{}/include".format(llvm_version),
367-
toolchain_path_prefix + "lib/clang/{}/share".format(llvm_version),
368-
toolchain_path_prefix + "lib64/clang/{}/include".format(llvm_version),
369-
toolchain_path_prefix + "lib/clang/{}/include".format(major_llvm_version),
370-
toolchain_path_prefix + "lib/clang/{}/share".format(major_llvm_version),
371-
toolchain_path_prefix + "lib64/clang/{}/include".format(major_llvm_version),
372373
]
373374

375+
# TODO(zbarsky): Not sure if these lib64 paths are actually needed for system toolchains?
376+
if use_absolute_paths_llvm:
377+
cxx_builtin_include_directories.extend([
378+
toolchain_path_prefix + "lib64/clang/{}/include".format(llvm_version),
379+
toolchain_path_prefix + "lib64/clang/{}/include".format(major_llvm_version),
380+
])
381+
374382
sysroot_prefix = ""
375383
if sysroot_path:
376384
sysroot_prefix = "%sysroot%"
@@ -505,17 +513,16 @@ filegroup(name = "strip-files-{suffix}", srcs = [{extra_files_str}])
505513
template = template + """
506514
filegroup(
507515
name = "cxx_builtin_include_files-{suffix}",
508-
srcs = [
509-
"{llvm_dist_label_prefix}clang",
510-
"{llvm_dist_label_prefix}include",
511-
],
516+
srcs = ["{llvm_dist_label_prefix}{cxx_builtin_include_label}"],
512517
)
513518
514519
filegroup(
515520
name = "compiler-components-{suffix}",
516521
srcs = [
517522
":cxx_builtin_include_files-{suffix}",
518523
":sysroot-components-{suffix}",
524+
"{llvm_dist_label_prefix}extra_config_site",
525+
"{llvm_dist_label_prefix}clang",
519526
{extra_compiler_files}
520527
],
521528
)
@@ -526,7 +533,7 @@ filegroup(
526533
"{llvm_dist_label_prefix}clang",
527534
"{llvm_dist_label_prefix}ld",
528535
"{llvm_dist_label_prefix}ar",
529-
"{llvm_dist_label_prefix}lib",
536+
"{llvm_dist_label_prefix}{lib_label}",
530537
":sysroot-components-{suffix}",
531538
],
532539
)
@@ -629,6 +636,8 @@ cc_toolchain(
629636
extra_unfiltered_compile_flags = _list_to_string(_dict_value(toolchain_info.extra_unfiltered_compile_flags_dict, target_pair)),
630637
extra_files_str = extra_files_str,
631638
cxx_builtin_include_directories = _list_to_string(filtered_cxx_builtin_include_directories),
639+
cxx_builtin_include_label = "cxx_builtin_include" if bazel_features.rules.merkle_cache_v2 else "include",
640+
lib_label = "lib" if bazel_features.rules.merkle_cache_v2 else "lib_legacy",
632641
extra_compiler_files = ("\"%s\"," % str(toolchain_info.extra_compiler_files)) if toolchain_info.extra_compiler_files else "",
633642
major_llvm_version = major_llvm_version,
634643
extra_exec_compatible_with_specific = toolchain_info.extra_exec_compatible_with.get(target_pair, []),

toolchain/internal/repo.bzl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
load(
1515
"//toolchain/internal:common.bzl",
1616
_attr_dict = "attr_dict",
17+
_exec_os_arch_dict_value = "exec_os_arch_dict_value",
1718
_os = "os",
1819
_supported_os_arch_keys = "supported_os_arch_keys",
1920
)
@@ -422,9 +423,16 @@ def llvm_repo_impl(rctx):
422423
rctx.file("BUILD.bazel", executable = False)
423424
return None
424425

426+
_, llvm_version = _exec_os_arch_dict_value(rctx, "llvm_versions")
427+
428+
major_llvm_version = int(llvm_version.split(".")[0])
429+
425430
rctx.file(
426431
"BUILD.bazel",
427-
content = rctx.read(Label("//toolchain:BUILD.llvm_repo")),
432+
content = rctx.read(Label("//toolchain:BUILD.llvm_repo.tpl")).format(
433+
# The versioning changed.
434+
LLVM_VERSION = major_llvm_version if major_llvm_version >= 16 else llvm_version,
435+
),
428436
executable = False,
429437
)
430438

toolchain/internal/system_module_map.bzl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
load("@bazel_features//:features.bzl", "bazel_features")
1516
load("@bazel_skylib//lib:paths.bzl", "paths")
1617

1718
def _textual_header(file, *, include_prefixes, execroot_prefix):
@@ -55,20 +56,32 @@ def _system_module_map(ctx):
5556
execroot_prefix = execroot_prefix,
5657
)
5758

59+
umbrella_submodule_closure = lambda file: _umbrella_submodule(
60+
execroot_prefix + paths.normalize(file.path).replace("//", "/"),
61+
)
62+
5863
template_dict = ctx.actions.template_dict()
64+
65+
if bazel_features.rules.merkle_cache_v2:
66+
# If provided, cxx_builtin_files should be a filegroup with 2 source directory entries:
67+
# - include/c++
68+
# - lib/clang/<VERSION>/include
69+
cxx_builtin_include_files_closure = umbrella_submodule_closure
70+
else:
71+
cxx_builtin_include_files_closure = textual_header_closure
72+
5973
template_dict.add_joined(
6074
"%cxx_builtin_include_files%",
6175
ctx.attr.cxx_builtin_include_files[DefaultInfo].files,
6276
join_with = "\n",
63-
map_each = textual_header_closure,
77+
map_each = cxx_builtin_include_files_closure,
6478
allow_closure = True,
6579
)
6680

6781
# We don't have a good way to detect a source directory, so check if it's a single File...
6882
sysroot_files = ctx.attr.sysroot_files[DefaultInfo].files.to_list()
6983
if len(sysroot_files) == 1:
70-
path = paths.normalize(sysroot_files[0].path).replace("//", "/")
71-
template_dict.add("%sysroot%", _umbrella_submodule(execroot_prefix + path))
84+
template_dict.add("%sysroot%", umbrella_submodule_closure(sysroot_files[0]))
7285
else:
7386
if sysroot_files:
7487
# buildifier: disable=print

0 commit comments

Comments
 (0)