From e0964ce24c086bb9f7de0916157f9177e85049d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 14 Oct 2024 14:23:08 +0300 Subject: [PATCH] Revert use of Clang config files This reverts commit 49db4a3a15b005c501d0dcd2a2d7df77ec7703a1, 9f1f0104f1cf696ab9487a7e74ed3dd98d19c300, 4f95c14adfc60c3e9dd055e2593fabbd44fd5880, c34dc64028bfc3418d34b8e7c086709b64ba8dbe, 570fdcd25186dd07934b58e4f42564a0b9098030, 4bff0298c5189b9eec5591a702db009b01291288 and 6939aee0c0eb6fe0ce8b1f82f53b05b03aa4226c. When relying on Clang config files, two issues appeared: - Running the compiler-rt tests fails, because the compiler-rt tests disable any default config files, breaking the compiler in this case: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.1/compiler-rt/test/lit.common.cfg.py#L983 - Wine fails to build using llvm-mingw as cross compiler, because Wine adds the --no-default-config flag to Clang while compiling, if supported: https://gitlab.winehq.org/wine/wine/-/blob/wine-9.19/configure.ac?ref_type=tags#L866-868 This causes llvm-mingw to omit the -rtlib=compiler-rt option (specified in a config file), making the compiler look for libgcc instead. Doing a check to see that linking succeeds doesn't necessarily help here - such a check already exists, but it tests linking with -nostdlib -nodefaultlibs: https://gitlab.winehq.org/wine/wine/-/blob/wine-9.19/aclocal.m4?ref_type=tags#L193-L206 --- Dockerfile | 2 +- Dockerfile.cross | 2 +- Dockerfile.dev | 2 +- build-llvm.sh | 11 +++++ install-wrappers.sh | 8 +--- wrappers/aarch64-w64-windows-gnu.cfg | 3 -- wrappers/armv7-w64-windows-gnu.cfg | 3 -- wrappers/clang-scan-deps-wrapper.c | 8 ++-- wrappers/clang-scan-deps-wrapper.sh | 67 ++++++++++++++++++++++++++++ wrappers/clang-target-wrapper.c | 16 ++++++- wrappers/clang-target-wrapper.sh | 18 ++++++++ wrappers/i686-w64-windows-gnu.cfg | 3 -- wrappers/mingw32-common.cfg | 4 -- wrappers/x86_64-w64-windows-gnu.cfg | 3 -- 14 files changed, 119 insertions(+), 31 deletions(-) delete mode 100644 wrappers/aarch64-w64-windows-gnu.cfg delete mode 100644 wrappers/armv7-w64-windows-gnu.cfg create mode 100755 wrappers/clang-scan-deps-wrapper.sh delete mode 100644 wrappers/i686-w64-windows-gnu.cfg delete mode 100644 wrappers/mingw32-common.cfg delete mode 100644 wrappers/x86_64-w64-windows-gnu.cfg diff --git a/Dockerfile b/Dockerfile index 0fba921..550db90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ ARG CFGUARD_ARGS=--enable-cfguard # Build everything that uses the llvm monorepo. We need to build the mingw runtime before the compiler-rt/libunwind/libcxxabi/libcxx runtimes. COPY build-llvm.sh build-lldb-mi.sh strip-llvm.sh install-wrappers.sh build-mingw-w64.sh build-mingw-w64-tools.sh build-compiler-rt.sh build-libcxx.sh build-mingw-w64-libraries.sh build-openmp.sh ./ -COPY wrappers/*.sh wrappers/*.c wrappers/*.h wrappers/*.cfg ./wrappers/ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ RUN ./build-llvm.sh $TOOLCHAIN_PREFIX && \ ./build-lldb-mi.sh $TOOLCHAIN_PREFIX && \ ./strip-llvm.sh $TOOLCHAIN_PREFIX && \ diff --git a/Dockerfile.cross b/Dockerfile.cross index 3329647..f41d0e5 100644 --- a/Dockerfile.cross +++ b/Dockerfile.cross @@ -54,7 +54,7 @@ ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" COPY build-mingw-w64.sh build-mingw-w64-tools.sh ./ RUN ./build-mingw-w64-tools.sh $CROSS_TOOLCHAIN_PREFIX --skip-include-triplet-prefix --host=$HOST -COPY wrappers/*.sh wrappers/*.c wrappers/*.h wrappers/*.cfg ./wrappers/ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ COPY install-wrappers.sh . RUN ./install-wrappers.sh $CROSS_TOOLCHAIN_PREFIX --host=$HOST diff --git a/Dockerfile.dev b/Dockerfile.dev index f0eb305..d0bdfd7 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -37,7 +37,7 @@ RUN ./strip-llvm.sh $TOOLCHAIN_PREFIX ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" # Install the usual $TUPLE-clang binaries -COPY wrappers/*.sh wrappers/*.c wrappers/*.h wrappers/*.cfg ./wrappers/ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ COPY install-wrappers.sh ./ RUN ./install-wrappers.sh $TOOLCHAIN_PREFIX diff --git a/build-llvm.sh b/build-llvm.sh index e7ec5f2..ed2fca2 100755 --- a/build-llvm.sh +++ b/build-llvm.sh @@ -242,6 +242,17 @@ if [ -n "$COMPILER_LAUNCHER" ]; then CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_CXX_COMPILER_LAUNCHER=$COMPILER_LAUNCHER" fi +if [ -n "$TARGET_WINDOWS" ]; then + # Custom, llvm-mingw specific defaults. We normally set these in + # the frontend wrappers, but this makes sure they are enabled by + # default if that wrapper is bypassed as well. + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_RTLIB=compiler-rt" + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_UNWINDLIB=libunwind" + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_CXX_STDLIB=libc++" + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_LINKER=lld" + CMAKEFLAGS="$CMAKEFLAGS -DLLD_DEFAULT_LD_LLD_IS_MINGW=ON" +fi + if [ -n "$LTO" ]; then CMAKEFLAGS="$CMAKEFLAGS -DLLVM_ENABLE_LTO=$LTO" fi diff --git a/install-wrappers.sh b/install-wrappers.sh index 8a618a2..31ed31e 100755 --- a/install-wrappers.sh +++ b/install-wrappers.sh @@ -123,10 +123,6 @@ fi mkdir -p "$PREFIX/bin" cp wrappers/*-wrapper.sh "$PREFIX/bin" -cp wrappers/mingw32-common.cfg $PREFIX/bin -for arch in $ARCHS; do - cp wrappers/$arch-w64-windows-gnu.cfg $PREFIX/bin -done if [ -n "$HOST" ] && [ -n "$EXEEXT" ]; then # TODO: If building natively on msys, pick up the default HOST value from there. WRAPPER_FLAGS="$WRAPPER_FLAGS -DDEFAULT_TARGET=\"$HOST\"" @@ -142,10 +138,8 @@ if [ -n "$EXEEXT" ]; then # when invoked from outside of MSYS. CTW_SUFFIX=$EXEEXT CTW_LINK_SUFFIX=$EXEEXT - CSDW=clang-scan-deps-wrapper$EXEEXT else CTW_SUFFIX=.sh - CSDW=clang-scan-deps fi cd "$PREFIX/bin" for arch in $ARCHS; do @@ -153,7 +147,7 @@ for arch in $ARCHS; do for exec in clang clang++ gcc g++ c++ as; do ln -sf clang-target-wrapper$CTW_SUFFIX $arch-w64-$target_os-$exec$CTW_LINK_SUFFIX done - ln -sf $CSDW $arch-w64-$target_os-clang-scan-deps$CTW_LINK_SUFFIX + ln -sf clang-scan-deps-wrapper$CTW_SUFFIX $arch-w64-$target_os-clang-scan-deps$CTW_LINK_SUFFIX for exec in addr2line ar ranlib nm objcopy readelf size strings strip llvm-ar llvm-ranlib; do if [ -n "$EXEEXT" ]; then link_target=llvm-wrapper diff --git a/wrappers/aarch64-w64-windows-gnu.cfg b/wrappers/aarch64-w64-windows-gnu.cfg deleted file mode 100644 index 2d68f2c..0000000 --- a/wrappers/aarch64-w64-windows-gnu.cfg +++ /dev/null @@ -1,3 +0,0 @@ --target aarch64-w64-mingw32 -@mingw32-common.cfg -# SEH is the default for aarch64. diff --git a/wrappers/armv7-w64-windows-gnu.cfg b/wrappers/armv7-w64-windows-gnu.cfg deleted file mode 100644 index 91747bf..0000000 --- a/wrappers/armv7-w64-windows-gnu.cfg +++ /dev/null @@ -1,3 +0,0 @@ --target armv7-w64-mingw32 -@mingw32-common.cfg -# SEH is the default for armv7. diff --git a/wrappers/clang-scan-deps-wrapper.c b/wrappers/clang-scan-deps-wrapper.c index f164377..11d467c 100644 --- a/wrappers/clang-scan-deps-wrapper.c +++ b/wrappers/clang-scan-deps-wrapper.c @@ -63,7 +63,7 @@ int _tmain(int argc, TCHAR *argv[]) { if (sep) *sep = '\0'; TCHAR *dash = _tcsrchr(cmd_exe, '-'); - int has_target = 0; + const TCHAR *target = NULL; if (dash) { *dash = '\0'; const TCHAR *cmd_exe_suffix = dash + 1; @@ -76,15 +76,14 @@ int _tmain(int argc, TCHAR *argv[]) { !_tcscmp(cmd_exe_suffix, _T("cc")) || !_tcscmp(cmd_exe_suffix, _T("c99")) || !_tcscmp(cmd_exe_suffix, _T("c11"))) { - has_target = 1; + target = cmd_exe; } } - const TCHAR *target = NULL; #ifdef _WIN32 // On Windows, we want to set our default target even if no target // was found in cmd_exe, as we want to support running with a foreign // clang-scan-deps-real.exe binary, that could have any default. - if (!has_target) + if (!target) target = _T(DEFAULT_TARGET); #endif @@ -93,6 +92,7 @@ int _tmain(int argc, TCHAR *argv[]) { // -target after cmd_exe. exec_argv[arg++] = _T("-target"); exec_argv[arg++] = target; + exec_argv[arg++] = _T("-stdlib=libc++"); } } diff --git a/wrappers/clang-scan-deps-wrapper.sh b/wrappers/clang-scan-deps-wrapper.sh new file mode 100755 index 0000000..5858a23 --- /dev/null +++ b/wrappers/clang-scan-deps-wrapper.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# +# Copyright (c) 2024 Martin Storsjo +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +get_dir() { + target="$1" + while [ -L "$target" ]; do + cd "$(dirname "$target")" + target="$(readlink "$(basename "$target")")" + done + cd "$(dirname "$target")" + pwd +} + +DIR="$(get_dir "$0")" + +# If changing this wrapper, change clang-scan-deps-wrapper.c accordingly. +EXE="$DIR/clang-scan-deps" +FLAGS=() +while [ $# -gt 0 ]; do + if [ -n "$got_flags" ]; then + CMD_EXE="$1" + FLAGS+=("$1") + shift + break + elif [ "$1" = "--" ]; then + got_flags=1 + FLAGS+=("$1") + else + FLAGS+=("$1") + fi + shift +done + +if [ -n "$CMD_EXE" ]; then + # If CMD_EXE is a - style command, pick up the + # target triple from there. + CMD_BASENAME="$(basename "$CMD_EXE")" + CMD_BASENAME="${CMD_BASENAME%.*}" + CMD_TARGET="${CMD_BASENAME%-*}" + CMD_EXE_SUFFIX="${CMD_BASENAME##*-}" + if [ "$CMD_TARGET" != "$CMD_BASENAME" ]; then + case $CMD_EXE_SUFFIX in + clang|clang++|gcc|g++|c++|as|cc|c99|c11) + TARGET="$CMD_TARGET" + ;; + esac + fi +fi + +if [ -n "$TARGET" ]; then + "$EXE" "${FLAGS[@]}" -target $TARGET -stdlib=libc++ "$@" +else + "$EXE" "${FLAGS[@]}" "$@" +fi diff --git a/wrappers/clang-target-wrapper.c b/wrappers/clang-target-wrapper.c index 0eba6ab..2067840 100644 --- a/wrappers/clang-target-wrapper.c +++ b/wrappers/clang-target-wrapper.c @@ -50,7 +50,7 @@ int _tmain(int argc, TCHAR* argv[]) { } } - int max_arg = argc + 18; + int max_arg = argc + 22; const TCHAR **exec_argv = malloc((max_arg + 1) * sizeof(*exec_argv)); int arg = 0; if (getenv("CCACHE")) @@ -66,6 +66,16 @@ int _tmain(int argc, TCHAR* argv[]) { else if (!_tcscmp(exe, _T("c11"))) exec_argv[arg++] = _T("-std=c11"); + if (!_tcscmp(arch, _T("i686"))) { + // Dwarf is the default for i686. + } else if (!_tcscmp(arch, _T("x86_64"))) { + // SEH is the default for x86_64. + } else if (!_tcscmp(arch, _T("armv7"))) { + // SEH is the default for armv7. + } else if (!_tcscmp(arch, _T("aarch64"))) { + // SEH is the default for aarch64. + } + if (target_os && !_tcscmp(target_os, _T("mingw32uwp"))) { // the UWP target is for Windows 10 exec_argv[arg++] = _T("-D_WIN32_WINNT=0x0A00"); @@ -80,6 +90,10 @@ int _tmain(int argc, TCHAR* argv[]) { exec_argv[arg++] = _T("-target"); exec_argv[arg++] = target; + exec_argv[arg++] = _T("-rtlib=compiler-rt"); + exec_argv[arg++] = _T("-unwindlib=libunwind"); + exec_argv[arg++] = _T("-stdlib=libc++"); + exec_argv[arg++] = _T("-fuse-ld=lld"); exec_argv[arg++] = _T("--end-no-unused-arguments"); for (int i = 1; i < argc; i++) diff --git a/wrappers/clang-target-wrapper.sh b/wrappers/clang-target-wrapper.sh index 42e8578..dff8c4e 100755 --- a/wrappers/clang-target-wrapper.sh +++ b/wrappers/clang-target-wrapper.sh @@ -67,6 +67,20 @@ c11) FLAGS="$FLAGS -std=c11" ;; esac +case $ARCH in +i686) + # Dwarf is the default for i686. + ;; +x86_64) + # SEH is the default for x86_64. + ;; +armv7) + # SEH is the default for armv7. + ;; +aarch64) + # SEH is the default for aarch64. + ;; +esac LINKER_FLAGS="" case $TARGET_OS in mingw32uwp) @@ -93,6 +107,10 @@ mingw32uwp) esac FLAGS="$FLAGS -target $TARGET" +FLAGS="$FLAGS -rtlib=compiler-rt" +FLAGS="$FLAGS -unwindlib=libunwind" +FLAGS="$FLAGS -stdlib=libc++" +FLAGS="$FLAGS -fuse-ld=lld" FLAGS="$FLAGS --end-no-unused-arguments" $CCACHE "$CLANG" $FLAGS "$@" $LINKER_FLAGS diff --git a/wrappers/i686-w64-windows-gnu.cfg b/wrappers/i686-w64-windows-gnu.cfg deleted file mode 100644 index efc00bf..0000000 --- a/wrappers/i686-w64-windows-gnu.cfg +++ /dev/null @@ -1,3 +0,0 @@ --target i686-w64-mingw32 -@mingw32-common.cfg -# Dwarf is the default for i686. diff --git a/wrappers/mingw32-common.cfg b/wrappers/mingw32-common.cfg deleted file mode 100644 index f39559c..0000000 --- a/wrappers/mingw32-common.cfg +++ /dev/null @@ -1,4 +0,0 @@ --rtlib=compiler-rt --unwindlib=libunwind --stdlib=libc++ --fuse-ld=lld diff --git a/wrappers/x86_64-w64-windows-gnu.cfg b/wrappers/x86_64-w64-windows-gnu.cfg deleted file mode 100644 index 0ced806..0000000 --- a/wrappers/x86_64-w64-windows-gnu.cfg +++ /dev/null @@ -1,3 +0,0 @@ --target x86_64-w64-mingw32 -@mingw32-common.cfg -# SEH is the default for x86_64.