rust: pick a GCC-compatible Cargo target under MSYS2/MinGW

When Git is built under MSYS2/MinGW with Rust support enabled, the
Makefile expects `cargo build` to drop a `target/release/libgitcore.a`
that is linkable by the same MinGW GCC used for every other object. With
Rust installed via `rustup` (the way it ships on the GitHub-hosted
`windows-2022` and `windows-11-arm` runners that build git/git and its
forks), the default toolchain targets the MSVC ABI; cargo then writes
`target/release/gitcore.lib` instead, which the MinGW `ld.exe` cannot
consume:

    LINK git-shell.exe
    D:\git-sdk-64-minimal\mingw64\bin/ld.exe: cannot find target/release/libgitcore.a: No such file or directory
    collect2.exe: error: ld returned 1 exit status

See https://github.com/microsoft/git/actions/runs/27341625000 for a
full example log.

Let's define the correct target, using the `CARGO_BUILD_TARGET` variable
that will be picked up by Rust, see
https://dirname.github.io/rust-std-doc/cargo/reference/environment-variables.html#:~:text=CARGO%5FBUILD%5FTARGET

Re-use (and fix) the existing `HOST_CPU` variable to determine the
correct value. Avoid relying on environment variables that are simply
not defined in Git for Windows' minimal SDK that Git uses in its CI
runs.

Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
Johannes Schindelin 2026-09-13 15:57:11 +00:00 committed by Junio C Hamano
parent f4742f3165
commit ce6f9ffaa7
2 changed files with 25 additions and 2 deletions

View File

@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib
else
RUST_LIB_NAME = libgitcore.a
endif
RUST_LIB = target/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
RUST_LIB = target$(if $(CARGO_BUILD_TARGET),/$(CARGO_BUILD_TARGET))/$(RUST_BUILD_CONFIG)/$(RUST_LIB_NAME)
endif

GITLIBS = common-main.o $(LIB_FILE)

View File

@ -758,7 +758,30 @@ ifeq ($(uname_S),MINGW)
MINGW_PREFIX := /$(shell echo '$(MSYSTEM)' | tr A-Z a-z)
endif
prefix = $(MINGW_PREFIX)
HOST_CPU = $(patsubst %-w64-mingw32,%,$(MINGW_CHOST))

# A rustup-managed Rust on Windows defaults to the MSVC ABI and
# produces a `gitcore.lib` that the MinGW `ld.exe` cannot link.
# Pick a GCC-compatible Rust target triple matching the MSYS2
# subsystem instead: `*-pc-windows-gnullvm` for the Clang/LLVM
# subsystems (which on Windows is also the only choice for
# ARM64, where no MinGW-GCC port exists) and `*-pc-windows-gnu`
# for the MSVCRT-based MinGW subsystems. For a `staticlib`
# crate-type Cargo does not invoke an external linker, so
# `rustup target add <triple>` is sufficient.
ifneq (,$(filter %ARM64, $(MSYSTEM)))
HOST_CPU = aarch64
else ifneq (,$(filter %32, $(MSYSTEM)))
HOST_CPU = i686
else
HOST_CPU = x86_64
endif
ifneq (,$(filter CLANG%, $(MSYSTEM)))
CARGO_BUILD_TARGET = $(HOST_CPU)-pc-windows-gnullvm
else
CARGO_BUILD_TARGET = $(HOST_CPU)-pc-windows-gnu
endif
export CARGO_BUILD_TARGET

BASIC_LDFLAGS += -Wl,--pic-executable
COMPAT_CFLAGS += -DDETECT_MSYS_TTY \
-DENSURE_MSYSTEM_IS_SET="\"$(MSYSTEM)\"" \