aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-03 19:46:07 +0900
committerOphestra <cat@gensokyo.uk>2026-05-03 19:48:49 +0900
commit7e2210ff712232ebfcbb5907d8528570b222144e (patch)
treec5c11eb0fc2663e6d56d5d7d926a3badef747e59 /internal
parenta71a008f3c8324ab394e451b852cd9b21f072fab (diff)
internal/rosa/llvm: provide runtimes early in stage0
The LLVM build system fails to handle a dynamically linked toolchain correctly, and leaks the system installation during builds. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal')
-rw-r--r--internal/rosa/all.go12
-rw-r--r--internal/rosa/llvm.go123
2 files changed, 134 insertions, 1 deletions
diff --git a/internal/rosa/all.go b/internal/rosa/all.go
index ef3275d6..a9c4ae56 100644
--- a/internal/rosa/all.go
+++ b/internal/rosa/all.go
@@ -178,6 +178,18 @@ const (
PresetUnexportedStart
llvmSource = iota - 1
+ // earlyCompilerRT is an early, standalone compiler-rt installation for the
+ // standalone runtimes build.
+ //
+ // earlyCompilerRT must only be loaded by [LLVM].
+ earlyCompilerRT
+ // earlyRuntimes is an early, standalone installation of LLVM runtimes to
+ // work around the cmake build system leaking the system LLVM installation
+ // when invoking the newly built toolchain.
+ //
+ // earlyRuntimes must only be loaded by [LLVM].
+ earlyRuntimes
+
buildcatrust
utilMacros
diff --git a/internal/rosa/llvm.go b/internal/rosa/llvm.go
index 7669e0d0..2751410c 100644
--- a/internal/rosa/llvm.go
+++ b/internal/rosa/llvm.go
@@ -30,7 +30,128 @@ func litArgs(verbose bool, skipChecks ...string) string {
return "'" + strings.Join(args, " ") + "'"
}
+func (t Toolchain) newEarlyCompilerRT() (pkg.Artifact, string) {
+ version := t.Version(llvmSource)
+ major, _, _ := strings.Cut(version, ".")
+ return t.NewPackage("early-compiler-rt", version, t.Load(llvmSource), &PackageAttr{
+ Flag: TExclusive,
+ }, &CMakeHelper{
+ Append: []string{"compiler-rt"},
+
+ Cache: []KV{
+ // libc++ not yet available
+ {"CMAKE_CXX_COMPILER_TARGET", ""},
+
+ {"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
+ {"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
+ {"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"},
+
+ {"COMPILER_RT_BUILD_BUILTINS", "ON"},
+ {"COMPILER_RT_DEFAULT_TARGET_ONLY", "OFF"},
+ {"COMPILER_RT_SANITIZERS_TO_BUILD", "asan"},
+
+ // does not work without libunwind
+ {"COMPILER_RT_BUILD_CTX_PROFILE", "OFF"},
+ {"COMPILER_RT_BUILD_LIBFUZZER", "OFF"},
+ {"COMPILER_RT_BUILD_MEMPROF", "OFF"},
+ {"COMPILER_RT_BUILD_PROFILE", "OFF"},
+ {"COMPILER_RT_BUILD_XRAY", "OFF"},
+ },
+ SkipTest: true,
+ Script: `
+mkdir -p "/work/system/lib/clang/` + major + `/lib/"
+ln -s \
+ "../../../${ROSA_TRIPLE}" \
+ "/work/system/lib/clang/` + major + `/lib/"
+
+ln -s \
+ "clang_rt.crtbegin-` + linuxArch() + `.o" \
+ "/work/system/lib/${ROSA_TRIPLE}/crtbeginS.o"
+ln -s \
+ "clang_rt.crtend-` + linuxArch() + `.o" \
+ "/work/system/lib/${ROSA_TRIPLE}/crtendS.o"
+`,
+ },
+ Python,
+
+ muslHeaders,
+ KernelHeaders,
+ ), version
+}
+func init() {
+ artifactsM[earlyCompilerRT] = Metadata{
+ f: Toolchain.newEarlyCompilerRT,
+
+ Name: "early-compiler-rt",
+ Description: "early LLVM runtime: compiler-rt",
+
+ Dependencies: P{
+ Musl,
+ },
+ }
+}
+
+func (t Toolchain) newEarlyRuntimes() (pkg.Artifact, string) {
+ version := t.Version(llvmSource)
+ return t.NewPackage("early-runtimes", version, t.Load(llvmSource), &PackageAttr{
+ Flag: TExclusive,
+ }, &CMakeHelper{
+ Append: []string{"runtimes"},
+
+ Cache: []KV{
+ // libc++ not yet available
+ {"CMAKE_CXX_COMPILER_WORKS", "ON"},
+
+ {"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`},
+ {"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`},
+ {"LLVM_ENABLE_RUNTIMES", "'libunwind;libcxx;libcxxabi'"},
+
+ {"LIBUNWIND_USE_COMPILER_RT", "ON"},
+ {"LIBCXX_HAS_MUSL_LIBC", "ON"},
+ {"LIBCXX_USE_COMPILER_RT", "ON"},
+ {"LIBCXX_HAS_ATOMIC_LIB", "OFF"},
+ {"LIBCXXABI_USE_COMPILER_RT", "ON"},
+ {"LIBCXXABI_USE_LLVM_UNWINDER", "ON"},
+ {"LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL", "OFF"},
+
+ {"LLVM_ENABLE_ZLIB", "FORCE_ON"},
+ {"LLVM_ENABLE_ZSTD", "FORCE_ON"},
+ {"LLVM_ENABLE_LIBXML2", "OFF"},
+ },
+ SkipTest: true,
+ },
+ Python,
+
+ Zlib,
+ Zstd,
+ earlyCompilerRT,
+ KernelHeaders,
+ ), version
+}
+func init() {
+ artifactsM[earlyRuntimes] = Metadata{
+ f: Toolchain.newEarlyRuntimes,
+
+ Name: "early-runtimes",
+ Description: "early LLVM runtimes: libunwind, libcxx, libcxxabi",
+
+ Dependencies: P{
+ earlyCompilerRT,
+ },
+ }
+}
+
func (t Toolchain) newLLVM() (pkg.Artifact, string) {
+ var early PArtifact = muslHeaders
+ if t.isStage0() {
+ // The LLVM build system is buggy around LLVM_LINK_LLVM_DYLIB and leaks
+ // the system installation when invoking the newly built toolchain. This
+ // is worked around in stage0 by providing standalone builds of
+ // runtimes. Later stages rely on 3-stage determinism and allows the
+ // system installation from its previous stage to leak through.
+ early = earlyRuntimes
+ }
+
cache := []KV{
{"ENABLE_LINKER_BUILD_ID", "ON"},
{"COMPILER_RT_USE_BUILTINS_LIBRARY", "ON"},
@@ -173,7 +294,7 @@ ninja ` + jobsFlagE + ` check-all
Zlib,
Zstd,
- muslHeaders,
+ early,
KernelHeaders,
), version
}