#!/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) # 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 (token from ~/.config/igneum/dl-token, never in the repo), the log intake # 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" TOKEN_FILE="$HOME/.config/igneum/dl-token" [ -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" 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 # 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//.../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 download token stays out of the repo TOKEN="" [ -f "$TOKEN_FILE" ] && TOKEN="$(tr -d '[:space:]' < "$TOKEN_FILE")" MANIFEST="" [ -n "$TOKEN" ] && MANIFEST="https://dl.igneum.network/dl/$TOKEN/igneum-app-latest.json" [ -n "$MANIFEST" ] || echo "note: no $TOKEN_FILE; the update check is disabled in this build" LOG_KEY="$(sed -n 's/^LOG_KEY="\(.*\)"/\1/p' "$ROOT/packaging/mac/packaged-config.sh")" # the pinned consensus parameters (packaged-config.sh NODE_OVERRIDE_PARAMS, e.g. the difficulty v2 activation height) NODE_OVERRIDE_PARAMS="$(sed -n "s/^NODE_OVERRIDE_PARAMS='\(.*\)'/\1/p" "$ROOT/packaging/mac/packaged-config.sh")" OVERRIDE_LINE="" [ -n "$NODE_OVERRIDE_PARAMS" ] && OVERRIDE_LINE=" \"node_override_params\": $NODE_OVERRIDE_PARAMS," cat > "$STAGE/igneum-app.json" < "$STAGE/README.txt" </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