import os import subprocess import shutil import glob import lib from lib import arch, cpp from lib.make import * pkgver = "22.1.8" [pkgver_major, pkgver_minor, pkgver_rev] = pkgver.split(".") version(pkgver) source_url(f"https://github.com/llvm/llvm-project/releases/download/llvmorg-{pkgver}/llvm-project-{pkgver}.src.tar.xz") builddep("shortcut/c++") builddep("shortcut/cmake") builddep(f"linux-dev @{arch.get_target()}") builddep(f"libffi-dev @{arch.get_target()}") builddep(f"libz-ng-dev @{arch.get_target()}") builddep(f"aws-lc-dev @{arch.get_target()}") builddep(f"libunwind-dev @{arch.get_target()}") srcdir = None packname = None def llvm_host_triple(): return arch.get_target().replace("-semios-linux", "-semios-linux-musl") def cmake(sourcedir, args): builddir = os.getcwd() + f"/../_build_{sourcedir}" installdir = os.getcwd() + f"/../_cpp_install/{sourcedir}" template_args = [ "cmake", "-G", "Ninja", "-S", sourcedir, "-B", builddir, "-DCMAKE_BUILD_TYPE=Release", f"-DLLVM_DEFAULT_TARGET_TRIPLE={llvm_host_triple()}", f"-DLLVM_HOST_TRIPLE={llvm_host_triple()}", "-DLLVM_ENABLE_EH=ON", "-DLLVM_ENABLE_RTTI=ON", "-DLLVM_ENABLE_ASSERTIONS=OFF", "-DLLVM_BUILD_LLVM_DYLIB=ON", "-DLLVM_LINK_LLVM_DYLIB=ON", "-DLLVM_ENABLE_LIBCXX=ON", "-DLLVM_ENABLE_LLD=ON", "-DLLVM_ENABLE_FFI=ON", ] subprocess.run(template_args + args, check=True) subprocess.run(["cmake", "--build", builddir], check=True) os.environ["DESTDIR"] = installdir subprocess.run(["cmake", "--install", builddir], check=True) def import_llvm(): return [f"-DLLVM_ROOT={os.getcwd()}/../_cpp_install/llvm/usr/local"] def import_clang(): return [f"-DClang_DIR={os.getcwd()}/../_cpp_install/clang/usr/local"] def enter_install(name): global packname packname = name def auto_pack_static(composer): composer.makedir("lib") for i in os.listdir("lib"): if ".a" in i: composer.addfile(f"lib/{i}", f"lib/{i}") def auto_pack_dev(composer, name, devbins=[], extdirs=["lib/cmake"]): composer.add_dir("include", "include") composer.makedir("lib") for i in os.listdir("lib"): prefix = None if os.path.isdir(i) and f"lib/{i}" in extdirs: composer.add_dir(f"lib/{i}", f"lib/{i}") elif ".so" in i: prefix = get_prefix(f"lib{name}") elif ".a" in i: prefix = get_prefix(f"lib{name}-static") if prefix: os.symlink(f"{prefix}/lib/{i}", f"{composer.workdir}/bundle/lib/{i}") composer.makedir("bin") for i in devbins: composer.addfile(f"bin/{i}", f"bin/{i}") for i in os.listdir("bin"): if i in devbins: continue prefix = get_prefix(name) os.symlink(f"{prefix}/bin/{i}", f"{composer.workdir}/bundle/bin/{i}") def auto_pack_runtime_lib(composer, name): composer.makedir("lib") for i in os.listdir("lib"): if name in i and ".so" in i: composer.addfile(f"lib/{i}", f"lib/{i}") def auto_pack_glob(composer, matches): for matchable in matches: for i in glob.glob(matchable): composer.makedirs(f"{os.path.dirname(i)}") if os.path.isdir(i): composer.add_dir(i, i) else: composer.addfile(i, i) old_on_pack = on_pack def new_on_pack(f): current_packname = packname def wrap_f(composer): pkgdir = f"{srcdir}/../_cpp_install/{current_packname}/usr/local" os.chdir(pkgdir) f(composer) old_on_pack(wrap_f) lib.make.on_pack = new_on_pack on_pack = new_on_pack def build_llvm(): cmake("llvm", []) def build_bolt(): cmake("bolt", import_llvm()) def build_clang(): options = [ "-DCLANG_DEFAULT_CXX_STDLIB=libc++", "-DCLANG_DEFAULT_RTLIB=compiler-rt", "-DLLVM_INCLUDE_TESTS=OFF", ] cmake("clang", import_llvm() + options) def build_lldb(): cmake("lldb", import_llvm() + import_clang()) def build_lld(): cmake("lld", import_llvm()) def build_polly(): cmake("polly", import_llvm()) def build_runtimes(): cflags = f"-isystem /lib/{arch.get_target()}/include -L/lib/{arch.get_target()} -B/lib/{arch.get_target()} -rtlib=compiler-rt" shutil.rmtree("../_build_runtimes") options = [ # Configure runtimes "-DLLVM_ENABLE_RUNTIMES=libunwind;libcxxabi;libcxx", # Configure libcxx "-DLIBCXX_HAS_MUSL_LIBC=ON", ] cmake("runtimes", options) shutil.rmtree("../_build_runtimes") options = [ # Configure runtimes "-DLLVM_ENABLE_RUNTIMES=compiler-rt", # Configure compiler-rt "-DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON", "-DCOMPILER_RT_BUILD_GWP_ASAN=OFF", "-DCOMPILER_RT_BUILD_LIBFUZZER=OFF", ] cmake("runtimes", options) def build(): global srcdir srcdir = os.getcwd() build_llvm() build_bolt() build_clang() build_lldb() build_lld() build_polly() build_runtimes() on_build(build) enter_install("llvm") package("libllvm") dep("semi-libc @same-arch") dep("libunwind @same-arch") dep("libcxx @same-arch") dep("libcxxabi @same-arch") on_pack(lambda composer: auto_pack_glob(composer, ["lib/*.so*"])) package("libllvm-dev") dep("libllvm (same)") on_pack(lambda composer: auto_pack_dev(composer, "llvm", ["llvm-config"])) package("libllvm-static") on_pack(auto_pack_static) def pack_llvm(composer): composer.add_dir("bin", "bin") os.remove(f"{composer.workdir}/bundle/bin/llvm-config") composer.add_dir("share", "share") package("llvm") dep("libllvm (same)") on_pack(pack_llvm) for i in ["strip", "ar", "ranlib", "readelf", "objcopy", "objdump", "strings", "nm"]: link(f"bin/llvm-{i}", f"/bin/{i}") enter_install("bolt") package("bolt") dep("libcxx @same-arch") cpp.use_auto_pack(["bin"]) enter_install("clang") package("libclang") dep("libllvm (same)") cpp.use_auto_pack(["lib"]) package("libclang-static") on_pack(auto_pack_static) package("libclang-dev") dep("libclang (same)") on_pack(lambda composer: auto_pack_dev(composer, "clang")) def pack_clang(composer): # Add base files composer.add_dir("bin", "bin") composer.add_dir("libexec", "libexec") composer.makedir("share") for i in ["clang", "scan-build", "scan-view"]: composer.add_dir(f"share/{i}", f"share/{i}") # Add resource files composer.makedir("lib") composer.add_dir("lib/clang", "lib/clang") # Add compiler-rt for current architecture linuxrtdir = "../../../runtimes/usr/local/lib/linux" localrtdir = f"lib/clang/{pkgver_major}/lib/{llvm_host_triple()}" composer.makedirs(localrtdir) for rtlib in os.listdir(linuxrtdir): larch = llvm_host_triple().split("-")[0] lrtlib = rtlib.replace(f"-{larch}", "") composer.addfile(f"{linuxrtdir}/{rtlib}", f"{localrtdir}/{lrtlib}") # Add symlink to system directories os.symlink(f"/lib/{arch.get_target()}/include", f"{composer.workdir}/bundle/include") # Add configuration clang_cfg = f"-L/lib/{arch.get_target()}\n-B/lib/{arch.get_target()}\n-rtlib=compiler-rt\n" clangxx_cfg = f"-stdlib=libc++\n{clang_cfg}" with open(f"{composer.workdir}/bundle/bin/clang.cfg", "wt+") as file: file.write(clang_cfg) with open(f"{composer.workdir}/bundle/bin/clang++.cfg", "wt+") as file: file.write(clangxx_cfg) package("clang") dep("libclang (same)") on_pack(pack_clang) enter_install("lld") package("lld") dep("libllvm (same)") cpp.use_auto_pack(["bin"]) link("bin/ld.lld", "/bin/ld") package("lld-dev") dep("lld (same)") cpp.use_auto_pack(["dev"]) enter_install("lldb") package("liblldb") dep("libclang (same)") dep("libllvm (same)") cpp.use_auto_pack(["lib"]) package("liblldb-dev") dep("liblldb (same)") cpp.use_auto_pack(["dev"]) package("lldb") dep("liblldb (same)") cpp.use_auto_pack(["bin"]) enter_install("polly") package("polly") dep("libcxx @same-arch") on_pack(lambda composer: auto_pack_glob(composer, ["*"])) enter_install("runtimes") package("libunwind") dep("semi-libc @same-arch") on_pack(lambda composer: auto_pack_runtime_lib(composer, "unwind")) package("libunwind-dev") dep("libunwind (same)") on_pack(lambda composer: auto_pack_glob(composer, ["lib/libunwind.a", "include/*unwind*", "include/mach-o"])) package("libcxxabi") dep("libunwind (same)") on_pack(lambda composer: auto_pack_runtime_lib(composer, "libc++abi")) package("libcxxabi-dev") dep("libcxxabi (same)") on_pack(lambda composer: auto_pack_glob(composer, ["lib/libc++abi.a"])) package("libcxx") dep("libcxxabi (same)") on_pack(lambda composer: auto_pack_runtime_lib(composer, "libc++")) package("libcxx-dev") dep("libcxx (same)") on_pack(lambda composer: auto_pack_glob(composer, ["lib/libc++experimental.a", "lib/libc++.a", "lib/libc++.modules.json", "include/c++", "share/libc++"]))