Skip to content

On a Windows host the mingw-target link depends on the runner image's C:\mingw64, not on anything declared #19

Description

@Sunrisepeak

What was measured

mcpp's openkal cross-build (3 hosts x 3 targets) workflow builds openkal-llvm-runtime/examples/same-source for x86_64-windows-gnu on a windows-2022 runner with xim:llvm@22.1.8. On 2026-09-13 (mcpp-community/mcpp#629) the job was green at one commit and red at the next on identical sources and the same runner image:

lld: error: unable to find library -lntdll
lld: error: unable to find library -lsynchronization
lld: error: unable to find library -lshell32
lld: error: unable to find library -lkernel32
lld: error: unable to find library -lbcrypt

The only difference between the two runs was the restored ~/.mcpp sandbox cache lineage. A diagnostic step added to the job then showed where the libraries come from when the link succeeds:

$ clang++ --target=x86_64-w64-windows-gnu -print-search-dirs
libraries: =...\xim-x-llvm\22.1.8\lib\clang\22;C:\mingw64\lib\gcc\x86_64-w64-mingw32\14.2.0;C:\mingw64\x86_64-w64-mingw32\lib;...
$ clang++ --target=x86_64-w64-windows-gnu -print-file-name=libntdll.a
C:\mingw64\x86_64-w64-mingw32\lib\libntdll.a
$ command -v x86_64-w64-mingw32-gcc
/c/mingw64/bin/x86_64-w64-mingw32-gcc

Why

build.mcpp returns before generating import libraries when the host is Windows ("on this system they are present, they are the vendor's"), and puts no link_search on the consumer's line. With xim:llvm's clang and --target=x86_64-w64-windows-gnu, the driver derives its sysroot from whichever x86_64-w64-mingw32-gcc it finds on PATH. On GitHub's image that is C:\mingw64; on a machine without one, or with a different one first on PATH (a sandbox that carries a mingw payload), -lntdll and its neighbours are not found. The link therefore depends on the host's state rather than on anything the package declares, which is the shape this package's own header says it exists to remove.

What would answer it

Generate the five import libraries from port/*.def with llvm-dlltool on a Windows host too whenever the compiler family is clang, exactly as on the other hosts, and put their directory on the consumer's link line. -L is searched first, so a project that does have a vendor set would resolve the forty-five names from these stubs; the header argues that is wrong where the vendor's set is present. The alternative that keeps that argument is to declare the payload that carries the vendor's set (xim:mingw-gcc) for cfg(all(windows, not(env = "msvc"))) and read its x86_64-w64-mingw32/lib through xpkg_dir, so the search directory is named rather than found.

The mcpp workflow now prints the search directories before the build so that the next such reading is diagnosed from the log; it does not work around the dependence.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions