Use Rust in the Windows CI jobs - #2213
Conversation
|
There are issues in commit 319a0f0:
|
319a0f0 to
7a24630
Compare
|
/submit |
|
Submitted as pull.2213.git.1788272509.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
| @@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib | |||
| else | |||
There was a problem hiding this comment.
Junio C Hamano wrote on the Git mailing list (how to reply to this email):
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:
> + 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_TARGET = $(HOST_CPU)-pc-windows-gnullvm
> + else
> + CARGO_TARGET = $(HOST_CPU)-pc-windows-gnu
> + endif
Assuming HOST_CPU is x86_64 in the above, as UCRT64, unlike
CLANG{ARM64,64,32}, does not match CLANG%, I presume that the above
gives "x86_64-pc-windows-gnu" to builds with MSYSTEM set to UCRT64.
There is this "we only need MINGW64 but the switch to UCRT64 is
imminent, and others are for documentation" part we see in the
[PATCH 2/2]
+ case "$MSYSTEM" in
+ CLANGARM64) target=aarch64-pc-windows-gnullvm ;;
+ CLANG64) target=x86_64-pc-windows-gnullvm ;;
+ CLANG32) target=i686-pc-windows-gnullvm ;;
+ UCRT64) target=x86_64-pc-windows-gnullvm ;;
+ MINGW64) target=x86_64-pc-windows-gnu ;;
+ MINGW32) target=i686-pc-windows-gnu ;;
+ *) echo "::error::Unsupported MSYSTEM: $MSYSTEM"; exit 1 ;;
+ esac &&
+ rustup target add "$target" &&
that maps UCRT64 to "x86_64-pc-windows-gnullvm"
I do not know if it is intended. If so, please ignore.
Thanks.There was a problem hiding this comment.
Johannes Schindelin wrote on the Git mailing list (how to reply to this email):
Hi Junio,
On Tue, 1 Sep 2026, Junio C Hamano wrote:
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > + 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_TARGET = $(HOST_CPU)-pc-windows-gnullvm
> > + else
> > + CARGO_TARGET = $(HOST_CPU)-pc-windows-gnu
> > + endif
>
> Assuming HOST_CPU is x86_64 in the above, as UCRT64, unlike
> CLANG{ARM64,64,32}, does not match CLANG%, I presume that the above
> gives "x86_64-pc-windows-gnu" to builds with MSYSTEM set to UCRT64.
Correct.
> There is this "we only need MINGW64 but the switch to UCRT64 is
> imminent, and others are for documentation" part we see in the
> [PATCH 2/2]
>
> + case "$MSYSTEM" in
> + CLANGARM64) target=aarch64-pc-windows-gnullvm ;;
> + CLANG64) target=x86_64-pc-windows-gnullvm ;;
> + CLANG32) target=i686-pc-windows-gnullvm ;;
> + UCRT64) target=x86_64-pc-windows-gnullvm ;;
> + MINGW64) target=x86_64-pc-windows-gnu ;;
> + MINGW32) target=i686-pc-windows-gnu ;;
> + *) echo "::error::Unsupported MSYSTEM: $MSYSTEM"; exit 1 ;;
> + esac &&
> + rustup target add "$target" &&
>
> that maps UCRT64 to "x86_64-pc-windows-gnullvm"
>
> I do not know if it is intended. If so, please ignore.
Since UCRT64 is still using GCC, it should be `-gnu`. Thanks for catching.
Ciao,
Johannes7c79584 to
f4742f3
Compare
7a24630 to
f2718f1
Compare
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
microsoft/git), 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 the
full log.
Let's define the correct target. Re-use (and fix) the existing
`HOST_CPU` variable for that purpose. 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>
The Windows runners used by Git's GitHub workflow's `windows-build` job ship `rustup` plus a `*-pc-windows-msvc` default toolchain (see https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md and https://github.com/actions/partner-runner-images/blob/main/images/arm-windows-11-image.md), but no precompiled `std` for `*-pc-windows-gnu` or `*-pc-windows-gnullvm`. With the Makefile now picking a GCC-compatible target triple based on `$(MSYSTEM)`, the build step needs that precompiled `std` to be installed before invoking `make`, otherwise `cargo build --target <triple>` fails to find a usable `std` for the chosen target. Add a step between the SDK setup and the `make` invocation that selects the matching triple from `$MSYSTEM` (which `git-for-windows/setup-git-for-windows-sdk` exports for every subsequent step) and runs `rustup target add` for it. The mapping mirrors what `config.mak.uname` derives from `$(MSYSTEM)` and `$(HOST_CPU)`, just enumerated explicitly here since CI has direct knowledge of which MSYS2 subsystems the matrix actually exercises (`CLANGARM64` for the ARM64 runner, `MINGW64` for the x86_64 runner). Technically, we only need to handle MINGW64 at present, but the switch to UCRT64 is imminent, and the other case arms serve as a very fine documentation of what people should do for other MSYSTEM values. For a `staticlib` crate-type `cargo build` does not invoke an external linker, so no further toolchain components (e.g. the `gnullvm` LLVM linker) need to be installed; `rustup target add` alone is sufficient. Assisted-by: Claude Opus 4.7 Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
f2718f1 to
0741539
Compare
|
/submit |
|
Submitted as pull.2213.v2.git.1789153730.gitgitgadget@gmail.com To fetch this version into To fetch this version to local tag |
| @@ -959,7 +959,7 @@ RUST_LIB_NAME = gitcore.lib | |||
| else | |||
There was a problem hiding this comment.
Junio C Hamano wrote on the Git mailing list (how to reply to this email):
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:
> @@ -993,6 +993,7 @@ endif
> ifndef DEBUG
> CARGO_ARGS += --release
> endif
> +CARGO_ARGS += $(if $(CARGO_TARGET),--target $(CARGO_TARGET))
Should this use CARGO_BUILD_TARGET (instead of CARGO_TARGET) to
match what the officially supported Cargo environment variable is
called? It would also help us work better with the changes from the
jc/rust-cargo-build-target topic.
Thanks.
Author: James Le Cuirot <chewi@gentoo.org>
Date: Thu Sep 10 11:20:14 2026 +0100
rust: respect CARGO_BUILD_TARGET when locating build output
When cross-compiling, Cargo always writes to a target-tuple subdirectory
determined by CARGO_BUILD_TARGET, even when it matches the native tuple.
The build looked in $BUILD_DIR/$BUILD_TYPE directly, so it failed to
locate the freshly built library.
Respect CARGO_BUILD_TARGET in the output path so the correct artifact
is located.
Signed-off-by: James Le Cuirot <chewi@gentoo.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/Makefile b/Makefile
index d4b775953d..f0ca2e4f72 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/src/cargo-meson.sh b/src/cargo-meson.sh
index 75f3cd1265..83c7e7b79b 100755
--- a/src/cargo-meson.sh
+++ b/src/cargo-meson.sh
@@ -38,7 +38,7 @@ then
exit $RET
fi
-if ! cmp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1
+if ! cmp "$BUILD_DIR/${CARGO_BUILD_TARGET:+$CARGO_BUILD_TARGET/}$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1
then
- cp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a"
+ cp "$BUILD_DIR/${CARGO_BUILD_TARGET:+$CARGO_BUILD_TARGET/}$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a"
fiThere was a problem hiding this comment.
James Le Cuirot wrote on the Git mailing list (how to reply to this email):
On Fri, 2026-09-11 at 14:09 -0700, Junio C Hamano wrote:
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > @@ -993,6 +993,7 @@ endif
> > ifndef DEBUG
> > CARGO_ARGS += --release
> > endif
> > +CARGO_ARGS += $(if $(CARGO_TARGET),--target $(CARGO_TARGET))
>
> Should this use CARGO_BUILD_TARGET (instead of CARGO_TARGET) to
> match what the officially supported Cargo environment variable is
> called? It would also help us work better with the changes from the
> jc/rust-cargo-build-target topic.
>
> Thanks.
Yes, without explicitly setting --target at all. This is how Gentoo Linux
supports cross-compiling of its Rust packages. Just avoid setting
CARGO_BUILD_TARGET (or passing --target) when you're not cross-compiling. It
will cause Cargo to behave differently, even if you give the native tuple. For
example, RUSTFLAGS is normally applied to both the build host binaries and the
target host binaries, but when an explicit target is set, RUSTFLAGS is only
applied to the target host binaries.
Regards,
Chewi
> Author: James Le Cuirot <chewi@gentoo.org>
> Date: Thu Sep 10 11:20:14 2026 +0100
>
> rust: respect CARGO_BUILD_TARGET when locating build output
>
> When cross-compiling, Cargo always writes to a target-tuple subdirectory
> determined by CARGO_BUILD_TARGET, even when it matches the native tuple.
> The build looked in $BUILD_DIR/$BUILD_TYPE directly, so it failed to
> locate the freshly built library.
>
> Respect CARGO_BUILD_TARGET in the output path so the correct artifact
> is located.
>
> Signed-off-by: James Le Cuirot <chewi@gentoo.org>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
>
> diff --git a/Makefile b/Makefile
> index d4b775953d..f0ca2e4f72 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -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)
> diff --git a/src/cargo-meson.sh b/src/cargo-meson.sh
> index 75f3cd1265..83c7e7b79b 100755
> --- a/src/cargo-meson.sh
> +++ b/src/cargo-meson.sh
> @@ -38,7 +38,7 @@ then
> exit $RET
> fi
>
> -if ! cmp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1
> +if ! cmp "$BUILD_DIR/${CARGO_BUILD_TARGET:+$CARGO_BUILD_TARGET/}$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1
> then
> - cp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a"
> + cp "$BUILD_DIR/${CARGO_BUILD_TARGET:+$CARGO_BUILD_TARGET/}$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a"
> fi|
User |
With v2.55.0, Git requires Rust by default, with an opt-out that is intended to be dropped in one of the next versions.
Due to the special circumstances in the Windows part of the CI builds, each Windows build job first downloads a "minimal Git for Windows SDK" that contains the GCC toolchain required to build and test Git. As a consequence, brian m. carlson opted out of Rust in Git's CI definition in 32d5b90 (Enable Rust by default, 2026-04-09).
So: How could we stop opting out? Notably, Rust is not part of that minimal Git for Windows SDK, and including it would more than double that payload, which I consider prohibitive. Yet including Rust in the minimal Git for Windows SDK is not actually necessary, at least not for the GitHub workflow: The runners on which this workflow is defined to run come with Rust pre-installed.
Granted, this Rust installation is configured to target the Windows-native C compiler, Visual C. To accommodate for the Windows CI job building with GCC, this patch series adds a step to the workflow that ensures that the needed Rust bits are installed and configured.
RFH: I haven't been able to confirm that GitLab's Windows runners come with Rust preinstalled, https://docs.gitlab.com/ci/runners/hosted_runners/windows/#available-runtimes did not clarify that for me. Patrick (or anyone else with access to GitLab CI), could you see whether this patch series builds on
saas-windows-medium-amd64without need for further changes?Changes since v1:
UCRT64was once marked as using clang and once as using gcc was fixed by clarifying that UCRT64 uses GCC.Cc: Patrick Steinhardt ps@pks.im
cc: James Le Cuirot chewi@gentoo.org