package rosa import ( "regexp" "slices" "strings" "hakurei.app/internal/pkg" ) var ( _llvmSource = H("llvm-project") _muslHeaders = H("musl-headers") _earlyRuntimes = H("early-runtimes") _musl = H("musl") _bash = H("bash") _awk = H("awk") _pythonEarly = H("python-early") _coreutils = H("coreutils") _diffutils = H("diffutils") _findutils = H("findutils") _zlib = H("zlib") _zstd = H("zstd") _kernelHeaders = H("kernel-headers") ) // 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 init() { native.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) { meta := Metadata{ Name: "llvm", Description: "a collection of modular and reusable compiler and toolchain technologies", Website: "https://llvm.org", Dependencies: P{ _zlib, _zstd, _musl, }, } _meta, source := t.MustLoad(_llvmSource) meta.Version = _meta.Version early := _muslHeaders if t.stage.isStage0() { // The LLVM build system uses the system installation when building with // LLVM_LINK_LLVM_DYLIB, since it builds runtimes after the fact, using // the just-built toolchain. This is unacceptable in stage0 due to the // potential version difference. Later stages bootstrap off of runtimes // of its previous stage via 3-stage determinism. 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"}, {"LLVM_INCLUDE_BENCHMARKS", "OFF"}, {"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.stage.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 t.arch { case "arm64": skipChecks = append(skipChecks, // LLVM: intermittently crashes "ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll", // unwind: unexpectedly passes "unwind_leaffunction", ) } if t.opts&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_BUILD_TESTS", "ON"}, {"LLVM_LIT_ARGS", litArgs(true, skipChecks...)}, }...) } return &meta, t.NewPackage("llvm", meta.Version, source, &PackageAttr{ Flag: TExclusive, Bin: []string{ "chmod", "mkdir", "rm", "tr", "awk", }, }, &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.stage.isStage0(), Test: "ninja " + jobsFlagE + " " + loadFlagE + " check-all", }, _pythonEarly, _perl, _diffutils, _bash, _awk, _coreutils, _findutils, _zlib, _zstd, early, _kernelHeaders, ) }) }