package rosa import ( "regexp" "runtime" "slices" "strings" "hakurei.app/internal/pkg" ) // litArgs returns [LIT] arguments for optional verbosity and check skipping. func litArgs(verbose bool, skipChecks ...string) string { args := []string{"-sv"} if verbose { args[0] = "--verbose" } if len(skipChecks) > 0 { skipChecks = slices.Clone(skipChecks) for i, s := range skipChecks { s = regexp.QuoteMeta(s) s = strings.ReplaceAll(s, "/", "\\/") skipChecks[i] = s } args = append(args, "--filter-out='\\''"+strings.Join(skipChecks, "|")+"'\\''") } 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"}, {"COMPILER_RT_DEFAULT_TARGET_ONLY", "ON"}, {"COMPILER_RT_BUILD_GWP_ASAN", "OFF"}, {"LIBCXX_CXX_ABI", "libcxxabi"}, {"LIBCXX_USE_COMPILER_RT", "ON"}, {"LIBCXX_ENABLE_STATIC_ABI_LIBRARY", "OFF"}, {"LIBCXX_HAS_MUSL_LIBC", "ON"}, {"LIBCXX_HARDENING_MODE", "fast"}, {"LIBCXXABI_USE_LLVM_UNWINDER", "ON"}, {"LIBCXXABI_ENABLE_STATIC_UNWINDER", "OFF"}, {"LIBCXXABI_USE_COMPILER_RT", "ON"}, {"LLVM_INSTALL_BINUTILS_SYMLINKS", "ON"}, {"LLVM_INSTALL_UTILS", "ON"}, {"LLVM_BUILD_LLVM_DYLIB", "ON"}, {"LLVM_LINK_LLVM_DYLIB", "ON"}, {"LLVM_APPEND_VC_REV", "OFF"}, {"LLVM_ENABLE_RTTI", "ON"}, {"LLVM_ENABLE_ZLIB", "FORCE_ON"}, {"LLVM_ENABLE_ZSTD", "FORCE_ON"}, {"LLVM_ENABLE_PER_TARGET_RUNTIME_DIR", "ON"}, {"CLANG_DEFAULT_RTLIB", "compiler-rt"}, {"CLANG_DEFAULT_UNWINDLIB", "libunwind"}, {"CLANG_DEFAULT_CXX_STDLIB", "libc++"}, {"CLANG_CONFIG_FILE_SYSTEM_DIR", "/system/etc/clang"}, {"LLVM_ENABLE_FFI", "OFF"}, {"LLVM_ENABLE_LIBXML2", "OFF"}, {"LLVM_ENABLE_LIBCXX", "ON"}, {"LLVM_ENABLE_LLD", "ON"}, {"LIBUNWIND_ENABLE_ASSERTIONS", "OFF"}, {"LIBUNWIND_USE_COMPILER_RT", "ON"}, {"LLVM_HOST_TRIPLE", `"${ROSA_TRIPLE}"`}, {"LLVM_DEFAULT_TARGET_TRIPLE", `"${ROSA_TRIPLE}"`}, {"LLVM_ENABLE_PROJECTS", "'" + strings.Join([]string{ "clang", "lld", }, ";") + "'"}, {"LLVM_ENABLE_RUNTIMES", "'" + strings.Join([]string{ "compiler-rt", "libcxx", "libcxxabi", "libunwind", "libclc", }, ";") + "'"}, } if !t.isStage0() { skipChecks := []string{ // expensive, pointless to run here "benchmarks", // LLVM ERROR: Tried to execute an unknown external function: roundevenf "ExecutionEngine/Interpreter/intrinsics.ll", // clang: deadlocks with LLVM_BUILD_LLVM_DYLIB "crash-recovery-modules", // clang: fatal error: '__config_site' file not found "CodeGen/PowerPC/ppc-xmmintrin.c", "CodeGen/PowerPC/ppc-mmintrin.c", "CodeGen/PowerPC/ppc-emmintrin.c", "CodeGen/PowerPC/ppc-pmmintrin.c", "CodeGen/PowerPC/ppc-tmmintrin.c", "CodeGen/PowerPC/ppc-smmintrin.c", "CodeGenCUDA/amdgpu-alias-undef-symbols.cu", // cxx: fails on musl "close.dont-get-rid-of-buffer", "re/re.traits", "std/time", "localization/locales", "localization/locale.categories", "selftest/dsl/dsl.sh.py", "input.output/iostream.format", "locale-specific_form", // cxx: deadlocks "std/thread/thread.jthread", // unwind: fails on musl "eh_frame_fde_pc_range", } switch runtime.GOARCH { case "arm64": skipChecks = append(skipChecks, // LLVM: intermittently crashes "ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll", // unwind: unexpectedly passes "unwind_leaffunction", ) } if presetOpts&OptLLVMNoLTO == 0 { cache = append(cache, []KV{ // very expensive {"LLVM_ENABLE_LTO", "Thin"}, }...) } cache = append(cache, []KV{ // symbols: clock_gettime, mallopt {"COMPILER_RT_INCLUDE_TESTS", "OFF"}, {"LLVM_LIT_ARGS", litArgs(true, skipChecks...)}, }...) } version := t.Version(llvmSource) return t.NewPackage("llvm", version, t.Load(llvmSource), nil, &CMakeHelper{ Append: []string{"llvm"}, Cache: cache, Script: ` ln -s ld.lld /work/system/bin/ld ln -s clang /work/system/bin/cc ln -s clang /work/system/bin/cpp ln -s clang++ /work/system/bin/c++ `, // LLVM_LINK_LLVM_DYLIB causes llvm test suite to leak system // installation into test environment, and the tests end up testing the // system installation instead. Tests are disabled on stage0 and relies // on 3-stage determinism to test later stages. SkipTest: t.isStage0(), Test: ` chmod +w /bin && ln -s \ ../system/bin/chmod \ ../system/bin/mkdir \ ../system/bin/rm \ ../system/bin/tr \ ../system/bin/awk \ /bin ninja ` + jobsFlagE + ` check-all `, }, Python, Perl, Diffutils, Bash, Gawk, Coreutils, Findutils, Zlib, Zstd, early, KernelHeaders, ), version } func init() { const ( version = "22.1.4" checksum = "Bk3t-tV5sD5T0bqefFMcLeFuAwXnhFipywZmqst5hAZs97QQWGKB_5XyAFjj5tDB" ) artifactsM[llvmSource] = Metadata{ f: func(t Toolchain) (pkg.Artifact, string) { return t.NewPatchedSource("llvm", version, newFromGitHub( "llvm/llvm-project", "llvmorg-"+version, checksum, ), true, llvmPatches...), version }, Name: "llvm-project", Description: "LLVM monorepo with Rosa OS patches", ID: 1830, } artifactsM[LLVM] = Metadata{ f: Toolchain.newLLVM, Name: "llvm", Description: "a collection of modular and reusable compiler and toolchain technologies", Website: "https://llvm.org", Dependencies: P{ Zlib, Zstd, Musl, }, } }