From 1075d4fff9eb75eb6d4299ad96a6ef3e83ae1bb0 Mon Sep 17 00:00:00 2001 From: Judah Caruso Date: Thu, 19 Feb 2026 23:40:54 -0700 Subject: [PATCH] support wasm build commands --- .gitignore | 2 ++ do.ps1 | 90 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index decca13..4d8e394 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .zed/ out/p2601* +out/*.o thirdparty/zig* +thirdparty/emsdk .DS_Store diff --git a/do.ps1 b/do.ps1 index 803383b..1322535 100755 --- a/do.ps1 +++ b/do.ps1 @@ -29,6 +29,7 @@ $EXE_NAME = "p2601"; function Get-Ext($platform) { if ($platform -eq "windows") { return ".exe"; } + if ($platform -eq "emscripten") { return ".o"; } return ""; } @@ -37,9 +38,14 @@ $ZIG_SLUG = "zig-${HOST_ARCH}-${HOST_OS}-${ZIG_VERSION}"; $ZIG_DIR = Join-Path $DEPS_DIR $ZIG_SLUG $ZIG = Join-Path $ZIG_DIR "zig$(Get-Ext $HOST_OS)" -$BLOCKS_RT_DIR = Join-Path $DEPS_DIR "blocksruntime"; -$BLOCKS_RT_FLAGS = "-I$BLOCKS_RT_DIR -I$(Join-Path $BLOCKS_RT_DIR "BlocksRuntime")"; -$BLOCKS_RT_SOURCE = (Join-Path $BLOCKS_RT_DIR "BlocksRuntime" "runtime.c") + " " + (Join-Path $BLOCKS_RT_DIR "BlocksRuntime" "data.c"); +$BLOCKS_RT_DIR = Join-Path $DEPS_DIR "blocksruntime"; +$BLOCKS_RT_FLAGS = "-I$BLOCKS_RT_DIR -I$(Join-Path $BLOCKS_RT_DIR "BlocksRuntime")"; +$BLOCKS_RT_RUNTIME = (Join-Path $BLOCKS_RT_DIR "BlocksRuntime" "runtime.c"); +$BLOCKS_RT_DATA = (Join-Path $BLOCKS_RT_DIR "BlocksRuntime" "data.c"); +$BLOCKS_RT_SOURCE = "$BLOCKS_RT_RUNTIME $BLOCKS_RT_DATA"; + +$EMSDK_REPO = "https://github.com/emscripten-core/emsdk.git"; +$EMSDK_DIR = Join-Path $DEPS_DIR "emsdk"; $C_SOURCE = "src/main.c"; $C_INCLUDES = "-Isrc -I$DEPS_DIR"; @@ -49,7 +55,7 @@ $RELEASE_FLAGS = "-Ofast -Wno-everything -ffast-math"; $WINDOWS_FLAGS = "-ld3d11 -lgdi32"; $MACOS_FLAGS = "-x objective-c -lobjc -framework Foundation -framework Cocoa -framework CoreFoundation -framework CoreGraphics -framework QuartzCore -framework Metal -framework MetalKit"; $LINUX_FLAGS = "-lgl"; - +$WASM_FLAGS = "-c -fno-sanitize=address -fno-sanitize=undefined -isystem " + (Join-Path $EMSDK_DIR "upstream" "emscripten" "cache" "sysroot" "include"); # try vendoring zig if (-not (Test-Path $ZIG)) { @@ -74,6 +80,21 @@ if (-not (Test-Path $ZIG)) { } } +# try vendoring emsdk +if (-not (Test-Path $EMSDK_DIR)) { + git clone $EMSDK_REPO $EMSDK_DIR + + Set-Location $EMSDK_DIR + + if ($IsWindows) { + &"./emsdk.bat" install latest + &"./emsdk.bat" activate latest + } else { + &"./emsdk" install latest + &"./emsdk" activate latest + } +} + # ensure the out directory exists New-Item -ItemType Directory -Force -Path $OUT_DIR | Out-Null; @@ -92,6 +113,9 @@ function Get-Flags($os, $release) { "linux" { $flags += " $LINUX_FLAGS $BLOCKS_RT_FLAGS -DPLATFORM_LINUX"; } + "emscripten" { + $flags += " $WASM_FLAGS $BLOCKS_RT_FLAGS -DPLATFORM_WASM -DPOINTER_32" + } default { Write-Error "Unsupported operating system '$os'"; } @@ -117,6 +141,9 @@ function Get-Source($os) { "linux" { $source += " $BLOCKS_RT_SOURCE"; } + "emscripten" { + $source += " $BLOCKS_RT_SOURCE" + } default { Write-Error "Unsupported operating system '$os'"; } @@ -139,7 +166,7 @@ switch ($command) { Write-Host (":: Compiling natively" + $(if ($release) { " (release mode)" } else { "" })); Write-Host $cmd; - + Invoke-Expression $cmd | Write-Host; } {($_ -eq "build-cross") -or ($_ -eq "bc")} { @@ -152,12 +179,39 @@ switch ($command) { Write-Error "Unsupported target '$target' - run list-targets to see possible targets"; } - $cmd = "$(CompileCommand $target_os $release) --target=$target -o $(Join-Path $OUT_DIR $($EXE_NAME + (Get-Ext $target_os)))"; + $out = Join-Path $OUT_DIR ($EXE_NAME + (Get-Ext $target_os)); + $cmd = "$(CompileCommand $target_os $release) --target=$target -o $out"; Write-Host (":: Cross-compiling for $target" + $(if ($release) { " (release mode)" } else { "" })); Write-Host $cmd; - + Invoke-Expression $cmd | Write-Host; + + if ($target_os -eq "emscripten") { + if (-not $IsWindows) { + Set-Alias "python" "python3"; + } + + [Environment]::SetEnvironmentVariable("EMSDK_QUIET", 1); + & (Join-Path $EMSDK_DIR "emsdk_env.ps1"); + + $runtime_o = (Join-Path $OUT_DIR "p2601-blocks-runtime.o"); + $cmd = "$ZIG cc $WASM_FLAGS $BLOCKS_RT_FLAGS --target=$target -c $BLOCKS_RT_RUNTIME -o $runtime_o"; + + Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; + + $data_o = (Join-Path $OUT_DIR "p2601-blocks-data.o"); + $cmd = "$ZIG cc $WASM_FLAGS $BLOCKS_RT_FLAGS --target=$target -c $BLOCKS_RT_DATA -o $data_O"; + + Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; + + $binary = Join-Path $OUT_DIR ($EXE_NAME + (Get-Ext $HOST_OS)); + $cmd = "emcc $out $runtime_o $data_o -sUSE_WEBGL2=1 -sFULL_ES3=1 -sALLOW_MEMORY_GROWTH -o " + (Join-Path $OUT_DIR ($EXE_NAME + ".html")); + Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; + } } {($_ -eq "run") -or ($_ -eq "r")} { $release = $rest[0] -eq "release" -or $rest[0] -eq "fast"; @@ -166,26 +220,40 @@ switch ($command) { Write-Host (":: Compiling natively" + $(if ($release) { " (release mode)" } else { "" })); Write-Host $cmd; - + Invoke-Expression $cmd | Write-Host; - + if ($LASTEXITCODE -eq 0) { Invoke-Expression $binary | Write-Host; } } + "run-wasm" { + if (-not (Test-Path (Join-Path $OUT_DIR "p2601.wasm"))) { + &"./do.ps1" build-cross wasm32-emscripten; + } + + $cmd = "$ZIG run " + (Join-Path $DEPS_DIR "tinyhttp.zig"); + Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; + } + {($_ -eq "clean") -or ($_ -eq "c")} { + Write-Host ":: Cleaning up build artifacts..."; + Remove-Item -Path (Join-Path $OUT_DIR ($EXE_NAME + "*")) -Force; + } {($_ -eq "list-targets") -or ($_ -eq "lt")} { # zig target doesn't actually output json... Write-Host ":: Available cross-compilation targets"; Write-Host " x86_64-windows-gnu"; Write-Host " x86_64-linux-gnu"; - Write-Host " wasm32-wasi"; - Write-Host " wasm32-freestanding"; + Write-Host " wasm32-emscripten"; } default { Write-Host ":: Available things to do"; Write-Host " build (b) compiles the program natively"; Write-Host " build-cross (bc) cross-compiles the program for the target triple (ex. x86_64-windows-gnu)"; Write-Host " run (r) compiles and runs the native program"; + Write-Host " run-wasm compiles and runs the wasm program"; + Write-Host " clean (c) cleans up all build artifacts"; Write-Host " list-targets (lt) lists all cross-compliation targets"; return; }