257 lines
8.1 KiB
PowerShell
Executable file
257 lines
8.1 KiB
PowerShell
Executable file
#!/usr/bin/env pwsh
|
|
$ErrorActionPreference = "Stop";
|
|
|
|
$HOST_OS = &{
|
|
if ($IsWindows) {
|
|
"windows"
|
|
} elseif ($IsMacOS) {
|
|
"macos";
|
|
} elseif ($IsLinux) {
|
|
"linux";
|
|
} else {
|
|
Write-Error "Unsupported host operating system";
|
|
}
|
|
};
|
|
|
|
$HOST_ARCH = &{
|
|
switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) {
|
|
"X86" { "x86" }
|
|
"X64" { "x86_64" }
|
|
"Arm" { "arm" }
|
|
"Arm64" { "aarch64" }
|
|
default { Write-Error "Unsupported host architecture"; }
|
|
}
|
|
}
|
|
|
|
$OUT_DIR = "out";
|
|
$DEPS_DIR = "thirdparty";
|
|
$EXE_NAME = "p2601";
|
|
|
|
function Get-Ext($platform) {
|
|
if ($platform -eq "windows") { return ".exe"; }
|
|
if ($platform -eq "emscripten") { return ".o"; }
|
|
return "";
|
|
}
|
|
|
|
$ZIG_VERSION = "0.15.2";
|
|
$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_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 = "source/main.c";
|
|
$C_INCLUDES = "-Isrc -I$DEPS_DIR";
|
|
$C_FLAGS = "-std=c23 -fblocks -g $C_INCLUDES";
|
|
$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)) {
|
|
$zig_ext = "";
|
|
if ($IsWindows) {
|
|
$zig_ext = ".zip";
|
|
} else {
|
|
$zig_ext = ".tar.xz";
|
|
}
|
|
|
|
$zig_url = "https://ziglang.org/download/$ZIG_VERSION/$ZIG_SLUG$ZIG_EXT";
|
|
Write-Host ":: Downloading Zig $ZIG_VERSION ($HOST_OS/$HOST_ARCH)";
|
|
Write-Host $zig_url;
|
|
|
|
if ($IsWindows) {
|
|
$tmp = Join-Path $DEPS_DIR "zig-compiler$zig_ext";
|
|
Invoke-WebRequest -Uri $zig_url -OutFile $tmp -UseBasicParsing
|
|
Expand-Archive -Path $tmp -DestinationPath $DEPS_DIR -Force
|
|
Remove-Item $tmp
|
|
} else {
|
|
curl -sSfL $zig_url | tar -xJ -C $DEPS_DIR
|
|
}
|
|
}
|
|
|
|
# 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;
|
|
|
|
|
|
# ...............
|
|
|
|
function GetFlags($os, $release) {
|
|
$flags = $C_FLAGS;
|
|
switch ($os) {
|
|
"windows" {
|
|
$flags += " $WINDOWS_FLAGS $BLOCKS_RT_FLAGS -DPLATFORM_WINDOWS";
|
|
}
|
|
"macos" {
|
|
$flags += " $MACOS_FLAGS -DPLATFORM_MACOS";
|
|
}
|
|
"linux" {
|
|
$flags += " $LINUX_FLAGS $BLOCKS_RT_FLAGS -DPLATFORM_LINUX";
|
|
}
|
|
"emscripten" {
|
|
$flags += " $WASM_FLAGS $BLOCKS_RT_FLAGS -DPLATFORM_WASM -DARCH_32"
|
|
}
|
|
default {
|
|
Write-Error "Unsupported operating system '$os'";
|
|
}
|
|
}
|
|
|
|
if ($release) {
|
|
$flags += " $RELEASE_FLAGS";
|
|
}
|
|
|
|
return $flags;
|
|
}
|
|
|
|
function GetSource($os) {
|
|
$source = $C_SOURCE;
|
|
switch ($os) {
|
|
"macos" {
|
|
# Do nothing here since macos already supports the blocks runtime
|
|
# and our local copy conflicts with the one shipped.
|
|
}
|
|
"windows" {
|
|
$source += " $BLOCKS_RT_SOURCE";
|
|
}
|
|
"linux" {
|
|
$source += " $BLOCKS_RT_SOURCE";
|
|
}
|
|
"emscripten" {
|
|
$source += " $BLOCKS_RT_SOURCE"
|
|
}
|
|
default {
|
|
Write-Error "Unsupported operating system '$os'";
|
|
}
|
|
}
|
|
return $source;
|
|
}
|
|
|
|
function CompileCommand($target_os, $release) {
|
|
return "$ZIG cc $(GetFlags $target_os $release) $(GetSource $target_os)";
|
|
}
|
|
|
|
# ..............
|
|
|
|
$command = $args[0];
|
|
$rest = $args[1..($args.Length-1)];
|
|
switch ($command) {
|
|
{($_ -eq "build") -or ($_ -eq "b")} {
|
|
$release = $rest[0] -eq "release" -or $rest[0] -eq "fast";
|
|
$cmd = "$(CompileCommand $HOST_OS $release) -o $(Join-Path $OUT_DIR $($EXE_NAME + (Get-Ext $HOST_OS)))";
|
|
|
|
Write-Host (":: Compiling natively" + $(if ($release) { " (release mode)" } else { "" }));
|
|
Write-Host $cmd;
|
|
|
|
Invoke-Expression $cmd | Write-Host;
|
|
}
|
|
{($_ -eq "build-cross") -or ($_ -eq "bc")} {
|
|
$target = $rest[0];
|
|
$rest = $rest[1..($rest.Length-1)];
|
|
$release = $rest[0] -eq "release" -or $rest[0] -eq "fast";
|
|
|
|
$target_os = ($target -split "-")[1];
|
|
if ($null -eq $target_os) {
|
|
Write-Error "Unsupported target '$target' - run list-targets to see possible targets";
|
|
}
|
|
|
|
$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")} {
|
|
$binary = Join-Path $OUT_DIR ($EXE_NAME + (Get-Ext $HOST_OS));
|
|
if (-not (Test-Path $binary)) {
|
|
$release = $rest[0] -eq "release" -or $rest[0] -eq "fast";
|
|
&"./do.ps1" build if ($release) { "release" } else { "" };
|
|
}
|
|
|
|
Invoke-Expression $binary | Write-Host;
|
|
}
|
|
{($_ -eq "run-wasm") -or ($_ -eq "rw")} {
|
|
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") -or ($_ -eq "l")} {
|
|
# 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-emscripten";
|
|
}
|
|
default {
|
|
Write-Host ":: Available things to do";
|
|
Write-Host " build (b) compiles the program natively";
|
|
Write-Host " build-cross (bc) <target> 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 (rw) 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;
|
|
}
|
|
}
|