1#!/bin/sh
2# cargo for Windows from macOS or Linux: `cargo.sh ARCH COMMAND ARGS...`.
3# x86_64 Windows 7 SP1 to 11: nightly's tier-3 x86_64-win7-windows-gnu, std built here
4# aarch64 Windows 11 on Arm: aarch64-pc-windows-gnullvm
5# Both link with llvm-mingw (`toolchain.sh`) against msvcrt.dll, which every Windows has.
6set -eu
7here=$(cd "$(dirname "$0")" && pwd)
8root=$(cd "$here/../.." && pwd)
9LLVM_MINGW=${LLVM_MINGW:-$root/target/windows/llvm-mingw}
10export LLVM_MINGW
11[ -x "$LLVM_MINGW/bin/clang" ] || {
12 echo "No llvm-mingw at $LLVM_MINGW; run $here/toolchain.sh" >&2
13 exit 1
14}
15arch=$1 command=$2
16shift 2
17case $arch in
18x86_64)
19 target=x86_64-win7-windows-gnu
20 toolchain=+nightly
21 # rustc would infer a bare ld from the name `link.sh`; it is a C compiler driver.
22 # raw-dylib imports (the windows crates) are made by llvm-mingw's dlltool. Cargo
23 # can't see link.sh's inputs; folding their hash into the flags relinks on change.
24 runtime=$(cat "$here/link.sh" "$here"/rt/* | shasum | cut -c1-12)
25 set -- -Zbuild-std=std,panic_abort,panic_unwind \
26 --config "target.$target.linker='$here/link.sh'" \
27 --config "target.$target.rustflags=['-C','linker-flavor=gcc','-C','metadata=rt-$runtime','-C','dlltool=$LLVM_MINGW/bin/x86_64-w64-mingw32-dlltool']" "$@"
28 ;;
29aarch64)
30 target=aarch64-pc-windows-gnullvm
31 toolchain=+stable
32 rustup target add --toolchain stable "$target" >/dev/null
33 # crt-static links libunwind in rather than beside the executable. clang ignores
34 # rustc's -no-pie.
35 set -- --config "target.$target.linker='$LLVM_MINGW/bin/aarch64-w64-mingw32-clang'" \
36 --config "target.$target.rustflags=['-C','target-feature=+crt-static','-C','link-arg=-Wno-unused-command-line-argument']" "$@"
37 ;;
38*)
39 echo "usage: $0 x86_64|aarch64 COMMAND ARGS..." >&2
40 exit 2
41 ;;
42esac
43variable=$(echo "$target" | tr - _)
44# cc-rs (bundled SQLite, ring) compiles with the same clang and archives with its llvm-ar.
45env "CC_$variable=$LLVM_MINGW/bin/$arch-w64-mingw32-clang" \
46 "AR_$variable=$LLVM_MINGW/bin/llvm-ar" \
47 CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$root/target/windows}" \
48 cargo "$toolchain" "$command" --target "$target" "$@"