]> git.ipfire.org Git - thirdparty/git.git/commitdiff
rust: fix linking binaries with cargo
authorbrian m. carlson <bk2204@github.com>
Sat, 7 Feb 2026 20:04:41 +0000 (20:04 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sun, 8 Feb 2026 01:41:02 +0000 (17:41 -0800)
When Cargo links binaries with MSVC, it uses the link.exe linker from
PATH to do so.  However, when running under a shell from MSYS, such as
when building with the Git for Windows SDK, which we do in CI, the
/ming64/bin and /usr/bin entries are first in PATH.  That means that the
Unix link binary shows up first, which obviously does not work for
linking binaries in any useful way.

To solve this problem, adjust PATH to place those binaries at the end of
the list instead of the beginning.  This allows access to the normal
Unix tools, but link.exe will be the compiler's linker.  Make sure to
export PATH explicitly: while this should be the default, it's more
robust to not rely on the shell operating in a certain way.

The reason this has not shown up before is that we typically link our
binaries from the C compiler.  However, now that we're about to
introduce a Rust build script (build.rs file), Rust will end up linking
that script to further drive Cargo, in which case we'll invoke the
linker from it.  There are other solutions, such as using LLD, but this
one is simple and reliable and is most likely to work with existing
systems.

Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: brian m. carlson <bk2204@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
src/cargo-meson.sh

index 38728a371137f9d2a98e2e98749cd693e0a005ed..75f3cd126540378e5d33f51432f75d9732f7913d 100755 (executable)
@@ -19,20 +19,25 @@ do
        esac
 done
 
-cargo build --lib --quiet --manifest-path="$SOURCE_DIR/Cargo.toml" --target-dir="$BUILD_DIR" "$@"
-RET=$?
-if test $RET -ne 0
-then
-       exit $RET
-fi
-
 case "$(cargo -vV | sed -n 's/^host: \(.*\)$/\1/p')" in
+       *-windows-msvc)
+               LIBNAME=gitcore.lib
+               PATH="$(echo "$PATH" | tr ':' '\n' | grep -Ev "^(/mingw64/bin|/usr/bin)$" | paste -sd: -):/mingw64/bin:/usr/bin"
+               export PATH
+               ;;
        *-windows-*)
                LIBNAME=gitcore.lib;;
        *)
                LIBNAME=libgitcore.a;;
 esac
 
+cargo build --lib --quiet --manifest-path="$SOURCE_DIR/Cargo.toml" --target-dir="$BUILD_DIR" "$@"
+RET=$?
+if test $RET -ne 0
+then
+       exit $RET
+fi
+
 if ! cmp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1
 then
        cp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a"