Bladeren bron

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>
Chandler Carruth 1 jaar geleden
bovenliggende
commit
fe2c0b48cf

+ 33 - 0
toolchain/driver/clang_runner_test.cpp

@@ -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 - 0
toolchain/install/BUILD

@@ -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
toolchain/install/install_filegroups.bzl

@@ -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
toolchain/install/symlink_helpers.bzl

@@ -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),
     },
 )