Cross-compile into ./bin for the usual platforms

build.sh produced one binary for the machine it ran on. It now builds
darwin/arm64, darwin/amd64, linux/amd64 and linux/arm64 into ./bin, all
from the single version that run bumped, so the four never disagree about
what they are. PLATFORMS="linux/amd64" ./build.sh narrows it.

bin/mgsh is a symlink to the host's build, so there is still one stable
path to "the binary for this machine". The old ./mgsh in the repo root is
no longer written, and the script deletes it once if it finds it -- a
stale binary on a path people have in their fingers is worse than a
missing one.

CGO_ENABLED=0 throughout: the cross builds then need no toolchain per
target and the binaries are static. That is only safe because os/user
still resolves the current user without cgo, which mgsh needs for the
"[user@host]" stamp on every commit -- checked on darwin before relying
on it.

Windows is left out on purpose: mgsh shells out to stty and /bin/sh, so
it would compile there and then not work.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 19:53:29 +02:00
co-authored by Claude Opus 5
parent cd5ab1a2bd
commit f3d8cbe281
4 changed files with 71 additions and 11 deletions
+41 -4
View File
@@ -1,12 +1,22 @@
#!/bin/sh
# Build mgsh, auto-incrementing the patch version by 0.0.1 on every build.
# Build mgsh for the usual platforms into ./bin, auto-incrementing the patch
# version by 0.0.1 on every build.
#
# version.txt holds the currently built version. Each run increments the patch
# component, then builds with that version injected via -ldflags, and writes it
# back. So version.txt always reflects the version of the binary just built.
# component, then builds every platform with that one version injected via
# -ldflags, and writes it back. So version.txt always reflects the version of
# the binaries just built, and all of them carry the same one.
#
# Override the platform list to build just one:
# PLATFORMS="linux/amd64" ./build.sh
#
# Windows is deliberately absent: mgsh shells out to stty and /bin/sh, so it
# would compile there and then not work.
set -e
cd "$(dirname "$0")"
PLATFORMS=${PLATFORMS:-"darwin/arm64 darwin/amd64 linux/amd64 linux/arm64"}
V=$(cat version.txt 2>/dev/null || echo 4.0.0)
# split MAJOR.MINOR.PATCH and increment PATCH (no carry: 4.0.9 -> 4.0.10)
@@ -17,7 +27,34 @@ PATCH=${REST#*.}
PATCH=$((PATCH + 1))
NV="$MAJOR.$MINOR.$PATCH"
go build -ldflags "-X main.VERSION=$NV" -o mgsh .
# earlier versions built ./mgsh in the repo root; drop it so nothing keeps
# running a stale binary from a path that is no longer written
if [ -f mgsh ]; then
rm -f mgsh
echo "removed stale ./mgsh (the build now writes ./bin)"
fi
mkdir -p bin
HOST="$(go env GOOS)/$(go env GOARCH)"
for p in $PLATFORMS; do
os=${p%/*}
arch=${p#*/}
out="bin/mgsh-$os-$arch"
# CGO_ENABLED=0 throughout: it makes the cross builds work without a
# toolchain per target and the binaries static, and os/user still resolves
# the current user without cgo on both darwin and linux.
CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" \
go build -ldflags "-X main.VERSION=$NV" -o "$out" .
if [ "$p" = "$HOST" ]; then
ln -sf "mgsh-$os-$arch" bin/mgsh # the one for this machine
echo " $out -> bin/mgsh"
else
echo " $out"
fi
done
echo "$NV" > version.txt
echo "built mgsh v$NV"