diff --git a/.gitignore b/.gitignore index b84b301..8699e98 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.swp +*.profraw llvm-project/llvm-project-* llvm-project/clang diff --git a/ci/test-clang-docker.sh b/ci/test-clang-docker.sh index 1493739..83b094c 100755 --- a/ci/test-clang-docker.sh +++ b/ci/test-clang-docker.sh @@ -9,6 +9,8 @@ fi CC=/repo/toolchain/bin/clang CXX=/repo/toolchain/bin/clang++ +LLVM_PROFILE_FILE=foo.profraw +LLVM_PROFILE_VERBOSE=1 hello_c=/repo/llvm-project/hello.c hello_cpp=/repo/llvm-project/hello.cpp hello_exe=/tmp/hello diff --git a/llvm-project/Dockerfile.epoch4 b/llvm-project/Dockerfile.epoch4 new file mode 100644 index 0000000..f47a190 --- /dev/null +++ b/llvm-project/Dockerfile.epoch4 @@ -0,0 +1,300 @@ +ARG BASE + +FROM alpine:edge AS source +RUN wget --no-verbose https://git.kernel.org/torvalds/t/linux-5.18-rc6.tar.gz +RUN wget --no-verbose https://musl.libc.org/releases/musl-1.2.3.tar.gz +RUN wget --no-verbose https://zlib.net/zlib-1.2.12.tar.gz +RUN wget --no-verbose https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.1/llvm-project-14.0.1.src.tar.xz + +FROM ${BASE} AS stage3 +FROM alpine:edge AS stage4 + +### BEGIN STAGE4 + +COPY --from=stage3 /usr/local/bin /usr/local/bin +COPY --from=stage3 /usr/local/lib /usr/local/lib +COPY --from=stage3 /usr/local/include /usr/local/include +RUN cd /usr/lib/ && \ + for library in libc++abi.so.1 libc++.a libc++abi.a libc++.so.1 libunwind.so.1 libunwind.a; \ + do ln -s "/usr/local/lib/x86_64-alpine-linux-musl/${library}" . ; \ + done + +### Linux +COPY --from=source linux-5.18-rc6.tar.gz . +RUN tar xf linux-5.18-rc6.tar.gz +RUN apk add make musl-dev rsync +RUN make -C linux-5.18-rc6 INSTALL_HDR_PATH=/sysroot/usr LLVM=1 -j$(nproc) headers_install +RUN apk del rsync musl-dev make + +### Musl +COPY --from=source musl-1.2.3.tar.gz . +RUN tar xf musl-1.2.3.tar.gz +ARG MUSL_DIR=musl-1.2.3/build +RUN mkdir -p ${MUSL_DIR} +RUN cd ${MUSL_DIR} && \ + CC=clang AR=llvm-ar RANLIB=llvm-ranlib \ + ../configure --prefix=/usr --syslibdir=/usr/lib +RUN apk add make +RUN make -C ${MUSL_DIR} -j$(nproc) +RUN make -C ${MUSL_DIR} -j$(nproc) DESTDIR=/sysroot install-headers +RUN make -C ${MUSL_DIR} -j$(nproc) DESTDIR=/sysroot install-libs +RUN apk del make + +# Pause for a quick sanity check +COPY hello.c hello.cpp / +ARG SYSROOT=--sysroot=/sysroot +RUN clang ${SYSROOT} hello.c && ./a.out && \ + clang ${SYSROOT} hello.c -static && ./a.out && \ + clang++ ${SYSROOT} hello.cpp && ./a.out && \ + clang++ ${SYSROOT} hello.cpp -static -lc++abi && ./a.out + +### Zlib +COPY --from=source zlib-1.2.12.tar.gz . +RUN tar xf zlib-1.2.12.tar.gz +ARG ZLIB_DIR=zlib-1.2.12/build +RUN mkdir -p ${ZLIB_DIR} +RUN cd ${ZLIB_DIR} && \ + CC="clang ${SYSROOT}" AR=llvm-ar ../configure --prefix=/sysroot/usr +RUN apk add make +RUN make -C ${ZLIB_DIR} -j$(nproc) +RUN make -C ${ZLIB_DIR} -j$(nproc) install +RUN apk del make + +### LLVM +COPY --from=source llvm-project-14.0.1.src.tar.xz . +RUN tar xf llvm-project-14.0.1.src.tar.xz && \ + mv llvm-project-14.0.1.src llvm-project +RUN apk add cmake ninja python3 +COPY stage4.cmake llvm-project/. +ARG LLVM_BUILD_DIR=llvm-project/llvm/build +RUN cmake \ + -B ${LLVM_BUILD_DIR} \ + -C llvm-project/stage4.cmake \ + -D LLVM_DEFAULT_TARGET_TRIPLE=$(clang -print-target-triple) \ + -S llvm-project/llvm \ + -G Ninja +RUN ninja -C ${LLVM_BUILD_DIR} install-clang install-lld +RUN ninja -C ${LLVM_BUILD_DIR} install-clang-resource-headers +RUN ninja -C ${LLVM_BUILD_DIR} \ + install-llvm-ar \ + install-llvm-nm \ + install-llvm-objcopy \ + install-llvm-objdump \ + install-llvm-ranlib \ + install-llvm-readelf \ + install-llvm-strip +RUN ninja -C ${LLVM_BUILD_DIR} install-compiler-rt +RUN ninja -C ${LLVM_BUILD_DIR} install-llvm-profdata + +RUN apk del cmake ninja python3 + +# Final test +RUN llvm-readelf -p .comment $(which clang) | grep -e clang -e LLD +RUN llvm-readelf -p .comment $(which clang) | grep -v GCC + +# Throw away profiles from building LLVM itself. +RUN find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm + +### Start doing kernel builds +# TODO: objtool needs libelf.h and gelf.h? elfutils-dev is the alpine package. +RUN apk add make flex bison +ARG arch=arm +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) allnoconfig all && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm + +ARG arch=arm64 +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) allnoconfig all && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm + +ARG arch=hexagon +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) allnoconfig all && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm + +# Mips needs bash if building all targets. +ARG arch=mips +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) allnoconfig vmlinux && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm + +# powernv_defconfig needs find -printf to work. find in busybox in alpine +# doesn't support that flag. +ARG arch=powerpc +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) allnoconfig vmlinux && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm + +# riscv requires perl to build +RUN apk add perl findutils +ARG arch=riscv +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) defconfig vmlinux && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm +RUN apk del perl findutils + +# s390 needs CC=clang, but Alpine does not package GNU binutils for s390 in +# main, so we need to fetch it from testing. +RUN apk add binutils-s390x --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/ +# We did not build openssl-dev or elfutils-dev, so hack them into the sysroot. +# Don't reuse the sysroot from stage4! +# s390 needs bash and GNU find. +RUN apk add openssl openssl-dev python3 elfutils-dev bash findutils +RUN \ + ln -s /usr/include/gelf.h /sysroot/usr/include/. && \ + ln -s /usr/include/libelf.h /sysroot/usr/include/. && \ + ln -s /usr/lib/libelf.so /sysroot/usr/lib/. && \ + ln -s /usr/include/openssl/ /sysroot/usr/include/. && \ + ln -s /usr/lib/libcrypto.so /sysroot/usr/lib/. +# bpf/resolve_btfids doesn't respect HOSTCFLAGS +RUN cp -r /sysroot/usr/include/ /usr/local/ +# TODO: something in the s390 build isn't respecting HOSTCC. +RUN \ + ln -s $(which clang) /usr/local/bin/gcc && \ + ln -s $(which clang) /usr/local/bin/s390x-alpine-linux-musl-gcc + +ARG arch=s390 +#ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- make CC=clang -j72 defconfig +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + CROSS_COMPILE=s390x-alpine-linux-musl- \ + CC=clang LLVM_IAS=0 \ + make -C linux-5.18-rc6 -s -j$(nproc) defconfig +RUN cd linux-5.18-rc6 && \ + ./scripts/config -d DEBUG_INFO_BTF +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + CROSS_COMPILE=s390x-alpine-linux-musl- \ + CC=clang LLVM_IAS=0 \ + make -C linux-5.18-rc6 -s -j$(nproc) vmlinux +RUN llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm +# Leave openssl-dev and elfutils-dev since we have symlinks to them that the +# x86 build will use. +RUN apk del binutils-s390x openssl bash findutils + +# Objtool on x86 diff from diffutils (BusyBox diff doesn't support -I used in +# tools/objtool/sync-check.sh). +RUN apk add diffutils findutils +# Objtool on x86 requires libelf (but we already did this above for s390). +#RUN apk add elfutils-dev openssl-dev +#### SYSROOT POISON +#RUN \ + #ln -s /usr/include/libelf.h /sysroot/usr/include/. && \ + #ln -s /usr/include/gelf.h /sysroot/usr/include/. && \ + #ln -s /usr/lib/libelf.so /sysroot/usr/lib/. && \ + #ln -s /usr/include/openssl /sysroot/usr/include/. && \ + #ln -s /usr/lib/libcrypto.so /sysroot/usr/lib/. +#### SYSROOT POISON +#### Objtool doesn't respect HOSTCFLAGS +#RUN cp -r /sysroot/usr/include/ /usr/local/ +ARG arch=x86_64 +RUN ARCH=${arch} HOSTCFLAGS=${SYSROOT} HOSTLDFLAGS=${SYSROOT} \ + KBUILDCFLAGS="-I /sysroot/usr/include" \ + make -C linux-5.18-rc6 LLVM=1 -s -j$(nproc) V=1 defconfig vmlinux && \ + llvm-profdata merge --output=${arch}.profdata.prof \ + $(find ${LLVM_BUILD_DIR} -name \*.profraw) && \ + find ${LLVM_BUILD_DIR} -name \*.profraw | xargs rm +#RUN apk del elfutils-dev openssl-dev diffutils +RUN apk del diffutils findutils + +RUN llvm-profdata merge --output=profdata.prof \ + $(find . -maxdepth 1 -name \*.profdata.prof) + +### END STAGE4 +### BEGIN STAGE5 +FROM alpine:edge AS stage5 + +COPY --from=stage3 /usr/local/bin /usr/local/bin +COPY --from=stage3 /usr/local/lib /usr/local/lib +COPY --from=stage3 /usr/local/include /usr/local/include +RUN cd /usr/lib/ && \ + for library in libc++abi.so.1 libc++.a libc++abi.a libc++.so.1 libunwind.so.1 libunwind.a; \ + do ln -s "/usr/local/lib/x86_64-alpine-linux-musl/${library}" . ; \ + done + +### Linux +COPY --from=source linux-5.18-rc6.tar.gz . +RUN tar xf linux-5.18-rc6.tar.gz +RUN apk add make musl-dev rsync +RUN make -C linux-5.18-rc6 INSTALL_HDR_PATH=/sysroot/usr LLVM=1 -j$(nproc) headers_install +RUN apk del rsync musl-dev make + +### Musl +COPY --from=source musl-1.2.3.tar.gz . +RUN tar xf musl-1.2.3.tar.gz +ARG MUSL_DIR=musl-1.2.3/build +RUN mkdir -p ${MUSL_DIR} +RUN cd ${MUSL_DIR} && \ + CC=clang AR=llvm-ar RANLIB=llvm-ranlib \ + ../configure --prefix=/usr --syslibdir=/usr/lib +RUN apk add make +RUN make -C ${MUSL_DIR} -j$(nproc) +RUN make -C ${MUSL_DIR} -j$(nproc) DESTDIR=/sysroot install-headers +RUN make -C ${MUSL_DIR} -j$(nproc) DESTDIR=/sysroot install-libs +RUN apk del make + +# Pause for a quick sanity check +COPY hello.c hello.cpp / +ARG SYSROOT=--sysroot=/sysroot +RUN clang ${SYSROOT} hello.c && ./a.out && \ + clang ${SYSROOT} hello.c -static && ./a.out && \ + clang++ ${SYSROOT} hello.cpp && ./a.out && \ + clang++ ${SYSROOT} hello.cpp -static -lc++abi && ./a.out + +### Zlib +COPY --from=source zlib-1.2.12.tar.gz . +RUN tar xf zlib-1.2.12.tar.gz +ARG ZLIB_DIR=zlib-1.2.12/build +RUN mkdir -p ${ZLIB_DIR} +RUN cd ${ZLIB_DIR} && \ + CC="clang ${SYSROOT}" AR=llvm-ar ../configure --prefix=/sysroot/usr +RUN apk add make +RUN make -C ${ZLIB_DIR} -j$(nproc) +RUN make -C ${ZLIB_DIR} -j$(nproc) install +RUN apk del make + +### LLVM +COPY --from=source llvm-project-14.0.1.src.tar.xz . +RUN tar xf llvm-project-14.0.1.src.tar.xz && \ + mv llvm-project-14.0.1.src llvm-project +RUN apk add cmake ninja python3 +COPY stage5.cmake llvm-project/. +ARG LLVM_BUILD_DIR=llvm-project/llvm/build +RUN cmake \ + -B ${LLVM_BUILD_DIR} \ + -C llvm-project/stage5.cmake \ + -D LLVM_DEFAULT_TARGET_TRIPLE=$(clang -print-target-triple) \ + -S llvm-project/llvm \ + -G Ninja +RUN ninja -C ${LLVM_BUILD_DIR} clang-tblgen +RUN ninja -C ${LLVM_BUILD_DIR} llvm-tblgen +RUN ninja -C ${LLVM_BUILD_DIR} clang +#RUN ninja -C ${LLVM_BUILD_DIR} install-clang install-lld +#RUN ninja -C ${LLVM_BUILD_DIR} install-clang-resource-headers +#RUN ninja -C ${LLVM_BUILD_DIR} \ + #install-llvm-ar \ + #install-llvm-nm \ + #install-llvm-objcopy \ + #install-llvm-objdump \ + #install-llvm-ranlib \ + #install-llvm-readelf \ + #install-llvm-strip + +#RUN apk del cmake ninja python3 + +# Final test +#RUN llvm-readelf -p .comment $(which clang) | grep -e clang -e LLD +#RUN llvm-readelf -p .comment $(which clang) | grep -v GCC diff --git a/llvm-project/Makefile b/llvm-project/Makefile index b382112..48f632a 100644 --- a/llvm-project/Makefile +++ b/llvm-project/Makefile @@ -30,10 +30,13 @@ epoch2: epoch3: $(call epoch_cmd,$@,$(IMAGE):stage3-$(HOST_ARCH),$(IMAGE):stage2-$(HOST_ARCH)) -clang: epoch3 - $(DOCKER) rm llvm-project || true - $(DOCKER) create --name llvm-project $(IMAGE):stage3-$(HOST_ARCH) +epoch4: + $(call epoch_cmd,$@,$(IMAGE):stage4-$(HOST_ARCH),$(IMAGE):stage3-$(HOST_ARCH)) + +clang: epoch4 + $(DOCKER) create --name llvm-project $(IMAGE):stage4-$(HOST_ARCH) $(DOCKER) cp llvm-project:/usr/local/bin/clang-14 clang + $(DOCKER) rm llvm-project -test: epoch3 - bash ../ci/test-clang.sh $(IMAGE):stage3-$(HOST_ARCH) +test: epoch4 + bash ../ci/test-clang.sh $(IMAGE):stage4-$(HOST_ARCH) diff --git a/llvm-project/stage4.cmake b/llvm-project/stage4.cmake new file mode 100644 index 0000000..ccc6ff6 --- /dev/null +++ b/llvm-project/stage4.cmake @@ -0,0 +1,95 @@ +# Please try to keep these cmake variables alphabetically sorted. + +# Enable optimizations, as opposed to a debug build. +set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") + +# Explicitly use stage3's clang. Not necessary, just being explicit. +set(CMAKE_CXX_COMPILER "/usr/local/bin/clang++" CACHE FILEPATH "") +set(CMAKE_C_COMPILER "/usr/local/bin/clang" CACHE FILEPATH "") + +# See above comment for CMAKE_CXX_COMPILER. +# Use the sysroot we've been building up. +set(CMAKE_CXX_FLAGS "--sysroot=/sysroot" CACHE STRING "") +set(CMAKE_C_FLAGS "--sysroot=/sysroot" CACHE STRING "") + +# Statically link resulting executable. +set(CMAKE_EXE_LINKER_FLAGS "-static -lc++abi" CACHE STRING "") + +# The compiler builtins are necessary. +set(COMPILER_RT_BUILD_BUILTINS ON CACHE BOOL "") + +# GWP ASAN fails to build without libexecinfo-dev. Don't need it for stage3. +set(COMPILER_RT_BUILD_GWP_ASAN OFF CACHE BOOL "") + +# Don't need libfuzzer, ever. +set(COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") + +# Don't need memprof, ever. +set(COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "") + +# Don't need ORC, ever. +set(COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") + +# Explicitly enable profiling support. The implicit default is ON. +set(COMPILER_RT_BUILD_PROFILE ON CACHE BOOL "") + +# Disable sanitizer support. Not necessary for stage3. +set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") + +# Don't need xray. +set(COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") + +# Build LLVM instrumented to collect PGO profile data. +set(LLVM_BUILD_INSTRUMENTED ON CACHE BOOL "") + +# Use libc++ from stage3. +# TODO: is CMAKE_CXX_FLAGS still necessary if this is set? +set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "") + +# Use lld from stage3. +set(LLVM_ENABLE_LLD ON CACHE BOOL "") + +# Build clang, lld, and compiler-rt. +set(LLVM_ENABLE_PROJECTS "clang;lld;compiler-rt" CACHE STRING "") + +# FORCE_ON causes the build to fail if zlib is not found in the environment +# during configuration, rather than much later during link. +set(LLVM_ENABLE_ZLIB "FORCE_ON" CACHE STRING "") + +# This is necessary to statically link libc++ into clang. +set(LLVM_STATIC_LINK_CXX_STDLIB "1" CACHE STRING "") + +# Build all relevant targets. +set(LLVM_TARGETS_TO_BUILD "AArch64;ARM;Hexagon;Mips;PowerPC;RISCV;SystemZ;X86" CACHE STRING "") + +# Necessary to avoid warnings about counter overflow. +set(LLVM_VP_COUNTERS_PER_SITE "6" CACHE STRING "") + +# Set clang's default --stdlib= to libc++. +set(CLANG_DEFAULT_CXX_STDLIB "libc++" CACHE STRING "") + +# Set clang's default -fuse-ld= to lld. +set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") + +# Have clang default to llvm-objcopy. +set(CLANG_DEFAULT_OBJCOPY "llvm-objcopy" CACHE STRING "") + +# Set clang's default --rtlib= to compiler-rt. +set(CLANG_DEFAULT_RTLIB "compiler-rt" CACHE STRING "") + +# Set clang's default --unwindlib= to libunwind. +set(CLANG_DEFAULT_UNWINDLIB "libunwind" CACHE STRING "") + +# Disable arc migrate. We don't use that, ever. +set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") + +# Disable static analyzer. Don't need it for stage3. +set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") + +# Disable plugin support. Don't need it, ever. +set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") + +# Because we're using --prefix=/sysroot/usr, zlib gets installed to a +# non-standard path. +set(ZLIB_INCLUDE_DIR "/sysroot/usr/include/zlib.h" CACHE FILEPATH "") +set(ZLIB_LIBRARY "/sysroot/usr/lib/libz.a" CACHE FILEPATH "") diff --git a/llvm-project/stage5.cmake b/llvm-project/stage5.cmake new file mode 100644 index 0000000..f9a6183 --- /dev/null +++ b/llvm-project/stage5.cmake @@ -0,0 +1,97 @@ +# Please try to keep these cmake variables alphabetically sorted. + +# Enable optimizations, as opposed to a debug build. +set(CMAKE_BUILD_TYPE "Release" CACHE STRING "") + +# Explicitly use stage3's clang. Not necessary, just being explicit. +set(CMAKE_CXX_COMPILER "/usr/local/bin/clang++" CACHE FILEPATH "") +set(CMAKE_C_COMPILER "/usr/local/bin/clang" CACHE FILEPATH "") + +# See above comment for CMAKE_CXX_COMPILER. +# Use the sysroot we've been building up. +set(CMAKE_CXX_FLAGS "--sysroot=/sysroot" CACHE STRING "") +set(CMAKE_C_FLAGS "--sysroot=/sysroot" CACHE STRING "") + +# Statically link resulting executable. +set(CMAKE_EXE_LINKER_FLAGS "-static -lc++abi" CACHE STRING "") + +# The compiler builtins are necessary. +set(COMPILER_RT_BUILD_BUILTINS ON CACHE BOOL "") + +# GWP ASAN fails to build without libexecinfo-dev. Don't need it for stage5. +set(COMPILER_RT_BUILD_GWP_ASAN OFF CACHE BOOL "") + +# Don't need libfuzzer, ever. +set(COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") + +# Don't need memprof, ever. +set(COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "") + +# Don't need ORC, ever. +set(COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") + +# Explicitly enable profiling support. The implicit default is ON. +set(COMPILER_RT_BUILD_PROFILE ON CACHE BOOL "") + +# Disable sanitizer support. Not necessary for stage5. +set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") + +# Don't need xray. +set(COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") + +# Use libc++ from stage3. +# TODO: is CMAKE_CXX_FLAGS still necessary if this is set? +set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "") + +# Use lld from stage3. +set(LLVM_ENABLE_LLD ON CACHE BOOL "") + +# TODO: clang segfaults when building llvm-tblgen. Do we need to use +# `--ulimit nofile=65536` for `docker build`? +# Build LLVM with thinLTO. This requires we bump the default memory limit up. +#set(LLVM_ENABLE_LTO "Thin" CACHE STRING "") + +# Build clang, lld, and compiler-rt. +set(LLVM_ENABLE_PROJECTS "clang;lld;compiler-rt" CACHE STRING "") + +# FORCE_ON causes the build to fail if zlib is not found in the environment +# during configuration, rather than much later during link. +set(LLVM_ENABLE_ZLIB "FORCE_ON" CACHE STRING "") + +# Consume PGO training data from stage4. +set(LLVM_PROFDATA_FILE "profdata.prof" CACHE FILEPATH "") + +# This is necessary to statically link libc++ into clang. +set(LLVM_STATIC_LINK_CXX_STDLIB "1" CACHE STRING "") + +# Build all relevant targets. +set(LLVM_TARGETS_TO_BUILD "AArch64;ARM;Hexagon;Mips;PowerPC;RISCV;SystemZ;X86" CACHE STRING "") + +# Set clang's default --stdlib= to libc++. +set(CLANG_DEFAULT_CXX_STDLIB "libc++" CACHE STRING "") + +# Set clang's default -fuse-ld= to lld. +set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") + +# Have clang default to llvm-objcopy. +set(CLANG_DEFAULT_OBJCOPY "llvm-objcopy" CACHE STRING "") + +# Set clang's default --rtlib= to compiler-rt. +set(CLANG_DEFAULT_RTLIB "compiler-rt" CACHE STRING "") + +# Set clang's default --unwindlib= to libunwind. +set(CLANG_DEFAULT_UNWINDLIB "libunwind" CACHE STRING "") + +# Disable arc migrate. We don't use that, ever. +set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") + +# Disable static analyzer. Don't need it for stage5. +set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") + +# Disable plugin support. Don't need it, ever. +set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") + +# Because we're using --prefix=/sysroot/usr, zlib gets installed to a +# non-standard path. +set(ZLIB_INCLUDE_DIR "/sysroot/usr/include/zlib.h" CACHE FILEPATH "") +set(ZLIB_LIBRARY "/sysroot/usr/lib/libz.a" CACHE FILEPATH "")