igneum/packaging/windows/make-payload.sh
igneum-josh b65cc64502 Igneum Miner 0.3.7: the Windows runtime DLLs come from the toolchain that linked the exes, and a gate refuses a payload whose exe imports a symbol the shipped DLL lacks
0.3.6 on both PCs: igneumd.exe (built on PC 1 with GCC 13's mingw) shipped with the Mac toolchain's GCC 16
libstdc++-6.dll, which no longer exports seven symbols the exe imports (std::codecvt_utf8_utf16 and a
stringbuf::seekpos); Windows refused the node with Entry Point Not Found. -C link-arg=-static had never removed
the libstdc++ import (0.3.5's Mac-built exe carries it too).
- packaging/windows/check-runtime-dlls.sh: objdump imports per DLL against the DLL's exports; shown to fail
  the 0.3.6 pairing (7 missing) and pass 0.3.5's; run by push-inputs.sh before signing and by make-payload.sh
- push-inputs.sh: DLLs next to the exes first, then the Mac toolchain
- jobbuild.rs: the PC's windows stage copies its own toolchain's three DLLs into the pack (unit test);
  build-job.mjs accepts the small DLL PE files and places them next to the exes
- cross-build.sh: -static-libstdc++ added as a try (measured on the 0.3.7 build)
- the six version files: 0.3.7
2026-10-05 10:46:49 +01:00

122 lines
10 KiB
Bash
Executable file

#!/usr/bin/env bash
# Assembles the Windows payload for Igneum Miner 0.3.0 on the Mac and zips it: packaging/windows/igneum-windows-app/
# and ~/Desktop/igneum-windows-app.zip (or $1). On the PC: extract the zip next to packaging\windows (or let
# build-installer.ps1 fetch it), run app\windows\BUILD-APP.bat (the WebView2 window host, optional), then
# packaging\windows\BUILD-INSTALLER.bat.
#
# What goes in:
# igneum-app.exe the engine, cross-compiled here (app/igneum-app, x86_64-pc-windows-gnu)
# igneum-prove-verify.exe the node's proof verifier wrapper (runs igneum-prove-host inside WSL2), same build
# igneumd.exe, igneum-miner.exe the devnet-v4 cross-build (vendor/igneum-node/target-integration/x86_64-pc-windows-gnu/release)
# lib*.dll the three mingw runtime DLLs, as igneum-windows-v4.zip ships them
# igneum-worker-cuda.exe, igneum-worker-opencl.exe, nvrtc*.dll the prebuilt GPU workers from the proto-cuda/proto-opencl
# agent when they exist (searched in a few places; IGNEUM_WORKERS_DIR overrides); without them
# the engine builds the CUDA worker from proto-cuda\ on the PC (needs the CUDA Toolkit and MSVC)
# proto-cuda\, proto-opencl\ the worker sources and build.bat for that fallback
# igneum-app.json the update manifest URL and the log intake key, from the files named by IGNEUM_DL_TOKEN_FILE and
# IGNEUM_INTAKE_KEY_FILE (defaults: the .next files under ~/.config/igneum when staged, else the
# plain ones; packaging/mac/packaged-config.sh, sourced here; never in the repo)
# stop-igneum.ps1 what the installer runs before an upgrade and on uninstall
# app\windows\ host.cpp, host.rc, version.h, BUILD-APP.bat (the window host is built on the PC or by CI)
# Igneum Miner.exe the window host, when app/windows/dist/ holds one (BUILD-APP.bat ran before this script)
# On GitHub (.github/workflows/windows.yml) the same script runs in Git Bash with IGNEUM_WIN_RELEASE and
# IGNEUM_WORKERS_DIR pointing at the unpacked payload-inputs.zip (push-inputs.sh) and IGNEUM_APP_EXE at the engine
# built on the runner; the mingw DLLs are taken from the release folder there, zip falls back to 7z.
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$HERE/../.." && pwd)"
VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' "$ROOT/app/igneum-app/Cargo.toml" | head -1)"
OUT="${1:-$HOME/Desktop/igneum-windows-app.zip}"
case "$OUT" in /*) ;; *) OUT="$PWD/$OUT" ;; esac
mkdir -p "$(dirname "$OUT")"
REL="${IGNEUM_WIN_RELEASE:-$ROOT/vendor/igneum-node/target-integration/x86_64-pc-windows-gnu/release}"
ENGINE="${IGNEUM_APP_EXE:-$ROOT/app/igneum-app/target/x86_64-pc-windows-gnu/release/igneum-app.exe}"
MINGW=/opt/homebrew/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32
STAGE="$HERE/igneum-windows-app"
# the packaged configuration (the manifest URL from the token file, the intake key from the key file, NODE_OVERRIDE_PARAMS)
. "$ROOT/packaging/mac/packaged-config.sh"
[ -f "$ENGINE" ] || { echo "no $ENGINE: build it first (cd app/igneum-app && cargo build --release --target x86_64-pc-windows-gnu, see proto-cuda/windows-node/cross-build.sh for the environment)" >&2; exit 1; }
[ -f "$REL/igneumd.exe" ] || { echo "no $REL/igneumd.exe; cross-compile the node first" >&2; exit 1; }
[ -f "$REL/igneum-miner.exe" ] || { echo "no $REL/igneum-miner.exe; cross-compile the miner first" >&2; exit 1; }
rm -rf "$STAGE"
mkdir -p "$STAGE/proto-cuda/packs" "$STAGE/proto-opencl" "$STAGE/app/windows"
cp "$ENGINE" "$STAGE/igneum-app.exe"
# the node's proof verifier on a PC (release 0.3.6, app/igneum-app/src/bin/prove-verify.rs): the engine sets
# IGNEUM_PROOF_VERIFIER to this wrapper, which runs the WSL2 host; built beside the engine by the same cargo build
if [ -f "$(dirname "$ENGINE")/igneum-prove-verify.exe" ]; then cp "$(dirname "$ENGINE")/igneum-prove-verify.exe" "$STAGE/"; echo "verifier wrapper: igneum-prove-verify.exe"
else echo "warning: no igneum-prove-verify.exe next to $ENGINE; the node on this build relays proof records and never includes them"; fi
cp "$REL/igneumd.exe" "$STAGE/igneumd.exe"
cp "$REL/igneum-miner.exe" "$STAGE/igneum-miner.exe"
for dll in lib/libstdc++-6.dll lib/libgcc_s_seh-1.dll bin/libwinpthread-1.dll; do
name="$(basename "$dll")"
if [ -f "$REL/$name" ]; then cp "$REL/$name" "$STAGE/" # push-inputs.sh ships them next to the exes (CI)
elif [ -f "$MINGW/$dll" ]; then cp "$MINGW/$dll" "$STAGE/"; x86_64-w64-mingw32-strip "$STAGE/$name" 2>/dev/null || true
else echo "note: $name not found in the mingw toolchain (the node exe is linked -static, so it may not need it)"; fi
done
"$(dirname "$0")/check-runtime-dlls.sh" "$STAGE" # every imported libstdc++ symbol exported by the shipped DLL (5 October 2026)
# the prebuilt one-click workers, from where proto-cuda/windows-app/make-package.sh takes them: the NVRTC CUDA worker
# with NVIDIA's redistributable DLLs and licence texts, and the OpenCL worker (IGNEUM_WORKERS_DIR overrides with a flat folder)
NVRTC_DIR="$ROOT/proto-cuda/nvrtc"
found_workers=0
if [ -n "${IGNEUM_WORKERS_DIR:-}" ] && [ -d "$IGNEUM_WORKERS_DIR" ]; then
for f in "$IGNEUM_WORKERS_DIR"/igneum-worker-*.exe "$IGNEUM_WORKERS_DIR"/nvrtc*.dll "$IGNEUM_WORKERS_DIR"/LICENSE-*.txt "$IGNEUM_WORKERS_DIR"/THIRD-PARTY.md; do
[ -f "$f" ] && { cp "$f" "$STAGE/"; found_workers=1; }
done
else
if [ -f "$NVRTC_DIR/igneum-worker-cuda.exe" ]; then
cp "$NVRTC_DIR/igneum-worker-cuda.exe" "$STAGE/"; found_workers=1
for f in "$NVRTC_DIR"/redist/bin/nvrtc*.dll "$NVRTC_DIR"/redist/LICENSE-*.txt "$NVRTC_DIR/THIRD-PARTY.md"; do [ -f "$f" ] && cp "$f" "$STAGE/"; done
ls "$STAGE"/nvrtc64_*_0.dll >/dev/null 2>&1 || echo "warning: igneum-worker-cuda.exe without nvrtc64_*_0.dll (run $NVRTC_DIR/fetch-redist.sh); the engine will not use it"
fi
if [ -f "$ROOT/proto-opencl/igneum-worker-opencl.exe" ]; then cp "$ROOT/proto-opencl/igneum-worker-opencl.exe" "$STAGE/"; found_workers=1; fi
fi
if [ "$found_workers" = 1 ]; then echo "workers: $(cd "$STAGE" && ls igneum-worker-*.exe nvrtc*.dll 2>/dev/null | tr '\n' ' ')"
else echo "note: no prebuilt igneum-worker-cuda.exe / igneum-worker-opencl.exe found; the engine builds the CUDA worker from proto-cuda\\ on the PC (CUDA Toolkit and MSVC needed)"; fi
# the worker sources for the fallback build
cp "$ROOT/proto-cuda/host.cu" "$ROOT/proto-cuda/build.bat" "$ROOT/proto-cuda/README.md" "$STAGE/proto-cuda/"
cp "$ROOT/proto-opencl/host.c" "$ROOT/proto-opencl/build.bat" "$ROOT/proto-opencl/README.md" "$STAGE/proto-opencl/"
# the window host sources, built on the PC or by CI; the built host when BUILD-APP.bat already ran here
cp "$ROOT/app/windows/host.cpp" "$ROOT/app/windows/host.rc" "$ROOT/app/windows/version.h" "$ROOT/app/windows/BUILD-APP.bat" "$STAGE/app/windows/"
mkdir -p "$STAGE/app/windows/art" && cp "$ROOT/brand/icons/igneum.ico" "$STAGE/app/windows/art/"
if [ -f "$ROOT/app/windows/dist/Igneum Miner.exe" ]; then cp "$ROOT/app/windows/dist/Igneum Miner.exe" "$STAGE/"; echo "window host: Igneum Miner.exe from app/windows/dist"; fi
cp "$HERE/stop-igneum.ps1" "$STAGE/stop-igneum.ps1"
# proving v0 (spec 7.7, app/igneum-app/src/prover.rs): the SP1 host runs inside WSL2 on a PC, so the payload ships the
# Linux x86_64 host and exporter (proving/igneum-prove cross-built with cargo-zigbuild, glibc 2.36, sp1 cuda feature;
# IGNEUM_PROVE_LINUX overrides the folder) under wsl2\bin\, the WSL2 setup scripts and the fixtures. The engine runs
# them as /mnt/<drive>/.../wsl2/bin/igneum-prove-host from Ubuntu-24.04; Set up runs wsl2\setup-wsl.sh.
PROVE_LINUX="${IGNEUM_PROVE_LINUX:-$ROOT/proving/igneum-prove/target-linux/x86_64-unknown-linux-gnu/release}"
mkdir -p "$STAGE/wsl2/bin" "$STAGE/wsl2/fixtures"
if [ -f "$PROVE_LINUX/igneum-prove-host" ] && [ -f "$PROVE_LINUX/igneum-prove-export" ]; then
cp "$PROVE_LINUX/igneum-prove-host" "$PROVE_LINUX/igneum-prove-export" "$STAGE/wsl2/bin/"
echo "prover (WSL2): igneum-prove-host $(stat -f %z "$PROVE_LINUX/igneum-prove-host") bytes, igneum-prove-export $(stat -f %z "$PROVE_LINUX/igneum-prove-export") bytes"
else echo "warning: no Linux igneum-prove-host/igneum-prove-export in $PROVE_LINUX (cargo zigbuild --target x86_64-unknown-linux-gnu.2.36 --features igneum-prove-host/cuda); the Proving tile will ask for the WSL2 setup, which builds them"; fi
cp "$ROOT"/proving/windows-wsl2/*.sh "$ROOT"/proving/windows-wsl2/*.ps1 "$ROOT"/proving/windows-wsl2/*.bat "$ROOT/proving/windows-wsl2/README.txt" "$STAGE/wsl2/"
cp "$ROOT"/proving/fixtures/*.json "$STAGE/wsl2/fixtures/"
# the packaged configuration: the token and the key stay out of the repo (packaged-config.sh prints the file names and
# the fingerprints, never the values)
write_packaged_config "$STAGE/igneum-app.json"
cat > "$STAGE/README.txt" <<TXT
Igneum Miner $VERSION for Windows (payload). Devnet v4. Test network; nothing is bought or sold.
Nobody from Igneum will ever ask for your seed.
This folder is what the installer packs. To build the installer on a PC:
1. app\\windows\\BUILD-APP.bat builds "Igneum Miner.exe" (the window; needs Visual Studio; optional)
2. packaging\\windows\\BUILD-INSTALLER.bat builds Igneum-Miner-Setup-$VERSION.exe (Inno Setup via winget)
To run without the installer: double-click igneum-app.exe (the dashboard opens in your browser).
TXT
for f in "$STAGE"/*.bat "$STAGE/README.txt" "$STAGE/stop-igneum.ps1" "$STAGE/app/windows/BUILD-APP.bat" "$STAGE/proto-cuda/build.bat" "$STAGE/proto-opencl/build.bat"; do
[ -f "$f" ] && perl -pi -e 's/\r?\n/\r\n/' "$f"
done
rm -f "$OUT"
if command -v zip >/dev/null 2>&1; then (cd "$HERE" && zip -qr "$OUT" "igneum-windows-app" -x '*.DS_Store')
elif command -v 7z >/dev/null 2>&1; then (cd "$HERE" && 7z a -tzip -bso0 -bsp0 "$OUT" "igneum-windows-app" '-xr!.DS_Store')
else echo "neither zip nor 7z is on PATH" >&2; exit 1; fi
echo "staged $STAGE"
ls -la "$OUT"
if command -v unzip >/dev/null 2>&1; then unzip -l "$OUT" | tail -n +4 | awk '{print $1, $4}' | sed '/^ *$/d' | head -40
else (cd "$STAGE" && find . -type f | sort | head -40); fi