igneum/infra/cross/build-linux.sh

55 lines
3.5 KiB
Bash
Executable file

#!/usr/bin/env bash
# Cross-compile igneumd and igneum-miner for x86_64 Linux (Debian 12, glibc 2.36) on the Mac, so a server never
# builds. Uses cargo-zigbuild (zig as the C/C++ cross toolchain and linker); rocksdb (librocksdb-sys, C++), blst,
# secp256k1 and the execution layer's crates all link through it.
#
# infra/cross/build-linux.sh build from NODE_SRC (default vendor/igneum-node-v4) into TARGET_DIR
# NODE_SRC=... TARGET_DIR=... JOBS=4 infra/cross/build-linux.sh
#
# Output: $TARGET_DIR/x86_64-unknown-linux-gnu/release/{igneumd,igneum-miner} and $OUT_DIR/{igneumd,igneum-miner,version.txt}
# (OUT_DIR default infra/cross/out). First build: about 500 crates; later builds are incremental.
#
# One-off setup (4 Oct 2026, done on this Mac): brew install zig (0.17.0); cargo install cargo-zigbuild (0.23.4);
# rustup target add x86_64-unknown-linux-gnu. Docker is not installed here, so `cross` is not an option.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
NODE_SRC="${NODE_SRC:-$REPO/vendor/igneum-node-v4}"
TARGET_DIR="${TARGET_DIR:-$REPO/vendor/igneum-node/target-linux}"
OUT_DIR="${OUT_DIR:-$HERE/out}"
# Every path absolute before the cd into NODE_SRC (5 October 2026, the 0.3.10 cut: a relative TARGET_DIR was resolved by
# cargo inside the node worktree, the copy below read the repository-relative one, and the seed's "new" binary was the
# previous build's bytes, twice).
abs() { case "$1" in /*) printf '%s' "$1" ;; *) printf '%s/%s' "$PWD" "$1" ;; esac; }
NODE_SRC="$(abs "$NODE_SRC")"; TARGET_DIR="$(abs "$TARGET_DIR")"; OUT_DIR="$(abs "$OUT_DIR")"
TARGET="${TARGET:-x86_64-unknown-linux-gnu}"
GLIBC="${GLIBC:-2.36}"
JOBS="${JOBS:-4}"
CARGO="${CARGO:-$HOME/.cargo/bin/cargo}"
log() { printf '%s %s\n' "$(date -u +%H:%M:%S)" "$*"; }
die() { log "ERROR: $*" >&2; exit 1; }
command -v zig >/dev/null 2>&1 || die "zig is not installed (brew install zig)"
[ -x "$HOME/.cargo/bin/cargo-zigbuild" ] || command -v cargo-zigbuild >/dev/null 2>&1 || die "cargo-zigbuild is not installed (cargo install cargo-zigbuild)"
"$HOME/.cargo/bin/rustup" target list --installed | grep -q "^$TARGET\$" || { log "adding rust target $TARGET"; "$HOME/.cargo/bin/rustup" target add "$TARGET"; }
[ -f "$NODE_SRC/Cargo.toml" ] || die "no node source at $NODE_SRC"
log "cross-compiling igneumd and igneum-miner for $TARGET.$GLIBC from $NODE_SRC ($(git -C "$NODE_SRC" rev-parse --short HEAD), $(git -C "$NODE_SRC" rev-parse --abbrev-ref HEAD)); target dir $TARGET_DIR; zig $(zig version); $JOBS jobs at nice 19"
start=$(date +%s)
( cd "$NODE_SRC" && CARGO_TARGET_DIR="$TARGET_DIR" nice -n 19 "$CARGO" zigbuild --release -j "$JOBS" \
--target "$TARGET.$GLIBC" -p kaspad -p igneum-miner --features kaspad/igneum-pow )
secs=$(( $(date +%s) - start ))
log "cross-compile finished in $secs s ($(( secs / 60 )) min)"
mkdir -p "$OUT_DIR"
cp "$TARGET_DIR/$TARGET/release/igneumd" "$TARGET_DIR/$TARGET/release/igneum-miner" "$OUT_DIR/"
chmod +x "$OUT_DIR/igneumd" "$OUT_DIR/igneum-miner"
ver=$(grep -m1 '^version' "$NODE_SRC/Cargo.toml" | sed 's/.*"\(.*\)".*/\1/')
{
printf 'igneumd %s\n' "$ver"
printf 'cross-compiled on %s from %s (%s) with cargo-zigbuild, target %s.%s, %s s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$(git -C "$NODE_SRC" rev-parse --short HEAD)" "$(git -C "$NODE_SRC" rev-parse --abbrev-ref HEAD)" "$TARGET" "$GLIBC" "$secs"
git -C "$NODE_SRC" rev-parse --short HEAD
} > "$OUT_DIR/version.txt"
file "$OUT_DIR/igneumd" "$OUT_DIR/igneum-miner" | sed 's/^/ /'
ls -la "$OUT_DIR" | sed 's/^/ /'
log "binaries in $OUT_DIR"