Explorar o código

Start moving runtimes building logic into Starlark (#6701)

The goal here is to be able to construct a build of the runtimes
directly in Bazel, or by emitting `BUILD` files, or by emitting into C++
code and using that on-demand. For that, we want a single source of
truth, and that source in Starlark.

This should also make the information more generally useful, and so I'm
moving as much as I can into the LLVM Bazel build. Apologies as that
makes the diffs extra annoying.

I do plan on upstreaming the Bazel parts of this, but would like to get
everything working in Carbon and stabilized first.

While here, I've also made a change suggested for the future in the
initial review by lifting the C++ template out of a string literal in
the `.bzl` file, and into an actual separate C++ file.

This only moves libc++, libc++abi, and libunwind. I want to get those
three working end-to-end before I work on the builtins or `crtbegin` and
`crtend`, as those have a bunch of additional complexity.

This also only uses the info in the C++ on-demand build. It seemed like
a reasonable increment to start code review, and my plan is to work on
other build strategies in a follow-up PR. If that doesn't work, let me
know and I'll come back once I have at least a second use of the info
here.
Chandler Carruth hai 2 meses
pai
achega
e5b094fdad

+ 9 - 0
.clangd

@@ -19,3 +19,12 @@ Diagnostics:
   Suppress:
     # The `#error` requiring a macro definition.
     - pp_hash_error
+
+---
+
+# Suppress diagnostics for template source files.
+If:
+  PathMatch: .*\.tpl\.h
+Diagnostics:
+  Suppress:
+    - undeclared_var_use

+ 32 - 2
bazel/llvm_project/0004_Introduce_basic_sources_exporting_for_libunwind.patch

@@ -1,7 +1,7 @@
-Commit ID: a79f1facf56cc5772557cdb09d811aa11a22e43b
+Commit ID: 354e38c89f28e2cc284e655a9cde707f457dc02c
 Change ID: sxspxmonsuvqzuvxvrvorlumwpwromsv
 Author   : Chandler Carruth <chandlerc@gmail.com> (2025-09-25 22:55:26)
-Committer: Chandler Carruth <chandlerc@gmail.com> (2025-11-17 09:59:25)
+Committer: Chandler Carruth <chandlerc@gmail.com> (2026-02-14 03:46:06)
 
     Introduce basic sources exporting for libunwind
 
@@ -32,3 +32,33 @@ index c9fdc819c0..7d734c5a06 100644
 +        "src/*.S",
 +    ]),
 +)
+diff --git a/utils/bazel/llvm-project-overlay/libunwind/libunwind_library.bzl b/utils/bazel/llvm-project-overlay/libunwind/libunwind_library.bzl
+new file mode 100644
+index 0000000000..25675d3070
+--- /dev/null
++++ b/utils/bazel/llvm-project-overlay/libunwind/libunwind_library.bzl
+@@ -0,0 +1,24 @@
++# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
++# See https://llvm.org/LICENSE.txt for license information.
++# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
++
++"""Starlark variables and macros for building libunwind.
++
++Variables provide base line information for how to build libunwind source files.
++These can be used to generate non-Bazel builds of the library.
++
++Macros provide a convenient way to construct Bazel `cc_library` rules for
++libunwind.
++"""
++
++# TODO: Should libunwind use `-fvisibility-inlines-hidden` and
++# `-fvisibility=hidden`, similar to libc++?
++libunwind_copts = [
++    "-D_LIBUNWIND_IS_NATIVE_ONLY",
++    "-O3",
++    "-fPIC",
++    "-fno-exceptions",
++    "-fno-rtti",
++    "-funwind-tables",
++    "-nostdinc++",
++]

+ 144 - 11
bazel/llvm_project/0005_Introduce_basic_sources_exporting_for_libcxx_and_libcxxabi.patch

@@ -1,8 +1,8 @@
-Commit ID: e4ff7299fe7e35e70ba79f5d8e2c58658cfba678
+Commit ID: 3812a423c5ca98c5cf6ceee006a59d6c3a3b33df
 Change ID: mstnwoqruyypnoouksnyqssllrsozpos
-Bookmarks: bz-libcxx bz-libcxx@git bz-libcxx@origin
+Bookmarks: bz-libcxx* bz-libcxx@git
 Author   : Chandler Carruth <chandlerc@gmail.com> (2025-09-25 22:55:26)
-Committer: Chandler Carruth <chandlerc@gmail.com> (2025-11-22 09:23:52)
+Committer: Chandler Carruth <chandlerc@gmail.com> (2026-02-14 04:12:09)
 
     Introduce basic sources exporting for libcxx and libcxxabi
 
