diff --git a/.gitignore b/.gitignore index bc1869d..7786fbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .zed/ -out/ +out/p2601* thirdparty/blocksruntime thirdparty/zig* .DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..c33e0ea --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Huh + +Quick test to see how easy it easy to have a fully self-contained repository that bootstraps its build process. + +# Requirements + +[PowerShell](https://github.com/PowerShell/PowerShell/releases/tag/v7.5.4) (>= 7.5.4) + +# Building + +Run `pwsh do.ps1` to see a list of commands. +Run `pwsh do.ps1 run` to bootstrap, compile, and run the resulting program. diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..ff52938 --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,9 @@ +-I./src +-I./thirdparty/ +-I./thirdparty/blocksruntime/BlocksRuntime/ +-I./thirdparty/blocksruntime/ +--std=c2x +-fblocks + +-xobjective-c +-DPLATFORM_MACOS -DCHANGE_THESE_LINES_IF_YOURE_ON_A_DIFFERENT_PLATFORM diff --git a/do.ps1 b/do.ps1 new file mode 100755 index 0000000..bb520f7 --- /dev/null +++ b/do.ps1 @@ -0,0 +1,192 @@ +#!/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"; } + 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_REPO = "https://github.com/mackyle/blocksruntime.git"; +$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"); + +$C_SOURCE = "src/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"; + + +# 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 blocks runtime +if (-not (Test-Path $BLOCKS_RT_DIR)) { + Write-Host ":: Cloning libBlocksRuntime"; + git clone --depth 1 $BLOCKS_RT_REPO $BLOCKS_RT_DIR +} + +# ensure the out directory exists +New-Item -ItemType Directory -Force -Path $OUT_DIR | Out-Null; + + +# ............... + +function Get-Flags($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"; + } + default { + Write-Error "Unsupported operating system '$os'"; + } + } + + if ($release) { + $flags += " $RELEASE_FLAGS"; + } + + return $flags; +} + +function Get-Source($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"; + } + default { + Write-Error "Unsupported operating system '$os'"; + } + } + return $source; +} + +function CompileCommand($target_os, $release) { + return "$ZIG cc $(Get-Flags $target_os $release) $(Get-Source $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"; + } + + $cmd = "$(CompileCommand $target_os $release) --target=$target -o $(Join-Path $OUT_DIR $($EXE_NAME + (Get-Ext $target_os)))"; + + Write-Host (":: Cross-compiling for $target" + $(if ($release) { " (release mode)" } else { "" })); + Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; + } + {($_ -eq "run") -or ($_ -eq "r")} { + $release = $rest[0] -eq "release" -or $rest[0] -eq "fast"; + $binary = Join-Path $OUT_DIR ($EXE_NAME + (Get-Ext $HOST_OS)); + $cmd = "$(CompileCommand $HOST_OS $release) -o $binary"; + + Write-Host (":: Compiling natively" + $(if ($release) { " (release mode)" } else { "" })); + Write-Host $cmd; + Invoke-Expression $cmd | Write-Host; + Invoke-Expression $binary | Write-Host; + } + {($_ -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"; + } + 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 " list-targets (lt) lists all cross-compliation targets"; + return; + } +} diff --git a/justfile b/justfile deleted file mode 100644 index 6a1fd52..0000000 --- a/justfile +++ /dev/null @@ -1,146 +0,0 @@ -set windows-shell := ["powershell.exe", "-NoLogo", "-Command"] -set shell := ["bash", "-cu"] - -# configuration -project := "p2601" -out_dir := "out" -thirdparty := "thirdparty" - -# platform-specific -host_os := if os() == "macos" { "macos" } else { os() } -host_arch := arch() -exe := if os() == "windows" { ".exe" } else { "" } - -# zig stuff -zig_version := "0.15.2" -zig_slug := "zig-" + host_arch + "-" + host_os + "-" + zig_version -zig_dir := thirdparty / zig_slug -zig := zig_dir / ("zig" + exe) -zig_ext := if os() == "windows" { "zip" } else { "tar.xz" } -zig_url := "https://ziglang.org/download/" + zig_version + "/" + zig_slug + "." + zig_ext - -# blocks runtime -blocks_dir := thirdparty / "blocksruntime" -blocks_repo := "https://github.com/mackyle/blocksruntime.git" -# use the real blocks runtime if we're on mac -blocks_include := if os() == "macos" { "" } else { "-I" + blocks_dir / "BlocksRuntime" + " -I" + blocks_dir } -blocks_src := if os() == "macos" { "" } else { blocks_dir / "BlocksRuntime" / "runtime.c" + " " + blocks_dir / "BlocksRuntime" / "data.c" } - -# cflags -winflags := if os() == "windows" { "-ld3d11 -lgdi32" } else { "" } -macflags := if os() == "macos" { "-x objective-c -lobjc -framework Foundation -framework Cocoa -framework CoreFoundation -framework CoreGraphics -framework QuartzCore -framework Metal -framework MetalKit" } else { "" } -lnxflags := if os() == "linux" { "" } else { "" } -allflags := macflags + winflags + lnxflags - -csrc := "src/main.c" + " " + blocks_src -cinc := "-Isrc -Ithirdparty " + blocks_include -cflags := "-std=c23 -fblocks -g " + cinc - - - -# how the hotdog is made -# ---------------------- - -# platform-specific vendoring - -[unix] -[private] -vendor-zig: - #!/usr/bin/env bash - set -euo pipefail - [[ -x "{{zig}}" ]] && exit 0 - echo ":: Downloading Zig {{zig_version}} ({{host_os}}/{{host_arch}})…" - echo {{zig_url}} - mkdir -p "{{thirdparty}}" - curl -sSfL "{{zig_url}}" | tar -xJ -C "{{thirdparty}}" - -[windows] -[private] -vendor-zig: - #!powershell.exe - if (Test-Path "{{zig}}") { exit 0 } - Write-Host ":: Downloading Zig {{zig_version}} ({{host_os}}/{{host_arch}})..." - New-Item -ItemType Directory -Force -Path "{{thirdparty}}" | Out-Null - $tmp = Join-Path $env:TEMP "zig-vendor.zip" - Invoke-WebRequest -Uri "{{zig_url}}" -OutFile $tmp -UseBasicParsing - Expand-Archive -Path $tmp -DestinationPath "{{thirdparty}}" -Force - Remove-Item $tmp - -[unix] -[private] -vendor-blocks: - #!/usr/bin/env bash - set -euo pipefail - [[ -d "{{blocks_dir}}" ]] && exit 0 - echo ":: Cloning libBlocksRuntime…" - git clone --depth 1 "{{blocks_repo}}" "{{blocks_dir}}" - -[windows] -[private] -vendor-blocks: - #!powershell.exe - if (Test-Path "{{blocks_dir}}") { exit 0 } - Write-Host ":: Cloning libBlocksRuntime..." - git clone --depth 1 "{{blocks_repo}}" "{{blocks_dir}}" - -[doc("Pull in unversioned thirdparty dependencies")] -vendor: vendor-zig vendor-blocks - -# building/running - -[unix] -[private] -_mkout: - @mkdir -p "{{out_dir}}" - -[windows] -[private] -_mkout: - @New-Item -ItemType Directory -Force -Path "{{out_dir}}" | Out-Null - -[doc("Compile natively (debug)")] -[default] -build: vendor _mkout - {{zig}} cc {{cflags}} {{allflags}} {{csrc}} {{blocks_include}} -o {{out_dir}}/{{project}}{{exe}} - -[doc("Compile natively with optimizations")] -build-release: vendor _mkout - {{zig}} cc {{cflags}} {{allflags}} -Ofast -Wno-everything -ffast-math -DNDEBUG {{csrc}} {{blocks_include}} -o {{out_dir}}/{{project}}{{exe}} - -[doc("Compile for wasm32-wasi")] -build-wasm: vendor _mkout - {{zig}} cc {{cflags}} {{allflags}} -target wasm32-wasi {{csrc}} {{blocks_include}} -o {{out_dir}}/{{project}}.wasm - -[doc("Cross-compile for a Zig target triple (e.g. aarch64-linux-gnu)")] -build-cross target *args: vendor _mkout - {{zig}} cc {{cflags}} -target {{target}} {{csrc}} {{blocks_include}} -o {{out_dir}}/{{project}}-{{target}} {{args}} - -[doc("Build and run natively")] -run *args: build - @./{{out_dir}}/{{project}}{{exe}} {{args}} - -[doc("Build for wasm32-wasi and run via Wasmer")] -run-wasm *args: build-wasm - @wasmer run {{out_dir}}/{{project}}.wasm -- {{args}} - -# extras - -[doc("List Zig cross-compilation targets")] -list-targets: vendor-zig - {{zig}} targets - -[doc("List available just commands")] -list: - @just --list - -[doc("Remove build artifacts")] -[unix] -[confirm] -@clean: - rm -rf {{out_dir}} - -[doc("Remove build artifacts")] -[windows] -[confirm] -clean: - if (Test-Path "{{out_dir}}") { Remove-Item -Recurse -Force "{{out_dir}}" } diff --git a/out/.do_not_delete b/out/.do_not_delete new file mode 100644 index 0000000..e69de29 diff --git a/src/main.c b/src/main.c index 04e5f7a..9080e2c 100644 --- a/src/main.c +++ b/src/main.c @@ -4,10 +4,14 @@ #define SOKOL_IMPL #define SOKOL_NO_ENTRY -#ifdef __APPLE__ -#define SOKOL_METAL +#ifdef PLATFORM_WINDOWS + #define SOKOL_D3D11 +#elifdef PLATFORM_MACOS + #define SOKOL_METAL +#elifdef PLATFORM_LINUX + #define SOKOL_GLES3 #else -#define SOKOL_D3D11 + #error "unsupported platform" #endif #include "sokol/sokol_app.h"