#!/bin/bash # NIP ARM64 Static Build Script using Zig # Builds a fully static ARM64 binary using Zig as C compiler with musl set -e echo "๐Ÿš€ Building NIP for ARM64 (aarch64-linux-musl) using Zig" echo "=========================================================" echo "" # Check dependencies if ! command -v nim &> /dev/null; then echo "โŒ Error: Nim compiler not found" exit 1 fi if ! command -v zig &> /dev/null; then echo "โŒ Error: Zig compiler not found" exit 1 fi echo "๐Ÿ“‹ Nim version: $(nim --version | head -1)" echo "๐Ÿ“‹ Zig version: $(zig version)" echo "" # Create Zig wrapper that shadows aarch64-linux-gnu-gcc ZIG_WRAPPER_DIR="/tmp/nip-zig-wrappers-arm64" rm -rf "$ZIG_WRAPPER_DIR" mkdir -p "$ZIG_WRAPPER_DIR" # Create a wrapper named exactly "aarch64-linux-gnu-gcc" that calls zig cc # This shadows the system's aarch64-linux-gnu-gcc when prepended to PATH # Filters out x86-specific compile flags AND problematic linker flags cat > "$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" << 'WRAPPER' #!/bin/bash # Zig CC wrapper for ARM64 cross-compilation # Shadows system's aarch64-linux-gnu-gcc and filters incompatible flags FILTERED_ARGS=() echo "Wrapper called with:" >> /tmp/wrapper.log printf "'%s' " "$@" >> /tmp/wrapper.log echo "" >> /tmp/wrapper.log for arg in "$@"; do case "$arg" in # Skip x86-specific compile flags -mpclmul|-maes|-msse*|-mavx*|-mno-80387|-fcf-protection|-fstack-clash-protection) ;; -march=x86*|-march=native) ;; -mtune=haswell|-mtune=skylake|-mtune=generic) ;; -Wp,-D_FORTIFY_SOURCE=*) ;; -flto) # LTO can cause issues with zig cross-compile ;; # Skip dynamic library flags that don't work with musl static -ldl) # musl's libc.a includes dl* functions, no separate libdl needed ;; # Filter all march/mtune flags to avoid zig cc conflicts -m64|-m32|-march=*|-mtune=*|-mcpu=*|-Xclang*|-target-feature*) # skip host-specific flags ;; *) FILTERED_ARGS+=("$arg") ;; esac done exec zig cc -target aarch64-linux-musl "${FILTERED_ARGS[@]}" WRAPPER chmod +x "$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" echo "โœ… Created Zig wrapper at $ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" echo "" # Clean previous builds and cache echo "๐Ÿงน Cleaning previous ARM64 builds and Nim cache..." rm -f nip-arm64 nip_arm64 nip-arm64-musl rm -rf ~/.cache/nim/nip_* rm -rf /tmp/nip-arm64-cache echo "" # Prepend our wrapper to PATH export PATH="$ZIG_WRAPPER_DIR:$PATH" # Verify our wrapper is first in PATH FOUND_GCC=$(which aarch64-linux-gnu-gcc) echo "๐Ÿ” Using gcc wrapper: $FOUND_GCC" echo "" # Compile statically echo "๐Ÿ”จ Building optimized ARM64 static binary..." echo " Target: aarch64-linux-musl (static via Zig)" echo " This may take a few minutes..." nim c \ --cpu:arm64 \ --os:linux \ --cc:gcc \ --gcc.exe:"$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" \ --gcc.linkerexe:"$ZIG_WRAPPER_DIR/aarch64-linux-gnu-gcc" \ --passC:"-O2" \ --passC:"-w" \ --passL:-static \ --passL:-s \ -d:release \ -d:danger \ -d:nimcrypto_disable_neon \ -d:nimcrypto_no_asm \ -d:nimcrypto_sysrand \ --opt:size \ --mm:orc \ --threads:on \ --nimcache:/tmp/nip-arm64-cache \ --skipProjCfg \ --out:nip-arm64 \ src/nip.nim 2>&1 | tee /tmp/nip-arm64-build.log if [ ! -f "nip-arm64" ]; then echo "" echo "โŒ Build failed! Check /tmp/nip-arm64-build.log for details" echo "Last 20 lines of error:" tail -20 /tmp/nip-arm64-build.log exit 1 fi echo "" echo "โœ… Build successful!" echo "" # Show binary info echo "๐Ÿ“Š Binary Information:" ls -lh nip-arm64 echo "" echo "๐Ÿ” File details:" file nip-arm64 echo "" # Verify it's ARM64 if file nip-arm64 | grep -q "ARM aarch64"; then echo "โœ… Verified: Binary is ARM64 aarch64" else echo "โš ๏ธ Binary may not be ARM64 - check file output above" fi echo "" # Verify static linking with readelf echo "๐Ÿ” Verifying static linking..." if readelf -d nip-arm64 2>/dev/null | grep -q "NEEDED"; then echo "โš ๏ธ Binary has dynamic dependencies:" readelf -d nip-arm64 2>/dev/null | grep NEEDED else echo "โœ… No dynamic dependencies found (fully static)" fi echo "" # Test with QEMU if available echo "๐Ÿงช Testing binary with QEMU user-mode emulation..." if command -v qemu-aarch64 &> /dev/null; then if timeout 10 qemu-aarch64 ./nip-arm64 --version 2>&1; then echo "โœ… Binary works under QEMU aarch64 emulation" else echo "โš ๏ธ Binary may need additional setup" fi else echo "โ„น๏ธ QEMU aarch64 user-mode not available" fi echo "" # Create output directory OUTPUT_DIR="build/arm64" mkdir -p "$OUTPUT_DIR" cp nip-arm64 "$OUTPUT_DIR/nip" chmod +x "$OUTPUT_DIR/nip" echo "๐ŸŽ‰ ARM64 build complete!" echo "" echo "๐Ÿ“‹ Build Summary:" echo " Binary: nip-arm64" echo " Target: aarch64-linux-musl (static)" echo " Size: $(ls -lh nip-arm64 | awk '{print $5}')" echo " Output: $OUTPUT_DIR/nip" echo "" echo "๐Ÿ“ฆ Ready for NexBox integration!"