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); }