@@ -11,10 +11,10 @@ Committer: Chandler Carruth <chandlerc@gmail.com> (2025-11-22 09:23:52)
 
 diff --git a/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel b/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel
 new file mode 100644
-index 0000000000..a81a64c649
+index 0000000000..c8b517ab56
 --- /dev/null
 +++ b/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel
-@@ -0,0 +1,49 @@
+@@ -0,0 +1,139 @@
 +# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
 +# See https://llvm.org/LICENSE.txt for license information.
 +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -25,9 +25,11 @@ index 0000000000..a81a64c649
 +    default_visibility = ["//visibility:public"],
 +)
 +
-+exports_files(["include/__config_site.in"])
-+
-+exports_files(["vendor/llvm/default_assertion_handler.in"])
++exports_files([
++    "include/__config_site.in",
++    "include/module.modulemap.in",
++    "vendor/llvm/default_assertion_handler.in",
++])
 +
 +filegroup(
 +    name = "libcxx_hdrs",
@@ -54,19 +56,150 @@ index 0000000000..a81a64c649
 +    ),
 +)
 +
++LIBCXX_SRCS_PSTL_LIBDISPATCH = [
++    "src/pstl/libdispatch.cpp",
++]
++
++filegroup(
++    name = "libcxx_srcs_pstl_libdispatch",
++    srcs = LIBCXX_SRCS_PSTL_LIBDISPATCH,
++)
++
++LIBCXX_SRCS_SUPPORT_IBM_PATTERNS = [
++    "src/support/ibm/**/*.cpp",
++]
++
++filegroup(
++    name = "libcxx_srcs_support_ibm",
++    srcs = glob(LIBCXX_SRCS_SUPPORT_IBM_PATTERNS),
++)
++
++LIBCXX_SRCS_SUPPORT_WIN32_PATTERNS = [
++    "src/support/win32/**/*.cpp",
++]
++
++filegroup(
++    name = "libcxx_srcs_support_win32",
++    srcs = glob(LIBCXX_SRCS_SUPPORT_WIN32_PATTERNS),
++)
++
++LIBCXX_SRCS_TZDB = [
++    "src/experimental/chrono_exception.cpp",
++    "src/experimental/time_zone.cpp",
++    "src/experimental/tzdb.cpp",
++    "src/experimental/tzdb_list.cpp",
++]
++
++filegroup(
++    name = "libcxx_srcs_tzdb",
++    srcs = LIBCXX_SRCS_TZDB,
++)
++
++# Exclude platform-dependent patterns that are provided by per-target filegroups
++# above.
++LIBCXX_SRCS_TARGET_EXCLUDES = (
++    LIBCXX_SRCS_PSTL_LIBDISPATCH +
++    LIBCXX_SRCS_SUPPORT_IBM_PATTERNS +
++    LIBCXX_SRCS_SUPPORT_WIN32_PATTERNS +
++    LIBCXX_SRCS_TZDB
++)
++
 +filegroup(
-+    name = "libcxx_srcs",
++    name = "libcxx_srcs_generic",
 +    srcs = glob(
 +        [
 +            "src/**/*.cpp",
 +            "src/**/*.h",
 +            "src/**/*.ipp",
 +        ],
++        exclude = [
++            # Build is for use with libc++abi and so don't need 'new.cpp'.
++            "src/new.cpp",
++
++            # Build is for compiler-rt platforms so we have its int128 support.
++            "src/filesystem/int128_builtins.cpp",
++        ] + LIBCXX_SRCS_TARGET_EXCLUDES,
 +    ),
 +)
