Skip to content

contrib: match optimized Windows builds to the shipped runtime libraries - #63321

Closed
maleadt wants to merge 1 commit into
masterfrom
tb/opt-windows-csl
Closed

maleadt wants to merge 1 commit into
masterfrom
tb/opt-windows-csl

Conversation

@maleadt

@maleadt maleadt commented Sep 23, 2026

Copy link
Copy Markdown
Member

The optimized Windows build (#63214) fails on CI while linking LLVM's own
tools in stage 1:

ld.lld: error: undefined symbol: std::__get_once_callable()
ld.lld: error: undefined symbol: std::__get_once_call()
>>> referenced by libLLVMSupport.a(Timer.cpp.obj)

The stages compile against the MSYS2 sysroot of the CI image
(package-windows-x86_64:v8.5, gcc 16.1.0, winpthreads 14), but link
against and ship BinaryBuilder's compiler support libraries (GCC 15). Those
are also what BinaryBuilder-built packages load. The two sets are not
interchangeable: neither DLL is a superset of the other for libstdc++,
libwinpthread or libgcc_s. Shipping MSYS2's instead would break the
packages' C++ libraries. This PR makes the source-built code bind to
BinaryBuilder's:

  • std::call_once. MSYS2's libstdc++ is configured with TLS, and since
    GCC 16 its headers call std::__get_once_callable()/__get_once_call().
    BinaryBuilder's is configured without TLS and exports __once_functor
    etc. instead. The stages now force-include
    contrib/windows/libstdcxx-call-once.h, which undefines
    _GLIBCXX_HAVE_TLS. That macro only selects between these two
    implementations in <mutex>.
  • 64-bit time functions. winpthreads 14's headers route nanosleep,
    clock_gettime and the timed waits to nanosleep64 etc. BinaryBuilder's
    older winpthreads lacks those, so libLLVM (via
    std::this_thread::sleep_for) failed to load. On x86-64 they are the plain
    functions, so stage 0 builds an import library from
    contrib/windows/winpthread-time64.def that imports them under the old
    names. Every link takes it ahead of the sysroot's import library. It is
    passed by name (-L… -l…) because MSYS2's argument conversion mangles a
    C:/… path inside LLVM's CMake linker flags.
  • Build-time tools. Tools built during a stage, such as llvm-tblgen,
    now load BinaryBuilder's libstdc++. A directory holding only that DLL
    goes first on PATH. The stage's other DLLs stay behind the sysroot's,
    because MSYS2's cc1 (used by windres) finds its GMP/MPFR/winpthread
    through PATH and fails with BinaryBuilder's.

The earlier Windows validation didn't catch this because it swapped the
stage trees' compiler support DLLs for MSYS2's by hand.

Not marked "needs full CI" yet because JuliaCI/julia-buildkite#636 hasn't merged.

Assisted-by: Claude Code (Opus 5.5)

The Windows stages compile against the MSYS2 sysroot, but link against and
ship BinaryBuilder's compiler support libraries, which BinaryBuilder-built
packages also expect at run time. Neither set of runtime DLLs is a superset
of the other, so the source-built code has to bind to BinaryBuilder's.

libstdc++ implements std::call_once differently in each: MSYS2's is
configured with TLS, and since GCC 16 its headers call accessors that
BinaryBuilder's libstdc++ does not export, so linking LLVM's tools fails.
Force-include a header that makes <mutex> use the implementation without
TLS. Tools built during a stage then need BinaryBuilder's libstdc++ at run
time too, so put a directory holding only that DLL first on PATH; the
stage's other DLLs stay behind the sysroot's, which its compiler needs.

MSYS2's winpthreads headers also route nanosleep, clock_gettime and the
timed waits to 64-bit time variants that BinaryBuilder's winpthreads lacks,
e.g. nanosleep64 through std::this_thread::sleep_for in libLLVM, which then
fails to load. On x86-64 these are the plain functions, so stage 0 generates
an import library that imports them under those names, and every link takes
it ahead of the sysroot's.

Assisted-by: Claude Code (Opus 5.5)
@maleadt maleadt added building Build system, or building Julia or its dependencies system:windows Affects only Windows labels Sep 23, 2026
@maleadt

maleadt commented Sep 23, 2026

Copy link
Copy Markdown
Member Author

I'm not really a fan of this, though. It seems questionable that Windows CI relies on the MSYS SDK while some of our artifacts assume the BB toolchain is being linked against.

@maleadt

maleadt commented Sep 23, 2026

Copy link
Copy Markdown
Member Author

Going to try this differently.

@maleadt maleadt closed this Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

building Build system, or building Julia or its dependencies system:windows Affects only Windows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant