diff options
Diffstat (limited to 'taskcluster/scripts/misc/build-clang-mingw.sh')
-rwxr-xr-x | taskcluster/scripts/misc/build-clang-mingw.sh | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/taskcluster/scripts/misc/build-clang-mingw.sh b/taskcluster/scripts/misc/build-clang-mingw.sh new file mode 100755 index 0000000000..7dc7843de7 --- /dev/null +++ b/taskcluster/scripts/misc/build-clang-mingw.sh @@ -0,0 +1,311 @@ +#!/bin/bash +set -x -e -v + +# This script is for building a mingw-clang toolchain for use on Linux. + +if [[ $# -eq 0 ]]; then + echo "Provide either x86 or x64 to specify a toolchain." + exit 1; +elif [ "$1" == "x86" ]; then + machine="i686" + compiler_rt_machine="i386" + crt_flags="--enable-lib32 --disable-lib64" + WRAPPER_FLAGS="" +elif [ "$1" == "x64" ]; then + machine="x86_64" + compiler_rt_machine="x86_64" + crt_flags="--disable-lib32 --enable-lib64" + WRAPPER_FLAGS="" +else + echo "Provide either x86 or x64 to specify a toolchain." + exit 1; +fi + +TOOLCHAIN_DIR=$MOZ_FETCHES_DIR/llvm-project +INSTALL_DIR=$TOOLCHAIN_DIR/build/stage4/clang +CROSS_PREFIX_DIR=$INSTALL_DIR/$machine-w64-mingw32 + +make_flags="-j$(nproc)" + +if [ -d "$MOZ_FETCHES_DIR/binutils/bin" ]; then + export PATH="$MOZ_FETCHES_DIR/binutils/bin:$PATH" +fi + +# This is default value of _WIN32_WINNT. Gecko configure script explicitly sets this, +# so this is not used to build Gecko itself. We default to 0x601, which is Windows 7. +default_win32_winnt=0x601 + +cd $GECKO_PATH + +patch_file1="$(pwd)/taskcluster/scripts/misc/mingw-winrt.patch" +patch_file2="$(pwd)/taskcluster/scripts/misc/mingw-dwrite_3.patch" + +prepare() { + pushd $MOZ_FETCHES_DIR/mingw-w64 + patch -p1 <$patch_file1 + patch -p1 <$patch_file2 + popd +} + +install_wrappers() { + pushd $INSTALL_DIR/bin + + compiler_flags="--sysroot \$DIR/../$machine-w64-mingw32 -rtlib=compiler-rt -stdlib=libc++ -fuse-ld=lld $WRAPPER_FLAGS -fuse-cxa-atexit -Qunused-arguments" + + cat <<EOF >$machine-w64-mingw32-clang +#!/bin/sh +DIR="\$(cd "\$(dirname "\$0")" && pwd)" +\$DIR/clang -target $machine-w64-mingw32 $compiler_flags "\$@" +EOF + chmod +x $machine-w64-mingw32-clang + + cat <<EOF >$machine-w64-mingw32-clang++ +#!/bin/sh +DIR="\$(cd "\$(dirname "\$0")" && pwd)" +\$DIR/clang -target $machine-w64-mingw32 --driver-mode=g++ $compiler_flags "\$@" +EOF + chmod +x $machine-w64-mingw32-clang++ + + CC="$machine-w64-mingw32-clang" + CXX="$machine-w64-mingw32-clang++" + + popd +} + +build_mingw() { + mkdir mingw-w64-headers + pushd mingw-w64-headers + $MOZ_FETCHES_DIR/mingw-w64/mingw-w64-headers/configure \ + --host=$machine-w64-mingw32 \ + --enable-sdk=all \ + --enable-idl \ + --with-default-msvcrt=ucrt \ + --with-default-win32-winnt=$default_win32_winnt \ + --prefix=$CROSS_PREFIX_DIR + make $make_flags install + popd + + mkdir mingw-w64-crt + pushd mingw-w64-crt + $MOZ_FETCHES_DIR/mingw-w64/mingw-w64-crt/configure \ + --host=$machine-w64-mingw32 \ + $crt_flags \ + --with-default-msvcrt=ucrt \ + CC="$CC" \ + AR=llvm-ar \ + RANLIB=llvm-ranlib \ + DLLTOOL=llvm-dlltool \ + --prefix=$CROSS_PREFIX_DIR + make $make_flags + make $make_flags install + popd + + mkdir widl + pushd widl + $MOZ_FETCHES_DIR/mingw-w64/mingw-w64-tools/widl/configure --target=$machine-w64-mingw32 --prefix=$INSTALL_DIR + make $make_flags + make $make_flags install + popd +} + +build_compiler_rt() { + CLANG_VERSION=$(basename $(dirname $(dirname $(dirname $($CC --print-libgcc-file-name -rtlib=compiler-rt))))) + mkdir compiler-rt + pushd compiler-rt + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \ + -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \ + -DCMAKE_C_COMPILER_WORKS=1 \ + -DCMAKE_C_COMPILER_TARGET=$compiler_rt_machine-windows-gnu \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=TRUE \ + $TOOLCHAIN_DIR/compiler-rt/lib/builtins + make $make_flags + mkdir -p $INSTALL_DIR/lib/clang/$CLANG_VERSION/lib/windows + cp lib/windows/libclang_rt.builtins-$compiler_rt_machine.a $INSTALL_DIR/lib/clang/$CLANG_VERSION/lib/windows/ + popd +} + +merge_libs() { + cat <<EOF |llvm-ar -M +CREATE tmp.a +ADDLIB $1 +ADDLIB $2 +SAVE +END +EOF + llvm-ranlib tmp.a + mv tmp.a $1 +} + +build_libcxx() { + # Below, we specify -g -gcodeview to build static libraries with debug information. + # Because we're not distributing these builds, this is fine. If one were to distribute + # the builds, perhaps one would want to make those flags conditional or investigation + # other options. + DEBUG_FLAGS="-g -gcodeview" + + mkdir libunwind + pushd libunwind + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_CROSSCOMPILING=TRUE \ + -DCMAKE_SYSROOT=$CROSS_PREFIX_DIR \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_WORKS=TRUE \ + -DCMAKE_CXX_COMPILER_WORKS=TRUE \ + -DLLVM_COMPILER_CHECKED=TRUE \ + -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \ + -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \ + -DLLVM_NO_OLD_LIBSTDCXX=TRUE \ + -DCXX_SUPPORTS_CXX11=TRUE \ + -DCXX_SUPPORTS_CXX_STD=TRUE \ + -DLIBUNWIND_USE_COMPILER_RT=TRUE \ + -DLIBUNWIND_ENABLE_THREADS=TRUE \ + -DLIBUNWIND_ENABLE_SHARED=FALSE \ + -DLIBUNWIND_ENABLE_CROSS_UNWINDING=FALSE \ + -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -Wno-dll-attribute-on-redeclaration -nostdinc++ -I$TOOLCHAIN_DIR/libcxx/include -DPSAPI_VERSION=2" \ + -DCMAKE_C_FLAGS="-Wno-dll-attribute-on-redeclaration" \ + $MOZ_FETCHES_DIR/libunwind + make $make_flags + make $make_flags install + popd + + mkdir libcxxabi + pushd libcxxabi + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_CROSSCOMPILING=TRUE \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_WORKS=TRUE \ + -DCMAKE_CXX_COMPILER_WORKS=TRUE \ + -DCMAKE_SYSROOT=$CROSS_PREFIX_DIR \ + -DLLVM_COMPILER_CHECKED=TRUE \ + -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \ + -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \ + -DLIBCXXABI_USE_COMPILER_RT=ON \ + -DLIBCXXABI_ENABLE_EXCEPTIONS=ON \ + -DLIBCXXABI_ENABLE_THREADS=ON \ + -DLIBCXXABI_TARGET_TRIPLE=$machine-w64-mingw32 \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ + -DLIBCXXABI_LIBCXX_INCLUDES=$TOOLCHAIN_DIR/libcxx/include \ + -DLLVM_NO_OLD_LIBSTDCXX=TRUE \ + -DCXX_SUPPORTS_CXX11=TRUE \ + -DCXX_SUPPORTS_CXX_STD=TRUE \ + -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_HAS_THREAD_API_WIN32" \ + $TOOLCHAIN_DIR/libcxxabi + make $make_flags VERBOSE=1 + popd + + mkdir libcxx + pushd libcxx + cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$CROSS_PREFIX_DIR \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_CROSSCOMPILING=TRUE \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_WORKS=TRUE \ + -DCMAKE_CXX_COMPILER_WORKS=TRUE \ + -DLLVM_COMPILER_CHECKED=TRUE \ + -DCMAKE_AR=$INSTALL_DIR/bin/llvm-ar \ + -DCMAKE_RANLIB=$INSTALL_DIR/bin/llvm-ranlib \ + -DLIBCXX_USE_COMPILER_RT=ON \ + -DLIBCXX_INSTALL_HEADERS=ON \ + -DLIBCXX_ENABLE_EXCEPTIONS=ON \ + -DLIBCXX_ENABLE_THREADS=ON \ + -DLIBCXX_HAS_WIN32_THREAD_API=ON \ + -DLIBCXX_ENABLE_MONOTONIC_CLOCK=ON \ + -DLIBCXX_ENABLE_SHARED=OFF \ + -DLIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG=TRUE \ + -DLIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB=TRUE \ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \ + -DLIBCXX_ENABLE_FILESYSTEM=OFF \ + -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE \ + -DLIBCXX_CXX_ABI=libcxxabi \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS=$TOOLCHAIN_DIR/libcxxabi/include \ + -DLIBCXX_CXX_ABI_LIBRARY_PATH=../libcxxabi/lib \ + -DCMAKE_CXX_FLAGS="${DEBUG_FLAGS} -D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS" \ + $TOOLCHAIN_DIR/libcxx + make $make_flags VERBOSE=1 + make $make_flags install + + # libc++.a depends on libunwind.a. Whild linker will automatically link + # to libc++.a in C++ mode, it won't pick libunwind.a, requiring caller + # to explicitly pass -lunwind. Wo work around that, we merge libunwind.a + # into libc++.a. + merge_libs $CROSS_PREFIX_DIR/lib/libc++.a $CROSS_PREFIX_DIR/lib/libunwind.a + popd +} + +build_libssp() { + pushd $MOZ_FETCHES_DIR/gcc-source/ + + # Massage the environment for the build-libssp.sh script + mkdir -p ./$machine-w64-mingw32/lib + cp $MOZ_FETCHES_DIR/llvm-mingw/libssp-Makefile . + sed -i 's/set -e/set -x -e -v/' $MOZ_FETCHES_DIR/llvm-mingw/build-libssp.sh + sed -i 's/(CROSS)gcc/(CROSS)clang/' libssp-Makefile + sed -i 's/\$(CROSS)ar/llvm-ar/' libssp-Makefile + OLDPATH=$PATH + PATH=$INSTALL_DIR/clang/bin:$PATH + + # Run the script + TOOLCHAIN_ARCHS=$machine $MOZ_FETCHES_DIR/llvm-mingw/build-libssp.sh . + + # Grab the artifacts, cleanup + cp $MOZ_FETCHES_DIR/gcc-source/$machine-w64-mingw32/lib/{libssp.a,libssp_nonshared.a} $INSTALL_DIR/$machine-w64-mingw32/lib/ + unset TOOLCHAIN_ARCHS + PATH=$OLDPATH + popd +} + +build_utils() { + pushd $INSTALL_DIR/bin/ + ln -s llvm-nm $machine-w64-mingw32-nm + ln -s llvm-strip $machine-w64-mingw32-strip + ln -s llvm-readobj $machine-w64-mingw32-readobj + ln -s llvm-objcopy $machine-w64-mingw32-objcopy + ./clang $MOZ_FETCHES_DIR/llvm-mingw/wrappers/windres-wrapper.c -O2 -Wl,-s -o $machine-w64-mingw32-windres + popd +} + +export PATH=$INSTALL_DIR/bin:$PATH + +prepare + +# gets a bit too verbose here +set +x + +cd $TOOLCHAIN_DIR +python3 $GECKO_PATH/build/build-clang/build-clang.py -c $GECKO_PATH/$2 --skip-tar + +set -x + +pushd $TOOLCHAIN_DIR/build + +install_wrappers +build_mingw +build_compiler_rt +build_libcxx +build_libssp +build_utils + +popd + +# Put a tarball in the artifacts dir +mkdir -p $UPLOAD_DIR + +pushd $(dirname $INSTALL_DIR) +tar c clang | $GECKO_PATH/taskcluster/scripts/misc/zstdpy > clangmingw.tar.zst +mv clangmingw.tar.zst $UPLOAD_DIR +popd |