Repository navigation
windows: perry.exe cannot link against the official LLVM 22 release — /MT vs /MD, bundled rpmalloc, and missing inkwell target backends #7985
Description
Summary
Linking perry.exe on windows-latest against the pinned C:\llvm (the official
clang+llvm-22.1.3-x86_64-pc-windows-msvc tarball installed by
.github/actions/setup-llvm22) fails with three independent link.exe
errors. This is the windows-latest arm of gc-native-roots (#7970), and it is
a real build breakage, not a harness problem.
It is very likely also latent in test.yml's windows-build. That job builds
the same -p perry with the same action, but it has been dying at its first
step since #7977 (cp1252 decode), so its build step has not executed on any recent
PR. Expect this to surface there the moment #7977 lands — please read the two
together.
Evidence
Run 31405431962, job native-roots-rs4gc (windows-latest, x86-64, PE),
LLVM_SYS_221_PREFIX: C:\llvm, step "Build compiler and static runtime":
error: linking with `link.exe` failed: exit code: 1120
1. CRT model mismatch (mimalloc /MD vs llvm-sys /MT)
liblibmimalloc_sys-*.rlib(mimalloc-static.o) : error LNK2038: mismatch detected for
'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'
in libllvm_sys-*.rlib(Core.cpp.obj)
LINK : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of other libs
The official LLVM Windows release is built /MT (static CRT); Rust's msvc target
and libmimalloc-sys use /MD. They cannot be linked into one image as-is.
2. Allocator symbol collision (LLVM release bundles rpmalloc)
ucrt.lib(api-ms-win-crt-heap-l1-1-0.dll) : error LNK2005: calloc already defined in libllvm_sys-*.rlib(rpmalloc.c.obj)
... free already defined in ... rpmalloc.c.obj
... malloc already defined in ... rpmalloc.c.obj
... realloc already defined in ... rpmalloc.c.obj
build_llvm_release.bat links rpmalloc into the Windows release to speed up
LLD. Those definitions come along through llvm-sys and collide with the UCRT —
and, separately, Perry already has its own allocator (mimalloc), so there would be
two.
3. Missing target backends inkwell references
libinkwell-*.rlib : error LNK2019: unresolved external symbol LLVMInitializeMipsTarget
... LLVMInitializeLanaiTarget
... LLVMInitializeSparcTarget
... LLVMInitializeMSP430Target
... LLVMInitializeXCoreTarget (and the
matching TargetInfo / AsmPrinter / AsmParser / Disassembler / TargetMC symbols)
inkwell's Target::initialize_* surface expects experimental targets the official
Windows release does not build.
Why it was invisible
gc-native-roots has never had a green run (#7970), and is not in branch
protection's required contexts, so a red result there is indistinguishable from
the queue noise. The only other Windows job, windows-build, has been failing
27 s in at an unrelated step (#7977). Between them, nothing has successfully
linked perry.exe on Windows in CI for some time.
The xml2s.lib comment block in .github/actions/setup-llvm22/action.yml says
this became fatal when #7353 made the in-process LLVM backend the default and
statically linked, and explicitly notes that "test.yml's windows-build and
gc-native-roots.yml's PE arm fail identically". That comment is about a
previous instance of the same class; these three errors are past it.
Directions (not a recommendation — this needs a Windows-toolchain decision)
- Build the perry Windows job against an LLVM built
/MDwithout rpmalloc
(e.g. a self-built or vcpkg LLVM), rather than the official release tarball. - Or
/NODEFAULTLIB+/FORCE:MULTIPLEsurgery, which trades a link error for
an allocator whose behaviour nobody has characterised — probably worse. - Or build
perryon Windows without the defaultllvm-inprocessfeature, so
llvm-sys/inkwell are not linked at all, and keep the in-process backend to
the platforms it is actually exercised on. This is the smallest change and the
one most consistent with the feature's current CI coverage (macOS only, and see
PERRY_LLVM_INPROCESS=native cannot build RS4GCptr addrspace(1)roots; the unit corpora froze 151 codegen commits ago #7982).
Separately fixed
The same job then failed a second time (exit 2) at the Windows LLVM download:
tar (child): Cannot connect to D: resolve failed
xz: (stdin): File format not recognized
Git-bash GNU tar reads $RUNNER_TEMP (D:\a\_temp) as a remote host:path.
That one is a workflow bug and is fixed in the #7970 PR with tar --force-local
plus a post-extraction check. It is noted here only so the log is not confusing.
Activity
ci: repair three broken gates — Windows cp1252, llvm-inprocess vacuou…