#!/usr/bin/env bash # Markus Maiwald (Architect) | Voxis Forge (AI) set -e # Nexus Rumpk Build Script v0.4 # "Split Brain" Networking Edition RUMPK_DIR=$(pwd) BUILD_DIR="$RUMPK_DIR/build" mkdir -p "$BUILD_DIR" export ZIG_GLOBAL_CACHE_DIR="$BUILD_DIR/.zig-cache" export ZIG_LOCAL_CACHE_DIR="$BUILD_DIR/.zig-cache-local" ARCH=${1:-riscv64} case $ARCH in riscv64) ZIG_TARGET="riscv64-freestanding-none" ZIG_OBJ_FLAGS="-mcpu=sifive_u54 -mcmodel=medany" ARCH_FLAGS="-mcpu=sifive_u54 -mabi=lp64d -mcmodel=medany -ffunction-sections -fdata-sections" NIM_CPU="riscv64" NIM_DEFINE="riscv64" ENTRY_FILE="riscv" ;; x86_64) ZIG_TARGET="x86_64-freestanding-none" ARCH_FLAGS="-mno-red-zone" NIM_CPU="amd64" NIM_DEFINE="x86_64" ENTRY_FILE="x86_64" ;; aarch64) ZIG_TARGET="aarch64-freestanding-none" ARCH_FLAGS="" NIM_CPU="arm64" NIM_DEFINE="aarch64" ENTRY_FILE="aarch64" ;; *) echo "Unsupported architecture: $ARCH" exit 1 ;; esac echo "╔═══════════════════════════════════════╗" echo "║ RUMPK MULTI-ARCH BUILD v0.4 ║" echo "║ Architecture: $ARCH " echo "╚═══════════════════════════════════════╝" # ========================================================= # Step 1: Compile Zig L0 (HAL + libc stubs) # ========================================================= echo "[1/8] Compiling Zig L0 (HAL + libc stubs)..." zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/hal/entry_$ENTRY_FILE.zig" \ --name hal mv hal.o "$BUILD_DIR/hal.o" echo " → $BUILD_DIR/hal.o" zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/hal/stubs.zig" \ --name stubs mv stubs.o "$BUILD_DIR/stubs.o" echo " → $BUILD_DIR/stubs.o" zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/hal/channel.zig" \ --name channel mv channel.o "$BUILD_DIR/channel.o" echo " → $BUILD_DIR/channel.o" # Compile NexShell NPL (Immune System Voice) echo "[1.1/8] Compiling NexShell NPL..." zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/src/npl/system/nexshell.zig" \ --name nexshell mv nexshell.o "$BUILD_DIR/nexshell.o" echo " → $BUILD_DIR/nexshell.o" # Compile UI (Zicroui) echo "[1.2/8] Compiling UI (Zicroui)..." zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ -I"$RUMPK_DIR/libs/microui" \ "$RUMPK_DIR/hal/ui.zig" \ --name ui mv ui.o "$BUILD_DIR/ui.o" echo " → $BUILD_DIR/ui.o" # Compile GPU Driver (Retina) echo "[1.3/8] Compiling GPU Driver (VirtIO-GPU)..." zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/hal/gpu.zig" \ --name gpu mv gpu.o "$BUILD_DIR/gpu.o" echo " → $BUILD_DIR/gpu.o" # Compile Matrix Protocol (Rainmaker) echo "[1.4/8] Compiling Matrix Protocol..." zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/hal/matrix.zig" \ --name matrix mv matrix.o "$BUILD_DIR/matrix.o" echo " → $BUILD_DIR/matrix.o" # ========================================================= # Step 2: Compile context switch assembly # ========================================================= echo "[2/8] Compiling context switch ($ARCH)..." zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -c "$RUMPK_DIR/hal/arch/$ARCH/switch.S" \ -o "$BUILD_DIR/switch.o" echo " → $BUILD_DIR/switch.o" # ========================================================= # Step 2.1: Compile Monocypher # ========================================================= echo "[2.1/8] Compiling Monocypher..." zig cc \ -target $ZIG_TARGET \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O3 \ -c "$RUMPK_DIR/hal/crypto/monocypher.c" \ -o "$BUILD_DIR/monocypher.o" echo " → $BUILD_DIR/monocypher.o" # ========================================================= # Step 2.1b: Compile Microui # ========================================================= echo "[2.1b/8] Compiling Microui..." zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O3 \ -I"$RUMPK_DIR/libs/microui/include" \ -c "$RUMPK_DIR/libs/microui/microui.c" \ -o "$BUILD_DIR/microui.o" echo " → $BUILD_DIR/microui.o" # ========================================================= # Step 2.2: Compile LwIP (Kernel Stack) # ========================================================= # echo "[2.2/8] Compiling LwIP (Kernel)..." # LWIP_CORE_FILES=( # "src/core/init.c" # "src/core/def.c" # "src/core/dns.c" # "src/core/inet_chksum.c" # "src/core/ip.c" # "src/core/mem.c" # "src/core/memp.c" # "src/core/netif.c" # "src/core/pbuf.c" # "src/core/raw.c" # "src/core/stats.c" # "src/core/sys.c" # "src/core/tcp.c" # "src/core/tcp_in.c" # "src/core/tcp_out.c" # "src/core/timeouts.c" # "src/core/udp.c" # "src/core/ipv4/autoip.c" # "src/core/ipv4/dhcp.c" # "src/core/ipv4/etharp.c" # "src/core/ipv4/icmp.c" # "src/core/ipv4/igmp.c" # "src/core/ipv4/ip4.c" # "src/core/ipv4/ip4_addr.c" # "src/core/ipv4/ip4_frag.c" # "src/netif/ethernet.c" # ) # # for cfile in "${LWIP_CORE_FILES[@]}"; do # cfile_path="$RUMPK_DIR/vendor/lwip/$cfile" # objname=$(basename "$cfile" .c) # zig cc \ # -target $ZIG_TARGET \ # $ARCH_FLAGS \ # -ffreestanding \ # -fno-stack-protector \ # -fno-builtin \ # -O2 \ # -I"$RUMPK_DIR/core/include" \ # -I"$RUMPK_DIR/core/net" \ # -I"$RUMPK_DIR/vendor/lwip/src/include" \ # -c "$cfile_path" \ # -o "$BUILD_DIR/lwip_kernel_$objname.o" # done # ========================================================= # Step 2.3: Compile LwIP (Membrane Stack) # ========================================================= echo "[2.3/8] Compiling LwIP (Membrane)..." for cfile in "${LWIP_CORE_FILES[@]}"; do cfile_path="$RUMPK_DIR/vendor/lwip/$cfile" objname=$(basename "$cfile" .c) zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O2 \ -I"$RUMPK_DIR/core/include" \ -I"$RUMPK_DIR/core/net" \ -I"$RUMPK_DIR/libs/membrane/include" \ -I"$RUMPK_DIR/vendor/lwip/src/include" \ -c "$cfile_path" \ -o "$BUILD_DIR/lwip_membrane_$objname.o" done LWIP_MEMBRANE_OBJS=$(ls $BUILD_DIR/lwip_membrane_*.o) # Compile sys_arch.c (LwIP Platform Abstraction) echo "[2.4/8] Compiling LwIP Platform Layer (sys_arch.c)..." # zig cc \ # -target $ZIG_TARGET \ # $ARCH_FLAGS \ # -ffreestanding \ # -fno-stack-protector \ # -fno-builtin \ # -O2 \ # -I"$RUMPK_DIR/core/include" \ # -I"$RUMPK_DIR/core/net" \ # -I"$RUMPK_DIR/vendor/lwip/src/include" \ # -c "$RUMPK_DIR/core/net/sys_arch.c" \ # -o "$BUILD_DIR/sys_arch.o" # # echo " → LwIP objects compiled." # ========================================================= # Step 3: Compile Nim L1 (Kernel + Fibers) # ========================================================= echo "[3/8] Compiling Nim L1 (Kernel + Fibers)..." mkdir -p "$BUILD_DIR/nimcache" nim c \ --cpu:$NIM_CPU \ --os:any \ --mm:arc \ --noMain:on \ --cc:clang \ --passC:"-target ${ZIG_TARGET/-freestanding-none/-unknown-none} -ffreestanding -fno-stack-protector -fno-builtin $ARCH_FLAGS -I$RUMPK_DIR/core/include -O3 -flto" \ --define:useMalloc \ --define:nimNoLibc \ --define:noSignalHandler \ --define:$NIM_DEFINE \ -d:danger \ --opt:speed \ --nimcache:"$BUILD_DIR/nimcache" \ --path:"$RUMPK_DIR/core" \ -c \ "$RUMPK_DIR/core/kernel.nim" # ========================================================= # Step 4: Compile Nim C files # ========================================================= echo "[4/8] Compiling Nim C files..." zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O2 \ -I"$RUMPK_DIR/core/include" \ -c "$RUMPK_DIR/core/cstubs.c" \ -o "$BUILD_DIR/cstubs.o" echo " → $BUILD_DIR/cstubs.o" NIM_OBJS="" for cfile in "$BUILD_DIR/nimcache"/*.c; do ofile="${cfile%.c}.o" zig cc \ -target $ZIG_TARGET \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -fno-sanitize=all \ $ARCH_FLAGS \ -I"$RUMPK_DIR/core/include" \ -I/usr/lib/nim \ -I"$RUMPK_DIR/core" \ -O3 -flto \ -c "$cfile" \ -o "$ofile" NIM_OBJS="$NIM_OBJS $ofile" done echo " → $BUILD_DIR/nimcache/*.o" # ========================================================= # Step 4.1: Compile Overrides (Math/Atomics Stubs) # ========================================================= echo "[4.1/8] Compiling Sovereign Overrides..." zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O2 \ -I"$RUMPK_DIR/core/include" \ -c "$RUMPK_DIR/core/overrides.c" \ -o "$BUILD_DIR/overrides.o" echo " → $BUILD_DIR/overrides.o" # ========================================================= # Step 5: Compile Membrane Library (libnexus.a) # ========================================================= echo "[5/8] Compiling Membrane Library (libnexus.a)..." mkdir -p "$BUILD_DIR/membrane_nimcache" # Compile clib.c (The Mini-Libc) zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O2 \ -I"$RUMPK_DIR/core/include" \ -c "$RUMPK_DIR/libs/membrane/clib.c" \ -o "$BUILD_DIR/clib.o" # Compile sys_arch.c (Membrane LwIP Platform Layer) zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -O2 \ -I"$RUMPK_DIR/core/include" \ -I"$RUMPK_DIR/libs/membrane/include" \ -I"$RUMPK_DIR/vendor/lwip/src/include" \ -c "$RUMPK_DIR/libs/membrane/sys_arch.c" \ -o "$BUILD_DIR/membrane_sys_arch.o" nim c \ --cpu:$NIM_CPU \ --os:any \ -d:is_membrane \ -d:danger \ --opt:speed \ -d:useMalloc \ -d:nimNoLibc \ -d:noSignalHandler \ --gc:arc \ --panics:on \ --app:staticlib \ --nimMainPrefix:Membrane \ --hint:Conf:off \ --hint:OSLib:off \ --nimcache:"$BUILD_DIR/membrane_nimcache" \ --path:"$RUMPK_DIR/libs/membrane" \ --path:"$RUMPK_DIR/core" \ -c \ "$RUMPK_DIR/libs/membrane/libc.nim" MEMBRANE_NIM_OBJS="" for cfile in "$BUILD_DIR/membrane_nimcache"/*.c; do ofile="${cfile%.c}.o" zig cc \ -target $ZIG_TARGET \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -fno-sanitize=all \ $ARCH_FLAGS \ -I"$RUMPK_DIR/core/include" \ -I/usr/lib/nim \ -I"$RUMPK_DIR/core" \ -I"$RUMPK_DIR/libs/membrane" \ -I"$RUMPK_DIR/libs/membrane/include" \ -I"$RUMPK_DIR/vendor/lwip/src/include" \ -O3 -flto \ -c "$cfile" \ -o "$ofile" MEMBRANE_NIM_OBJS="$MEMBRANE_NIM_OBJS $ofile" done # ========================================================= # Step 5.1: [MOVED] NipBox compilation happens AFTER libnexus.a # ========================================================= # NipBox requires libnexus.a to link, so it's compiled at Step 5.6 echo "[5.1/8] Skipping Subject (NipBox will be compiled after Membrane)..." # ========================================================= # Step 5.5: Patch Atomic References & Nuke Cache (GLOBAL) # ========================================================= # We must do this BEFORE creating archives or linking anything. # This ensures broken libcompiler_rt refs are removed from ALL objects. echo "[5.5/8] Patching Atomic References & Nuking Cache..." find "$BUILD_DIR" -name "*.o" | while read obj; do zig objcopy --redefine-syms="$RUMPK_DIR/core/re-symbol.txt" "$obj" "$obj" 2>/dev/null || true # Remove auto-linking sections zig objcopy \ --remove-section .linker-options \ --remove-section .comment \ --remove-section .deplibs \ --remove-section .llvm_addrsig \ --remove-section .dependent-lib \ "$obj" "$obj" 2>/dev/null || true done echo " → SWAPPING libcompiler_rt.a with dummy archive (GLOB)..." echo "" > "$BUILD_DIR/dummy.c" zig cc -target $ZIG_TARGET -c "$BUILD_DIR/dummy.c" -o "$BUILD_DIR/dummy.o" $ARCH_FLAGS for lib in "$BUILD_DIR"/.zig-cache/o/*/libcompiler_rt.a; do if [ -f "$lib" ]; then echo " Replacing $lib" rm -f "$lib" zig ar rc "$lib" "$BUILD_DIR/dummy.o" fi done # ========================================================= # Step 5b: Create Membrane Archive # ========================================================= # Note: We manually include ion_switch.o from the KERNEL nimcache if needed, # but it should be in membrane_nimcache too because libc.nim imports it. # Let's verify if ion_switch.o exists in membrane_nimcache. ION_SWITCH_OBJ=$(ls "$BUILD_DIR/membrane_nimcache"/*ion_switch*o 2>/dev/null || echo "") zig ar rc "$BUILD_DIR/libnexus.a" \ $MEMBRANE_NIM_OBJS \ $LWIP_MEMBRANE_OBJS \ "$BUILD_DIR/clib.o" \ "$BUILD_DIR/membrane_sys_arch.o" \ "$BUILD_DIR/switch.o" echo " → $BUILD_DIR/libnexus.a" # ========================================================= # Step 5.6: Compile NipBox (The Sovereign Userland) # ========================================================= echo "[5.6/8] Compiling NipBox (Sovereign Userland)..." # Stage 1: Let Nim generate C code only (no linking) nim c \ --cpu:$NIM_CPU \ --os:any \ -d:danger \ --opt:size \ -d:useMalloc \ -d:nimNoLibc \ -d:noSignalHandler \ --mm:arc \ --checks:off \ --panics:on \ --noMain:off \ --hint:Conf:off \ --hint:OSLib:off \ --nimcache:"$BUILD_DIR/nipbox_nimcache" \ --path:"$RUMPK_DIR/libs/membrane" \ --path:"$RUMPK_DIR/core" \ --compileOnly \ "$RUMPK_DIR/npl/nipbox/nipbox.nim" # Stage 2: Compile all C files with zig cc echo "[5.6.1/8] Compiling NipBox C files with zig cc..." NIPBOX_OBJS="" find "$BUILD_DIR/nipbox_nimcache" -name "*.c" | while read cfile; do ofile="${cfile%.c}.o" zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -fno-builtin \ -Os \ -ffunction-sections \ -fdata-sections \ -I/usr/lib/nim \ -I"$RUMPK_DIR/core/include" \ -c "$cfile" \ -o "$ofile" done # Collect all object files NIPBOX_OBJS=$(find "$BUILD_DIR/nipbox_nimcache" -name "*.o" | tr '\n' ' ') # Stage 2.5: Compile libc_shim.zig (Universal Adapter) echo "[5.6.1b/8] Compiling libc_shim.zig..." zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseSmall \ "$RUMPK_DIR/libs/membrane/libc_shim.zig" \ --name libc_shim mv libc_shim.o "$BUILD_DIR/libc_shim.o" # Stage 2.6: Compile subject_entry.S echo "[5.6.1c/8] Compiling subject_entry.S..." zig cc -target $ZIG_TARGET -ffreestanding -c "$RUMPK_DIR/apps/subject_entry.S" -o "$BUILD_DIR/subject_entry.o" # Stage 3: Link with zig cc echo "[5.6.2/8] Linking NipBox binary..." zig cc \ -target $ZIG_TARGET \ $ARCH_FLAGS \ -ffreestanding \ -fno-stack-protector \ -nostdlib \ -static \ -Wl,--gc-sections \ -T "$RUMPK_DIR/apps/linker_user.ld" \ "$BUILD_DIR/subject_entry.o" \ "$BUILD_DIR/stubs.o" \ $NIPBOX_OBJS \ "$BUILD_DIR/libc_shim.o" \ -L"$BUILD_DIR" \ -lnexus \ -o "$BUILD_DIR/nipbox" # Convert NipBox binary to object file for embedding echo "[5.6.3/8] Embedding NipBox as Subject..." llvm-objcopy -O binary "$BUILD_DIR/nipbox" "$BUILD_DIR/nipbox.bin" # Generate assembly wrapper for safe embedding cat < "$BUILD_DIR/subject_wrapper.S" .section .rodata .global _subject_start .global _subject_end _subject_start: .incbin "$BUILD_DIR/nipbox.bin" _subject_end: EOF # Compile wrapper to object file zig cc \ -target $ZIG_TARGET \ -c "$BUILD_DIR/subject_wrapper.S" \ -o "$BUILD_DIR/subject_zig.o" echo " → $BUILD_DIR/nipbox ($(stat -c%s "$BUILD_DIR/nipbox" 2>/dev/null || echo "unknown") bytes)" echo " → $BUILD_DIR/subject_zig.o (embedded)" # ========================================================= # Step 6: Link Subject Zero # ========================================================= echo "[6/8] Linking Subject Zero (Canary)..." # Note: subject_zero.o and libnexus.a are already compiled and patched. # ========================================================= # Step 6: Link Subject Zig # ========================================================= echo "[6/8] Linking Subject Zig..." zig cc \ -target $ZIG_TARGET \ -nostdlib \ -T "$RUMPK_DIR/apps/linker_user.ld" \ "$BUILD_DIR/subject_zig.o" \ "$BUILD_DIR/libnexus.a" \ -o "$BUILD_DIR/subject.elf" \ -lgcc echo " → $BUILD_DIR/subject.elf" zig objcopy -O binary "$BUILD_DIR/subject.elf" "$BUILD_DIR/subject.bin" echo " → $BUILD_DIR/subject.bin" # ========================================================= # Step 7: Compile Loader (After Subject) # ========================================================= echo "[7/8] Compiling Loader (with Embedded Subject)..." # Copy nipbox.bin to core/ so loader.zig can embed it (replacing stale subject.bin) cp "$BUILD_DIR/nipbox.bin" "$RUMPK_DIR/core/subject.bin" zig build-obj \ -target $ZIG_TARGET \ $ZIG_OBJ_FLAGS \ -O ReleaseFast \ "$RUMPK_DIR/core/loader.zig" \ --name loader mv loader.o "$BUILD_DIR/loader.o" echo " → $BUILD_DIR/loader.o" # Clean up temp file rm "$RUMPK_DIR/core/subject.bin" # Patch Loader Object specifically echo " → Patching Loader Object..." obj="$BUILD_DIR/loader.o" zig objcopy --redefine-syms="$RUMPK_DIR/core/re-symbol.txt" "$obj" "$obj" 2>/dev/null || true zig objcopy \ --remove-section .linker-options \ --remove-section .comment \ --remove-section .deplibs \ --remove-section .llvm_addrsig \ --remove-section .dependent-lib \ "$obj" "$obj" 2>/dev/null || true # ========================================================= # Step 8: Link Kernel (Direct LLD Bypass) # ========================================================= echo "[8/8] Linking Kernel ($ARCH) using LLD..." # Check if ld.lld is available, otherwise assume zig cc wrapper but we try direct first LINKER="ld.lld" EMULATION="" if [ "$ARCH" = "riscv64" ]; then EMULATION="-m elf64lriscv" elif [ "$ARCH" = "x86_64" ]; then EMULATION="-m elf_x86_64" elif [ "$ARCH" = "aarch64" ]; then EMULATION="-m aarch64elf" fi $LINKER \ -t \ $EMULATION \ --gc-sections \ -T "$RUMPK_DIR/hal/arch/$ARCH/linker.ld" \ "$BUILD_DIR/hal.o" \ "$BUILD_DIR/stubs.o" \ "$BUILD_DIR/channel.o" \ "$BUILD_DIR/switch.o" \ "$BUILD_DIR/monocypher.o" \ "$BUILD_DIR/cstubs.o" \ "$BUILD_DIR/overrides.o" \ "$BUILD_DIR/loader.o" \ "$BUILD_DIR/nexshell.o" \ "$BUILD_DIR/ui.o" \ "$BUILD_DIR/gpu.o" \ "$BUILD_DIR/matrix.o" \ "$BUILD_DIR/microui.o" \ $NIM_OBJS \ -o "$BUILD_DIR/rumpk-$ARCH.elf" echo " → $BUILD_DIR/rumpk-$ARCH.elf" echo "" echo "✅ Build complete for $ARCH!" echo "Run with:" echo " qemu-system-riscv64 -M virt -nographic -kernel $BUILD_DIR/rumpk-riscv64.elf -netdev user,id=n0 -device virtio-net-pci,netdev=n0,disable-modern=on" echo ""