++
++filegroup(
++    name = "libcxx_linux_srcs",
++    srcs = [
++        ":libcxx_srcs_generic",
++        ":libcxx_srcs_tzdb",
++    ],
++)
++
++filegroup(
++    name = "libcxx_macos_srcs",
++    srcs = [
++        ":libcxx_srcs_generic",
++        # TODO: Include libdispatch sources here to enable that pstl backend.
++    ],
++)
++
++filegroup(
++    name = "libcxx_win32_srcs",
++    srcs = [
++        ":libcxx_srcs_generic",
++        ":libcxx_srcs_support_win32",
++    ],
++)
++
++filegroup(
++    name = "libcxx_all_srcs",
++    srcs = [
++        ":libcxx_linux_srcs",
++        ":libcxx_macos_srcs",
++        ":libcxx_win32_srcs",
++    ],
++)
+diff --git a/utils/bazel/llvm-project-overlay/libcxx/libcxx_library.bzl b/utils/bazel/llvm-project-overlay/libcxx/libcxx_library.bzl
+new file mode 100644
+index 0000000000..66f64f3610
+--- /dev/null
++++ b/utils/bazel/llvm-project-overlay/libcxx/libcxx_library.bzl
+@@ -0,0 +1,37 @@
++# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
++# See https://llvm.org/LICENSE.txt for license information.
++# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
++
++"""Starlark variables and macros for building libc++ and libc++abi.
++
++Variables provide base line information for how to build libc++ and libc++abi
++source files. These can be used to generate non-Bazel builds of the library.
++
++TODO: Add macros that provide a convenient way to construct Bazel `cc_library`
++rules for libc++ and libc++abi.
++
++TODO: Add either sufficient usage in the macros, or add a how-to example here in
++the documentation so the use of these variables is more clear.
++"""
++
++_libcxx_base_copts = [
++    "-std=c++26",
++    "-O3",
++    "-fPIC",
++    "-fvisibility-inlines-hidden",
++    "-fvisibility=hidden",
++    "-nostdinc++",
++]
++
++_libcxx_defines = [
++    "-D_LIBCPP_BUILDING_LIBRARY",
++    "-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES",
++]
++
++_libcxxabi_defines = [
++    "-DLIBCXX_BUILDING_LIBCXXABI",
++]
++
++libcxx_copts = _libcxx_base_copts + _libcxx_defines
++libcxxabi_copts = _libcxx_base_copts + _libcxxabi_defines
++libcxx_and_abi_copts = _libcxx_base_copts + _libcxx_defines + _libcxxabi_defines
 diff --git a/utils/bazel/llvm-project-overlay/libcxxabi/BUILD.bazel b/utils/bazel/llvm-project-overlay/libcxxabi/BUILD.bazel
 new file mode 100644
-index 0000000000..cf491e4e46
+index 0000000000..279030b097
 --- /dev/null
 +++ b/utils/bazel/llvm-project-overlay/libcxxabi/BUILD.bazel
 @@ -0,0 +1,24 @@
@@ -89,8 +222,8 @@ index 0000000000..cf491e4e46
 +    name = "libcxxabi_srcs",
 +    srcs = glob([
 +        "src/**/*.cpp",
++        "src/**/*.h",
 +        "src/**/*.def",
 +        "src/**/*.inc",
-+        "src/**/*.h",
 +    ]),
 +)

+ 1 - 1
scripts/fix_cc_deps.py

@@ -71,7 +71,7 @@ IGNORE_SOURCE_FILE_REGEX = re.compile(
     r"^(third_party/clangd.*|common/version.*\.cpp"
     r"|.*_autogen_manifest\.cpp"
     r"|toolchain/base/llvm_tools.def"
-    r"|toolchain/base/runtime_sources.h)$"
+    r"|toolchain/base/runtimes_build_info.h)$"
 )
 
 

+ 2 - 2
toolchain/base/BUILD

@@ -4,7 +4,7 @@
 
 load("//bazel/cc_rules:defs.bzl", "cc_binary", "cc_library", "cc_test")
 load("llvm_tools.bzl", "LLVM_MAIN_TOOLS", "generate_llvm_tools_def")
-load("runtime_sources.bzl", "generate_runtime_sources_cc_library")
+load("runtimes_build_info.bzl", "generate_runtimes_build_info_cc_library")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -326,7 +326,7 @@ cc_library(
     ] + [info.lib for info in LLVM_MAIN_TOOLS.values()],
 )
 
