Begin packaging builtin Clang headers (#4959)

This digs the Clang builtin headers out of the Clang package and
reconfigures them to install into our installation prefix, under the
LLVM installation subtree.

---------

Co-authored-by: Ilya Biryukov <ibiryukov@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Chandler Carruth
2025-02-15 23:03:32 +00:00
committed by GitHub
co-authored by Ilya Biryukov Jon Ross-Perkins
parent a881e21432
commit fe2c0b48cf
4 changed files with 62 additions and 4 deletions
+33
View File
@@ -181,5 +181,38 @@ TEST(ClangRunnerTest, DashC) {
EXPECT_THAT(err, StrEq(""));
}
TEST(ClangRunnerTest, BuitinHeaders) {
std::filesystem::path test_file = WriteTestFile("test.c", R"cpp(
#include <stdalign.h>
#ifndef alignas
#error included the wrong header
#endif
)cpp");
std::filesystem::path test_output = WriteTestFile("test.o", "");
const auto install_paths =
InstallPaths::MakeForBazelRunfiles(Testing::GetExePath());
RawStringOstream verbose_out;
std::string target = llvm::sys::getDefaultTargetTriple();
auto vfs = llvm::vfs::getRealFileSystem();
ClangRunner runner(&install_paths, target, vfs, &verbose_out);
std::string out;
std::string err;
EXPECT_TRUE(RunWithCapturedOutput(out, err,
[&] {
return runner.Run(
{"-c", test_file.string(), "-o",
test_output.string()});
}))
<< "Verbose output from runner:\n"
<< verbose_out.TakeStr() << "\n";
verbose_out.clear();
// No output should be produced.
EXPECT_THAT(out, StrEq(""));
EXPECT_THAT(err, StrEq(""));
}
} // namespace
} // namespace Carbon
+12
View File
@@ -2,6 +2,10 @@
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
load(
"@llvm-project//:vars.bzl",
"LLVM_VERSION_MAJOR",
)
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load("//bazel/cc_toolchains:defs.bzl", "cc_env")
load("//bazel/manifest:defs.bzl", "manifest")
@@ -119,6 +123,11 @@ lld_aliases = [
"wasm-ld",
]
filegroup(
name = "clang_headers",
srcs = ["@llvm-project//clang:builtin_headers_gen"],
)
# Given a root `prefix_root`, the hierarchy looks like:
#
# - prefix_root/bin: Binaries intended for direct use.
@@ -158,6 +167,9 @@ install_dirs = {
is_driver = True,
),
] + [install_symlink(name, "lld") for name in lld_aliases],
"lib/carbon/llvm/lib/clang/" + LLVM_VERSION_MAJOR: [
install_filegroup("include", ":clang_headers", "staging/include/"),
],
}
make_install_filegroups(
+3 -1
View File
@@ -7,7 +7,7 @@
load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files", "pkg_mklink", "strip_prefix")
load("symlink_helpers.bzl", "symlink_file", "symlink_filegroup")
def install_filegroup(name, filegroup_target):
def install_filegroup(name, filegroup_target, remove_prefix = ""):
"""Adds a filegroup for install.
Used in the `install_dirs` dict.
@@ -20,6 +20,7 @@ def install_filegroup(name, filegroup_target):
"filegroup": filegroup_target,
"is_driver": False,
"name": name,
"remove_prefix": remove_prefix,
}
def install_symlink(name, symlink_to, is_driver = False):
@@ -111,6 +112,7 @@ def make_install_filegroups(name, no_driver_name, pkg_name, install_dirs, prefix
name = prefixed_path,
out_prefix = prefixed_path,
srcs = [entry["filegroup"]],
remove_prefix = entry["remove_prefix"],
)
pkg_files(
name = pkg_path,
+14 -3
View File
@@ -46,14 +46,24 @@ symlink_file = rule(
def _symlink_filegroup_impl(ctx):
prefix = ctx.attr.out_prefix
remove_prefix = ctx.attr.remove_prefix
outputs = []
for f in ctx.files.srcs:
# We normalize the path to be package-relative in order to ensure
# consistent paths across possible repositories.
relative_path = f.short_path.removeprefix(f.owner.package)
# consistent paths across possible repositories. After experimenting,
# incrementally removing these path fragments, in this order,
# effectively handles the full permutation of files across different
# repositories and both generated and source files.
relative_path = f.path
relative_path = relative_path.removeprefix(f.root.path + "/")
relative_path = relative_path.removeprefix(f.owner.workspace_root + "/")
relative_path = relative_path.removeprefix(f.owner.package + "/")
if not relative_path.startswith(remove_prefix):
fail("Missing `{0}` in `{1}`".format(remove_prefix, relative_path))
relative_path = relative_path.removeprefix(remove_prefix)
out = ctx.actions.declare_file(prefix + relative_path)
out = ctx.actions.declare_file(prefix + "/" + relative_path)
outputs.append(out)
ctx.actions.symlink(output = out, target_file = f)
@@ -72,6 +82,7 @@ symlink_filegroup = rule(
implementation = _symlink_filegroup_impl,
attrs = {
"out_prefix": attr.string(mandatory = True),
"remove_prefix": attr.string(),
"srcs": attr.label_list(mandatory = True),
},
)