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.
Этот коммит содержится в:
Ayke van Laethem 2021-12-28 15:39:23 +01:00 коммит произвёл Ron Evans
родитель 7ca45d61fc
коммит 34ba0c1be1
3 изменённых файлов: 17 добавлений и 5 удалений

2
.github/workflows/windows.yml предоставленный
Просмотреть файл

@ -66,7 +66,7 @@ jobs:
uses: actions/cache/restore@v3 uses: actions/cache/restore@v3
id: cache-llvm-build id: cache-llvm-build
with: with:
key: llvm-build-15-windows-v5 key: llvm-build-15-windows-v6
path: llvm-build path: llvm-build
- name: Build LLVM - name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true' if: steps.cache-llvm-build.outputs.cache-hit != 'true'

Просмотреть файл

@ -120,10 +120,8 @@ ifeq ($(OS),Windows_NT)
START_GROUP = -Wl,--start-group START_GROUP = -Wl,--start-group
END_GROUP = -Wl,--end-group END_GROUP = -Wl,--end-group
# LLVM compiled using MinGW on Windows appears to have problems with threads. # PIC needs to be disabled for libclang to work.
# Without this flag, linking results in errors like these: LLVM_OPTION += -DLLVM_ENABLE_PIC=OFF
# 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
CGO_CPPFLAGS += -DCINDEX_NO_EXPORTS CGO_CPPFLAGS += -DCINDEX_NO_EXPORTS
CGO_LDFLAGS += -static -static-libgcc -static-libstdc++ CGO_LDFLAGS += -static -static-libgcc -static-libstdc++

Просмотреть файл

@ -3,25 +3,39 @@
// This file provides C wrappers for liblld. // This file provides C wrappers for liblld.
#include <lld/Common/Driver.h> #include <lld/Common/Driver.h>
#include <llvm/Support/Parallel.h>
extern "C" { 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) { bool tinygo_link_elf(int argc, char **argv) {
configure();
std::vector<const char*> args(argv, argv + argc); std::vector<const char*> args(argv, argv + argc);
return lld::elf::link(args, llvm::outs(), llvm::errs(), false, false); return lld::elf::link(args, llvm::outs(), llvm::errs(), false, false);
} }
bool tinygo_link_macho(int argc, char **argv) { bool tinygo_link_macho(int argc, char **argv) {
configure();
std::vector<const char*> args(argv, argv + argc); std::vector<const char*> args(argv, argv + argc);
return lld::macho::link(args, llvm::outs(), llvm::errs(), false, false); return lld::macho::link(args, llvm::outs(), llvm::errs(), false, false);
} }
bool tinygo_link_mingw(int argc, char **argv) { bool tinygo_link_mingw(int argc, char **argv) {
configure();
std::vector<const char*> args(argv, argv + argc); std::vector<const char*> args(argv, argv + argc);
return lld::mingw::link(args, llvm::outs(), llvm::errs(), false, false); return lld::mingw::link(args, llvm::outs(), llvm::errs(), false, false);
} }
bool tinygo_link_wasm(int argc, char **argv) { bool tinygo_link_wasm(int argc, char **argv) {
configure();
std::vector<const char*> args(argv, argv + argc); std::vector<const char*> args(argv, argv + argc);
return lld::wasm::link(args, llvm::outs(), llvm::errs(), false, false); return lld::wasm::link(args, llvm::outs(), llvm::errs(), false, false);
} }