-generate_runtime_sources_cc_library(name = "runtime_sources")
+generate_runtimes_build_info_cc_library(name = "runtimes_build_info")
 
 cc_library(
     name = "shared_value_stores",

+ 63 - 90
toolchain/base/runtime_sources.bzl → toolchain/base/runtimes_build_info.bzl

@@ -4,20 +4,23 @@
 
 """Provides variables and rules to work with Clang's runtime library sources.
 
-These are organized into groups based on the runtime functionality:
+These are organized into groups based on the Clang runtimes providing them and
+how they are built:
 - CRT: The C language runtimes not provided by the C standard library, currently
   just infrastructure for global initialization and teardown.
 - Builtins: The compiler builtins library mirroring `libgcc` that provides
   function definitions for operations not reliably available in hardware but
   needed by Clang.
+- Libc++ and libc++abi: The C++ standard library and its ABI components.
+- Libunwind: The unwinding library.
 
 Future runtimes we plan to add support for but not yet included:
-- Libunwind
-- Libc++ and libc++abi
 - Sanitizers
 - Profiling runtimes
 """
 
+load("@llvm-project//libcxx:libcxx_library.bzl", "libcxx_and_abi_copts")
+load("@llvm-project//libunwind:libunwind_library.bzl", "libunwind_copts")
 load("//bazel/cc_rules:defs.bzl", "cc_library")
 
 CRT_FILES = {
@@ -38,78 +41,29 @@ BUILTINS_FILEGROUPS = {
 }
 
 RUNTIMES_FILEGROUPS = {
-    "libcxx": "@llvm-project//libcxx:libcxx_srcs",
+    "libcxx_linux": "@llvm-project//libcxx:libcxx_linux_srcs",
+    "libcxx_macos": "@llvm-project//libcxx:libcxx_macos_srcs",
+    "libcxx_win32": "@llvm-project//libcxx:libcxx_win32_srcs",
     "libcxxabi": "@llvm-project//libcxxabi:libcxxabi_srcs",
     "libunwind": "@llvm-project//libunwind:libunwind_srcs",
 }
 
-_TEMPLATE = """
-// 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
-//
-// Generated header file of strings describing the Clang runtime library source
-// files.
-//
-// See toolchain/driver/runtime_sources.bzl for more details.
-
-#ifndef CARBON_TOOLCHAIN_BASE_RUNTIME_SOURCES_H_
-#define CARBON_TOOLCHAIN_BASE_RUNTIME_SOURCES_H_
-
-#include "llvm/ADT/StringRef.h"
-
-namespace Carbon::RuntimeSources {{
-
-inline constexpr llvm::StringLiteral CrtBegin = {crtbegin_src};
-inline constexpr llvm::StringLiteral CrtEnd = {crtend_src};
-
-inline constexpr llvm::StringLiteral BuiltinsGenericSrcs[] = {{
-{generic_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsMacosSrcs[] = {{
-{macos_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsBf16Srcs[] = {{
-{bf16_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsTfSrcs[] = {{
-{tf_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsX86ArchSrcs[] = {{
-{x86_arch_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsX86Fp80Srcs[] = {{
-{x86_fp80_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsAarch64Srcs[] = {{
-{aarch64_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsX86_64Srcs[] = {{
-{x86_64_srcs}
-}};
-inline constexpr llvm::StringLiteral BuiltinsI386Srcs[] = {{
-{i386_srcs}
-}};
-
-constexpr inline llvm::StringLiteral LibcxxSrcs[] = {{
-{libcxx}
-}};
-
-constexpr inline llvm::StringLiteral LibcxxabiSrcs[] = {{
-{libcxxabi}
-}};
-
-constexpr inline llvm::StringLiteral LibunwindSrcs[] = {{
-{libunwind}
-}};
-
-}}  // namespace Carbon::RuntimeSources
-
-#endif  // CARBON_TOOLCHAIN_BASE_RUNTIME_SOURCES_H_
-"""
+RUNTIMES_PREFIXES = {
+    "libcxx_linux": "libcxx/",
+    "libcxx_macos": "libcxx/",
+    "libcxx_win32": "libcxx/",
+    "libcxxabi": "libcxxabi/",
+    "libunwind": "libunwind/",
+}
+
+def _format_one_per_line(list):
+    return "\n" + "\n".join([
+        '    "{0}",'.format(item)
+        for item in list
+    ]) + "\n"
 
 def _builtins_path(file):
-    """Returns the runtime install path for a file in CompilerRT's builtins library."""
+    """Returns the install path for a file in CompilerRT's builtins library."""
 
     # The CompilerRT package has the builtins runtime sources in the
     # "lib/builtins/" subdirectory, and we install into a "builtins/"
@@ -118,13 +72,13 @@ def _builtins_path(file):
     return file.owner.name.removeprefix("lib/")
 
 def _runtimes_path(file):
-    """Returns the runtime install path for a file in a normal runtimes library."""
+    """Returns the install path for a file in a normal runtimes library."""
     return file.owner.name
 
 def _get_path(file_attr, to_path_fn):
     files = file_attr[DefaultInfo].files.to_list()
     if len(files) > 1:
-        fail(msg = "Expected a single file and got {0} files.".format(len(files)))
+        fail("Expected a single file and got {0} files.".format(len(files)))
 
     return '"{0}"'.format(to_path_fn(files[0]))
 
@@ -134,29 +88,44 @@ def _get_paths(files_attr, to_path_fn, prefix = ""):
         files.extend(src[DefaultInfo].files.to_list())
         files.extend(src[DefaultInfo].default_runfiles.files.to_list())
 
-    return "\n".join([
-        '    "{0}{1}",'.format(prefix, to_path_fn(f))
+    return _format_one_per_line([
+        "{0}{1}".format(prefix, to_path_fn(f))
         for f in files
     ])
 
-def _generate_runtime_sources_h_rule(ctx):
-    h_file = ctx.actions.declare_file(ctx.label.name)
-    ctx.actions.write(h_file, _TEMPLATE.format(**({
-        k: _get_path(getattr(ctx.attr, "_" + k), _builtins_path)
+def _get_substitutions(ctx):
+    key_attr = lambda k: getattr(ctx.attr, "_" + k)
+    return {
+        "LIBCXX_AND_ABI_COPTS": _format_one_per_line(libcxx_and_abi_copts),
+        "LIBUNWIND_COPTS": _format_one_per_line(libunwind_copts),
+    } | {
+        k.upper(): _get_path(key_attr(k), _builtins_path)
         for k in CRT_FILES.keys()
     } | {
-        k: _get_paths(getattr(ctx.attr, "_" + k), _builtins_path)
+        "BUILTINS_" + k.upper(): _get_paths(key_attr(k), _builtins_path)
         for k in BUILTINS_FILEGROUPS.keys()
     } | {
-        # Other runtimes are installed under separate directories named the same
-        # as their key.
-        k: _get_paths(getattr(ctx.attr, "_" + k), _runtimes_path, k + "/")
+        # Other runtimes are installed under separate directories named the
+        # same as their key.
+        k.upper() + "_SRCS": _get_paths(
+            key_attr(k),
+            _runtimes_path,
+            RUNTIMES_PREFIXES[k],
+        )
         for k in RUNTIMES_FILEGROUPS.keys()
-    })))
+    }
+
+def _generate_runtimes_build_info_h_rule(ctx):
+    h_file = ctx.actions.declare_file(ctx.label.name)
+    ctx.actions.expand_template(
+        template = ctx.file._template_file,
+        output = h_file,
+        substitutions = _get_substitutions(ctx),
+    )
     return [DefaultInfo(files = depset([h_file]))]
 
-generate_runtime_sources_h = rule(
-    implementation = _generate_runtime_sources_h_rule,
+generate_runtimes_build_info_h = rule(
+    implementation = _generate_runtimes_build_info_h_rule,
     attrs = {
         "_" + k: attr.label(default = v, allow_single_file = True)
         for k, v in CRT_FILES.items()
@@ -164,23 +133,27 @@ generate_runtime_sources_h = rule(
         "_" + k: attr.label_list(default = [v], allow_files = True)
         for k, v in BUILTINS_FILEGROUPS.items() + RUNTIMES_FILEGROUPS.items()
     } | {
+        "_template_file": attr.label(
+            default = "runtimes_build_info.tpl.h",
+            allow_single_file = True,
+        ),
     },
 )
 
-def generate_runtime_sources_cc_library(name, deps = [], **kwargs):
-    """Generates a `runtime_sources.h` header and a `cc_library` rule for it.
+def generate_runtimes_build_info_cc_library(name, deps = [], **kwargs):
+    """Generates a `runtimes_build_info.h` header and a `cc_library` rule.
 
-    This first generates the header file with variables describing the runtime
-    sources from Clang, and then a `cc_library` that exports that header.
+    This first generates the header file with variables describing the runtimes
+    build info from Clang, and then a `cc_library` that exports that header.
 
     The `cc_library` rule name is the provided `name` and should be depended on
     by code that includes the generated header. The `kwargs` are expanded into
     the `cc_library` in case other attributes need to be configured there.
     """
-    generate_runtime_sources_h(name = "runtime_sources.h")
+    generate_runtimes_build_info_h(name = "runtimes_build_info.h")
     cc_library(
         name = name,
-        hdrs = ["runtime_sources.h"],
+        hdrs = ["runtimes_build_info.h"],
         deps = [
             # For StringRef.h
             "@llvm-project//llvm:Support",

+ 47 - 0
toolchain/base/runtimes_build_info.tpl.h

@@ -0,0 +1,47 @@
+// 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
+//
+// Header file template expanded with strings describing build info for Carbon's
+// runtimes.
+//
+// See toolchain/base/runtimes_build_info.bzl for more details.
+
+#ifndef CARBON_TOOLCHAIN_BASE_RUNTIMES_BUILD_INFO_TPL_H_
+#define CARBON_TOOLCHAIN_BASE_RUNTIMES_BUILD_INFO_TPL_H_
+
+#include "llvm/ADT/StringRef.h"
+
+namespace Carbon::RuntimesBuildInfo {
+
+constexpr inline llvm::StringLiteral CrtBegin = CRTBEGIN_SRC;
+constexpr inline llvm::StringLiteral CrtEnd = CRTEND_SRC;
+
+// Prevent wrapping these lines -- the expansion of the variables will add line
+// breaks.
+//
+// clang-format off
+constexpr inline llvm::StringLiteral BuiltinsGenericSrcs[] = {BUILTINS_GENERIC_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsMacosSrcs[] = {BUILTINS_MACOS_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsBf16Srcs[] = {BUILTINS_BF16_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsTfSrcs[] = {BUILTINS_TF_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsX86ArchSrcs[] = {BUILTINS_X86_ARCH_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsX86Fp80Srcs[] = {BUILTINS_X86_FP80_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsAarch64Srcs[] = {BUILTINS_AARCH64_SRCS};
+// NOLINTNEXTLINE(readability-identifier-naming)
+constexpr inline llvm::StringLiteral BuiltinsX86_64Srcs[] = {BUILTINS_X86_64_SRCS};
+constexpr inline llvm::StringLiteral BuiltinsI386Srcs[] = {BUILTINS_I386_SRCS};
+// clang-format on
+
+constexpr inline llvm::StringLiteral LibcxxLinuxSrcs[] = {LIBCXX_LINUX_SRCS};
+constexpr inline llvm::StringLiteral LibcxxMacosSrcs[] = {LIBCXX_MACOS_SRCS};
+constexpr inline llvm::StringLiteral LibcxxWin32Srcs[] = {LIBCXX_WIN32_SRCS};
+constexpr inline llvm::StringLiteral LibcxxabiSrcs[] = {LIBCXXABI_SRCS};
+constexpr inline llvm::StringLiteral LibcxxCopts[] = {LIBCXX_AND_ABI_COPTS};
+
+constexpr inline llvm::StringLiteral LibunwindSrcs[] = {LIBUNWIND_SRCS};
+constexpr inline llvm::StringLiteral LibunwindCopts[] = {LIBUNWIND_COPTS};
+
+}  // namespace Carbon::RuntimesBuildInfo
+
+#endif  // CARBON_TOOLCHAIN_BASE_RUNTIMES_BUILD_INFO_TPL_H_

+ 1 - 1
toolchain/driver/BUILD

@@ -44,7 +44,7 @@ cc_library(
         "//toolchain/base:clang_invocation",
         "//toolchain/base:install_paths",
         "//toolchain/base:kind_switch",
-        "//toolchain/base:runtime_sources",
+        "//toolchain/base:runtimes_build_info",
         "@llvm-project//clang:basic",
         "@llvm-project//clang:clang-driver",
         "@llvm-project//clang:codegen",

+ 32 - 81
toolchain/driver/clang_runtimes.cpp

@@ -38,7 +38,7 @@
 #include "llvm/TargetParser/Host.h"
 #include "llvm/TargetParser/Triple.h"
 #include "toolchain/base/kind_switch.h"
-#include "toolchain/base/runtime_sources.h"
+#include "toolchain/base/runtimes_build_info.h"
 #include "toolchain/driver/clang_runner.h"
 #include "toolchain/driver/runtimes_cache.h"
 
@@ -293,54 +293,23 @@ auto ClangArchiveRuntimesBuilder<Component>::CollectSrcFiles()
     -> llvm::SmallVector<llvm::StringRef> {
   if constexpr (Component == Runtimes::LibUnwind) {
     return llvm::to_vector_of<llvm::StringRef>(llvm::make_filter_range(
-        RuntimeSources::LibunwindSrcs, [](llvm::StringRef src) {
+        RuntimesBuildInfo::LibunwindSrcs, [](llvm::StringRef src) {
           return src.ends_with(".c") || src.ends_with(".cpp") ||
                  src.ends_with(".S");
         }));
   } else if constexpr (Component == Runtimes::Libcxx) {
+    auto libcxx_target_srcs =
+        target_triple_.isOSWindows()
+            ? llvm::ArrayRef(RuntimesBuildInfo::LibcxxWin32Srcs)
+        : target_triple_.isMacOSX()
+            ? llvm::ArrayRef(RuntimesBuildInfo::LibcxxMacosSrcs)
+            : llvm::ArrayRef(RuntimesBuildInfo::LibcxxLinuxSrcs);
     auto libcxx_srcs = llvm::make_filter_range(
-        RuntimeSources::LibcxxSrcs, [this](llvm::StringRef src) {
-          if (!src.ends_with(".cpp")) {
-            return false;
-          }
-
-          // We include libc++abi and so don't need new/delete definitions.
-          if (src == "libcxx/src/new.cpp") {
-            return false;
-          }
-          // We use compiler-rt for builtins, so we don't need int128 helpers.
-          if (src == "libcxx/src/filesystem/int128_builtins.cpp") {
-            return false;
-          }
-
-          // We don't currently use the libdispatch PSTL backend.
-          // TODO: We should evaluate enabling this on macOS.
-          if (src == "libcxx/src/pstl/libdispatch.cpp") {
-            return false;
-          }
-
-          // Skip platform-specific code for unsupported platforms.
-          // TODO: We should revisit this and include the code for these targets
-          // along with testing to make sure it works.
-          if (src.starts_with("libcxx/src/support/ibm/") ||
-              src.starts_with("libcxx/src/support/win32/")) {
-            return false;
-          }
-
-          // The timezone database is currently only enabled on Linux in
-          // upstream.
-          if (!target_triple_.isOSLinux() &&
-              (src == "libcxx/src/experimental/chrono_exception.cpp" ||
-               src == "libcxx/src/experimental/time_zone.cpp" ||
-               src == "libcxx/src/experimental/tzdb.cpp" ||
-               src == "libcxx/src/experimental/tzdb_list.cpp")) {
-            return false;
-          }
+        libcxx_target_srcs,
+        [](llvm::StringRef src) { return src.ends_with(".cpp"); });
 
-          return true;
-        });
     auto libcxxabi_srcs = llvm::make_filter_range(
-        RuntimeSources::LibcxxabiSrcs,
+        RuntimesBuildInfo::LibcxxabiSrcs,
         [](llvm::StringRef src) { return src.ends_with(".cpp"); });
     return llvm::to_vector(
         llvm::concat<llvm::StringRef>(libcxx_srcs, libcxxabi_srcs));
@@ -354,38 +323,20 @@ template <Runtimes::Component Component>
   requires IsClangArchiveRuntimes<Component>
 auto ClangArchiveRuntimesBuilder<Component>::CollectCflags()
     -> llvm::SmallVector<llvm::StringRef> {
-  llvm::SmallVector<llvm::StringRef> cflags;
-
+  // Start with some hard-coded flags used across any runtime.
+  //
   // TODO: It would be nice to plumb through an option to enable (some) warnings
   // when building runtimes, especially for folks working directly on the Carbon
   // toolchain to validate our builds of runtimes.
+  llvm::SmallVector<llvm::StringRef> cflags = {
+      "-no-canonical-prefixes",
+      "-w",
+  };
 
   if constexpr (Component == Runtimes::LibUnwind) {
-    // TODO: Should libunwind also limit symbol visibility?
-    cflags = {
-        "-no-canonical-prefixes",
-        "-D_LIBUNWIND_IS_NATIVE_ONLY",
-        "-O3",
-        "-fPIC",
-        "-fno-exceptions",
-        "-fno-rtti",
-        "-funwind-tables",
-        "-nostdinc++",
-        "-w",
-    };
+    llvm::append_range(cflags, RuntimesBuildInfo::LibunwindCopts);
   } else if constexpr (Component == Runtimes::Libcxx) {
-    cflags = {
-        "-no-canonical-prefixes",
-        "-DLIBCXX_BUILDING_LIBCXXABI",
-        "-D_LIBCPP_BUILDING_LIBRARY",
-        "-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES",
-        "-O3",
-        "-fPIC",
-        "-fvisibility-inlines-hidden",
-        "-fvisibility=hidden",
-        "-nostdinc++",
-        "-w",
-    };
+    llvm::append_range(cflags, RuntimesBuildInfo::LibcxxCopts);
   } else {
     static_assert(false,
                   "Invalid runtimes component for an archive runtime builder.");
@@ -485,21 +436,21 @@ auto ClangResourceDirBuilder::CollectBuiltinsSrcFiles()
           src_files.push_back(input_src);
         }
       };
-  append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsGenericSrcs));
-  append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsBf16Srcs));
+  append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsGenericSrcs));
+  append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsBf16Srcs));
   if (target_triple_.isArch64Bit()) {
-    append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsTfSrcs));
+    append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsTfSrcs));
   }
   auto filter_out_chkstk = [&](llvm::StringRef src) {
     return !target_triple_.isOSWindows() || !src.ends_with("chkstk.S");
   };
   if (target_triple_.isAArch64()) {
-    append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsAarch64Srcs),
+    append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsAarch64Srcs),
                      filter_out_chkstk);
   } else if (target_triple_.isX86()) {
-    append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsX86ArchSrcs));
+    append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsX86ArchSrcs));
     if (target_triple_.isArch64Bit()) {
-      append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsX86_64Srcs),
+      append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsX86_64Srcs),
                        filter_out_chkstk);
     } else {
       // TODO: This should be turned into a nice user-facing diagnostic about an
@@ -507,7 +458,7 @@ auto ClangResourceDirBuilder::CollectBuiltinsSrcFiles()
       CARBON_CHECK(
           target_triple_.isArch32Bit(),
           "The Carbon toolchain doesn't currently support 16-bit x86.");
-      append_src_files(llvm::ArrayRef(RuntimeSources::BuiltinsI386Srcs),
+      append_src_files(llvm::ArrayRef(RuntimesBuildInfo::BuiltinsI386Srcs),
                        filter_out_chkstk);
     }
   } else {
@@ -545,10 +496,10 @@ auto ClangResourceDirBuilder::Setup() -> void {
   // provide the CRT begin/end files, and so we need to build them.
   if (target_triple_.isOSLinux()) {
     tasks_.async([this, latch_handle] {
-      crt_begin_result_ = BuildCrtFile(RuntimeSources::CrtBegin);
+      crt_begin_result_ = BuildCrtFile(RuntimesBuildInfo::CrtBegin);
     });
     tasks_.async([this, latch_handle] {
-      crt_end_result_ = BuildCrtFile(RuntimeSources::CrtEnd);
+      crt_end_result_ = BuildCrtFile(RuntimesBuildInfo::CrtEnd);
     });
   }
 
@@ -575,12 +526,12 @@ auto ClangResourceDirBuilder::Finish() -> void {
 
 auto ClangResourceDirBuilder::BuildCrtFile(llvm::StringRef src_file)
     -> ErrorOr<Success> {
-  CARBON_CHECK(src_file == RuntimeSources::CrtBegin ||
-               src_file == RuntimeSources::CrtEnd);
+  CARBON_CHECK(src_file == RuntimesBuildInfo::CrtBegin ||
+               src_file == RuntimesBuildInfo::CrtEnd);
   std::filesystem::path out_path =
       runtimes_builder_->path() / lib_path_ /
-      (src_file == RuntimeSources::CrtBegin ? "clang_rt.crtbegin.o"
-                                            : "clang_rt.crtend.o");
+      (src_file == RuntimesBuildInfo::CrtBegin ? "clang_rt.crtbegin.o"
+                                               : "clang_rt.crtend.o");
   std::filesystem::path src_path =
       installation().runtimes_root() / std::string_view(src_file);
   CARBON_VLOG("Building `{0}' from `{1}`...\n", out_path, src_path);

+ 2 - 2
toolchain/install/BUILD

@@ -10,7 +10,7 @@ load("@rules_python//python:defs.bzl", "py_binary", "py_test")
 load("//bazel/cc_rules:defs.bzl", "cc_binary", "cc_library", "cc_test")
 load("//bazel/manifest:defs.bzl", "manifest")
 load("//toolchain/base:llvm_tools.bzl", "LLVM_MAIN_TOOLS", "LLVM_TOOL_ALIASES")
-load("//toolchain/base:runtime_sources.bzl", "BUILTINS_FILEGROUPS", "CRT_FILES")
+load("//toolchain/base:runtimes_build_info.bzl", "BUILTINS_FILEGROUPS", "CRT_FILES")
 load("configure_cmake_file.bzl", "configure_cmake_file")
 load("install_filegroups.bzl", "install_filegroup", "install_symlink", "install_target", "make_install_filegroups")
 load("pkg_helpers.bzl", "pkg_naming_variables", "pkg_tar_and_test")
@@ -252,8 +252,8 @@ configure_cmake_file(
 filegroup(
     name = "libcxx",
     srcs = [
+        "@llvm-project//libcxx:libcxx_all_srcs",
         "@llvm-project//libcxx:libcxx_hdrs",
-        "@llvm-project//libcxx:libcxx_srcs",
     ],
 )