From 34ba0c1be1e5adc4b5095fa9d1e15a7a26e2f519 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 28 Dec 2021 15:39:23 +0100 Subject: [PATCH] ci: build LLVM with thread support on Windows This should fix a number of concurrency/threading issues. I had to force-disable concurrency in the linker using a hack. I'm not entirely sure what the cause is, possibly the MinGW version (version 12 appears to work for me, while version 11 as used on the GitHub runner image seems to be broken). There are a few ways to fix this in a better way: * Fix the underlying cause (possibly by upgrading to MinGW-w64 12). * Add the `--threads` flag to the LLD MinGW linker, so we can use a regular parameter instead of this hack. --- .github/workflows/windows.yml | 2 +- Makefile | 6 ++---- builder/lld.cpp | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 95825358..b2a3be13 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -66,7 +66,7 @@ jobs: uses: actions/cache/restore@v3 id: cache-llvm-build with: - key: llvm-build-15-windows-v5 + key: llvm-build-15-windows-v6 path: llvm-build - name: Build LLVM if: steps.cache-llvm-build.outputs.cache-hit != 'true' diff --git a/Makefile b/Makefile index a0acb881..4a201052 100644 --- a/Makefile +++ b/Makefile @@ -120,10 +120,8 @@ ifeq ($(OS),Windows_NT) START_GROUP = -Wl,--start-group END_GROUP = -Wl,--end-group - # LLVM compiled using MinGW on Windows appears to have problems with threads. - # Without this flag, linking results in errors like these: - # libLLVMSupport.a(Threading.cpp.obj):Threading.cpp:(.text+0x55): undefined reference to `std::thread::hardware_concurrency()' - LLVM_OPTION += -DLLVM_ENABLE_THREADS=OFF -DLLVM_ENABLE_PIC=OFF + # PIC needs to be disabled for libclang to work. + LLVM_OPTION += -DLLVM_ENABLE_PIC=OFF CGO_CPPFLAGS += -DCINDEX_NO_EXPORTS CGO_LDFLAGS += -static -static-libgcc -static-libstdc++ diff --git a/builder/lld.cpp b/builder/lld.cpp index c7688f0c..6cecbebe 100644 --- a/builder/lld.cpp +++ b/builder/lld.cpp @@ -3,25 +3,39 @@ // This file provides C wrappers for liblld. #include +#include extern "C" { +static void configure() { +#if _WIN64 + // This is a hack to work around a hang in the LLD linker on Windows, with + // -DLLVM_ENABLE_THREADS=ON. It has a similar effect as the -threads=1 + // linker flag, but with support for the COFF linker. + llvm::parallel::strategy = llvm::hardware_concurrency(1); +#endif +} + bool tinygo_link_elf(int argc, char **argv) { + configure(); std::vector args(argv, argv + argc); return lld::elf::link(args, llvm::outs(), llvm::errs(), false, false); } bool tinygo_link_macho(int argc, char **argv) { + configure(); std::vector args(argv, argv + argc); return lld::macho::link(args, llvm::outs(), llvm::errs(), false, false); } bool tinygo_link_mingw(int argc, char **argv) { + configure(); std::vector args(argv, argv + argc); return lld::mingw::link(args, llvm::outs(), llvm::errs(), false, false); } bool tinygo_link_wasm(int argc, char **argv) { + configure(); std::vector args(argv, argv + argc); return lld::wasm::link(args, llvm::outs(), llvm::errs(), false, false); }