diff --git a/build-all.sh b/build-all.sh index d13827a..ba8603d 100755 --- a/build-all.sh +++ b/build-all.sh @@ -16,6 +16,7 @@ set -e +HOST_CLANG= LLVM_ARGS="" MINGW_ARGS="" CFGUARD_ARGS="--enable-cfguard" @@ -26,6 +27,11 @@ while [ $# -gt 0 ]; do --enable-asserts) LLVM_ARGS="$LLVM_ARGS $1" ;; + --host-clang|--host-clang=*) + HOST_CLANG=${1#--host-clang} + HOST_CLANG=${HOST_CLANG#=} + HOST_CLANG=${HOST_CLANG:-clang} + ;; --full-llvm) LLVM_ARGS="$LLVM_ARGS $1" FULL_LLVM=1 @@ -78,11 +84,11 @@ while [ $# -gt 0 ]; do shift done if [ -z "$PREFIX" ]; then - echo "$0 [--enable-asserts] [--disable-dylib] [--full-llvm] [--with-python] [--disable-lldb] [--disable-lldb-mi] [--disable-clang-tools-extra] [--host=triple] [--with-default-win32-winnt=0x601] [--with-default-msvcrt=ucrt] [--enable-cfguard|--disable-cfguard] [--no-runtimes] [--no-tools] [--wipe-runtimes] dest" + echo "$0 [--host-clang[=clang]] [--enable-asserts] [--disable-dylib] [--full-llvm] [--with-python] [--disable-lldb] [--disable-lldb-mi] [--disable-clang-tools-extra] [--host=triple] [--with-default-win32-winnt=0x601] [--with-default-msvcrt=ucrt] [--enable-cfguard|--disable-cfguard] [--no-runtimes] [--no-tools] [--wipe-runtimes] dest" exit 1 fi -for dep in git cmake; do +for dep in git cmake ${HOST_CLANG}; do if ! command -v $dep >/dev/null; then echo "$dep not installed. Please install it and retry" 1>&2 exit 1 @@ -90,14 +96,16 @@ for dep in git cmake; do done if [ -z "$NO_TOOLS" ]; then - ./build-llvm.sh $PREFIX $LLVM_ARGS $HOST_ARGS - if [ -z "$NO_LLDB" ] && [ -z "$NO_LLDB_MI" ]; then - ./build-lldb-mi.sh $PREFIX $HOST_ARGS + if [ -z "${HOST_CLANG}" ]; then + ./build-llvm.sh $PREFIX $LLVM_ARGS $HOST_ARGS + if [ -z "$NO_LLDB" ] && [ -z "$NO_LLDB_MI" ]; then + ./build-lldb-mi.sh $PREFIX $HOST_ARGS + fi + if [ -z "$FULL_LLVM" ]; then + ./strip-llvm.sh $PREFIX $HOST_ARGS + fi fi - if [ -z "$FULL_LLVM" ]; then - ./strip-llvm.sh $PREFIX $HOST_ARGS - fi - ./install-wrappers.sh $PREFIX $HOST_ARGS + ./install-wrappers.sh $PREFIX $HOST_ARGS ${HOST_CLANG:+--host-clang=$HOST_CLANG} ./build-mingw-w64-tools.sh $PREFIX $HOST_ARGS fi if [ -n "$NO_RUNTIMES" ]; then diff --git a/build-compiler-rt.sh b/build-compiler-rt.sh index 68ff1f8..33055ac 100755 --- a/build-compiler-rt.sh +++ b/build-compiler-rt.sh @@ -81,6 +81,8 @@ else fi cd llvm-project/compiler-rt +# Use a staging directory in case parts of the resource dir are immutable +WORKDIR=$(mktemp -d); trap "rm -rf $WORKDIR" 0 for arch in $ARCHS; do if [ -n "$SANITIZERS" ]; then @@ -123,10 +125,16 @@ for arch in $ARCHS; do -DCMAKE_CXX_FLAGS_INIT="$CFGUARD_CFLAGS" \ $SRC_DIR cmake --build . ${CORES:+-j${CORES}} - cmake --install . + cmake --install . --prefix "${WORKDIR}/install" mkdir -p "$PREFIX/$arch-w64-mingw32/bin" if [ -n "$SANITIZERS" ]; then - mv "$CLANG_RESOURCE_DIR/lib/windows/"*.dll "$PREFIX/$arch-w64-mingw32/bin" + mv "${WORKDIR}/install/lib/windows/"*.dll "$PREFIX/$arch-w64-mingw32/bin" fi cd .. done + +if [ -h "$CLANG_RESOURCE_DIR/include" ]; then + # symlink to system headers - skip copy + rm -rf ${WORKDIR}/install/include +fi +cp -r ${WORKDIR}/install/. $CLANG_RESOURCE_DIR diff --git a/install-wrappers.sh b/install-wrappers.sh index 0ce5663..0df42ab 100755 --- a/install-wrappers.sh +++ b/install-wrappers.sh @@ -17,9 +17,15 @@ set -e unset HOST +unset HOST_CLANG while [ $# -gt 0 ]; do case "$1" in + --host-clang|--host-clang=*) + HOST_CLANG=${1#--host-clang} + HOST_CLANG=${HOST_CLANG#=} + HOST_CLANG=${HOST_CLANG:-clang} + ;; --host=*) HOST="${1#*=}" ;; @@ -30,7 +36,7 @@ while [ $# -gt 0 ]; do shift done if [ -z "$PREFIX" ]; then - echo $0 [--host=triple] dest + echo $0 [--host=triple] [--host-clang[=clang]] dest exit 1 fi mkdir -p "$PREFIX" @@ -58,6 +64,44 @@ else esac fi +if [ -n "${HOST_CLANG}" ]; then + HOST_CLANG_EXE=$(command -v $HOST_CLANG) + HOST_CLANG_VER=$(echo "__clang_major__ __clang_minor__ __clang_patchlevel__" | $HOST_CLANG_EXE -E -P -x c - | xargs printf '%d.%d.%d') + + mkdir -p $PREFIX/bin + + # ex. /usr/lib/llvm-17/lib/clang/17 + resdir=$($HOST_CLANG -print-resource-dir) + # ex. /usr/lib/llvm-17 + llvmdir=${resdir%/lib/clang/*} + # ex /lib/clang/17 + clangres=${resdir#$llvmdir} + + mkdir -p $PREFIX$clangres + + # link the header directory, prevent modification + ln -snf $resdir/include $PREFIX$clangres/include + + # Note: clang will detect the "InstalledDir" based on the path that was used to invoke the tools + # This might still have some hidden effects + printf '#!/bin/sh\nsr=$(dirname "$(dirname "$(readlink -f "$0")")")\nexec %s -resource-dir="$sr"%s --sysroot="$sr" "$@"\n' "$HOST_CLANG_EXE" "$clangres" > $PREFIX/bin/clang + # printf '#!/bin/sh\nsr=$(dirname "$(dirname "$(readlink -f "$0")")")\nexec %s -resource-dir="$sr"%s --sysroot="$sr" "$@"\n' "$(readlink -f "$HOST_CLANG_EXE")" "$clangres" > $PREFIX/bin/clang + chmod 755 $PREFIX/bin/clang + ln -sf clang $PREFIX/bin/clang++ + ln -sf clang $PREFIX/bin/clang-cpp + + echo "Using existing clang $HOST_CLANG_EXE ($HOST_CLANG_VER)" + $PREFIX/bin/clang -v + + # prefer system llvm installation, but search in llvm private paths (eg. debian does not symlink all tools into /usr/bin) + llvmexec="$PATH:$llvmdir/bin" + + for exec in ld.lld llvm-ar llvm-ranlib llvm-nm llvm-objcopy llvm-strip llvm-rc llvm-cvtres \ + llvm-addr2line llvm-dlltool llvm-readelf llvm-size llvm-strings llvm-addr2line llvm-windres llvm-ml; do + execpath=$(PATH=$llvmexec command -v $exec) && ln -sf $execpath $PREFIX/bin/$exec + done +fi + if [ -n "$MACOS_REDIST" ]; then : ${MACOS_REDIST_ARCHS:=arm64 x86_64} : ${MACOS_REDIST_VERSION:=10.9}