diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e807bc4..a2e1b51 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,14 @@ jobs: steps: - name: Install dependencies run: | - brew install autoconf automake libtool pkg-config check cmake sdl3 + brew install autoconf automake libtool pkg-config check cmake + + - name: Build SDL3 + run: | + git clone --depth 1 --branch ObjectivelyGPU https://github.com/jdolan/SDL.git SDL3 + cmake -S SDL3 -B SDL3/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${HOMEBREW_PREFIX} + cmake --build SDL3/build -j$(sysctl -n hw.logicalcpu) + cmake --install SDL3/build - name: Checkout Objectively uses: actions/checkout@v6 @@ -67,7 +74,7 @@ jobs: - name: Build SDL3 run: | - git clone --depth 1 --branch release-3.4.12 https://github.com/libsdl-org/SDL.git SDL3 + git clone --depth 1 --branch ObjectivelyGPU https://github.com/jdolan/SDL.git SDL3 cmake -S SDL3 -B SDL3/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local cmake --build SDL3/build -j$(nproc) sudo cmake --install SDL3/build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 630924e..edff69c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ permissions: env: # Objectively is a source dependency (resolved via ObjectivelyGPU.xcworkspace). # Override to point a GPU release/branch at a specific Objectively ref. - # SDL3 / curl versions live in fetch-sdl3.sh / build-libcurl.sh, not here. + # SDL3 is the jdolan/SDL ObjectivelyGPU tag (fetch-sdl3.sh); curl lives in build-libcurl.sh. OBJECTIVELY_REF: "main" jobs: @@ -82,7 +82,6 @@ jobs: - name: Zip xcframeworks working-directory: ObjectivelyGPU/Frameworks run: | - zip -r "$GITHUB_WORKSPACE/SDL3.xcframework.zip" SDL3.xcframework zip -r "$GITHUB_WORKSPACE/ObjectivelyGPU.xcframework.zip" ObjectivelyGPU.xcframework - name: Create release @@ -92,7 +91,6 @@ jobs: gh release create ${{ github.ref_name }} \ --title "ObjectivelyGPU ${{ github.ref_name }}" \ --generate-notes \ - "$GITHUB_WORKSPACE/SDL3.xcframework.zip" \ "$GITHUB_WORKSPACE/ObjectivelyGPU.xcframework.zip" env: GH_TOKEN: ${{ github.token }} diff --git a/Documentation/install.md b/Documentation/install.md index 5e45718..1e3a170 100644 --- a/Documentation/install.md +++ b/Documentation/install.md @@ -14,6 +14,30 @@ Tagged releases are published on the [GitHub releases page](https://github.com/j * [Objectively](https://github.com/jdolan/Objectively) >= 2.0.0 * [SDL3](https://github.com/libsdl-org/SDL) >= 3.2.0 +### SDL3 and occlusion queries + +`QueryPool` requires the SDL_gpu query API (`SDL_GPU_QUERY_API`), which upstream SDL does not ship yet. The +`ObjectivelyGPU` tag in [jdolan/SDL](https://github.com/jdolan/SDL) carries it, and CI for ObjectivelyGPU, +ObjectivelyMVC and Quetoo MUST build against that tag. Against any other SDL3, ObjectivelyGPU still builds, but +`QueryPool.c` emits a compiler warning and occlusion queries are disabled. + +* Linux and macOS (autotools): build SDL from source with + `git clone --branch ObjectivelyGPU https://github.com/jdolan/SDL.git`. +* macOS and iOS (Xcode): `Frameworks/fetch-sdl3.sh` downloads `SDL3.xcframework` from the tag's release. It + records the tag's commit, and downloads again if the tag moves. +* Windows (Visual Studio): `ObjectivelyGPU.vs15/sdl3.targets` downloads `SDL3-devel-VC.zip` from the tag's + release on first build. Delete `ObjectivelyGPU.vs15/libs/` to pick up a moved tag. + +To change the SDL3 revision for the whole stack, move the tag, then publish its artifacts. The publish run +MUST finish before any consumer builds, because until then the release still serves the previous assets. +`fetch-sdl3.sh` refuses a release that was built from another commit. + +```sh +git tag -f ObjectivelyGPU && git push -f origin ObjectivelyGPU +gh workflow run objectivelygpu.yml -R jdolan/SDL +gh run watch -R jdolan/SDL --exit-status "$(gh run list -R jdolan/SDL -w objectivelygpu.yml -L 1 --json databaseId -q '.[0].databaseId')" +``` + ## Building ```sh diff --git a/Frameworks/fetch-sdl3.sh b/Frameworks/fetch-sdl3.sh index faabbd3..07edce1 100755 --- a/Frameworks/fetch-sdl3.sh +++ b/Frameworks/fetch-sdl3.sh @@ -1,40 +1,44 @@ #!/usr/bin/env bash # -# fetch-sdl3.sh — downloads the official SDL3 Apple xcframework from libsdl.org -# on demand and caches it under Frameworks/. +# fetch-sdl3.sh — downloads SDL3.xcframework from the jdolan/SDL release for SDL3_TAG and caches it +# under Frameworks/. # -# This mirrors the Windows VS build (ObjectivelyGPU.vs15/sdl3.targets): CI and -# local developers share a single code path. The download is cached at -# Frameworks/SDL3.xcframework.stable, and Frameworks/SDL3.xcframework is a -# symlink to it. This indirection lets link-sdl3-local.sh (and use-sdl3.sh) -# repoint that same symlink at a locally-built SDL3 checkout without disturbing -# this cache. Bump SDL3_VERSION to upgrade; delete -# Frameworks/SDL3.xcframework.stable to force a re-download. +# The whole stack (ObjectivelyGPU, ObjectivelyMVC, Quetoo) pins SDL3 to one tag in jdolan/SDL, which +# carries the SDL_gpu query API. The tag's commit SHA is stored next to the cache, so moving the tag +# causes a new download. The release notes name the commit its assets were built from; if that is +# not the tag's commit, the publish workflow has not run for the moved tag yet, and this script +# fails. This mirrors ObjectivelyGPU.vs15/sdl3.targets on Windows. # set -euo pipefail -SDL3_VERSION="${SDL3_VERSION:-3.4.2}" +SDL3_REPO="${SDL3_REPO:-jdolan/SDL}" +SDL3_TAG="${SDL3_TAG:-ObjectivelyGPU}" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -STABLE="$SCRIPT_DIR/SDL3.xcframework.stable" XCFRAMEWORK="$SCRIPT_DIR/SDL3.xcframework" +STAMP="$SCRIPT_DIR/SDL3.xcframework.sha" -# Migrate a pre-existing plain directory (from before the .stable split) in place. -if [ -d "$XCFRAMEWORK" ] && [ ! -L "$XCFRAMEWORK" ]; then - mv "$XCFRAMEWORK" "$STABLE" +sha="$(git ls-remote "https://github.com/$SDL3_REPO.git" "refs/tags/$SDL3_TAG" "refs/tags/$SDL3_TAG^{}" | tail -1 | cut -f1)" +if [ -z "$sha" ]; then + echo "error: tag $SDL3_TAG not found in $SDL3_REPO" >&2 + exit 1 fi -# Point the symlink at the stable cache, creating/replacing it as needed. -relink() { - ln -sfn "$(basename "$STABLE")" "$XCFRAMEWORK" +cached() { + [ -d "$XCFRAMEWORK" ] && [ ! -L "$XCFRAMEWORK" ] && [ "$(cat "$STAMP" 2>/dev/null)" = "$sha" ] } -# Already cached? Just make sure the symlink points at it and we're done. -if [ -d "$STABLE" ]; then - relink +if cached; then exit 0 fi +released="$(curl -fsSL "https://api.github.com/repos/$SDL3_REPO/releases/tags/$SDL3_TAG" | grep -Eo 'at [0-9a-f]{40}' | head -1 | cut -c4- || true)" +if [ "$released" != "$sha" ]; then + echo "error: the $SDL3_TAG release of $SDL3_REPO was built from ${released:-an unknown commit}, not $sha" >&2 + echo "error: run: gh workflow run objectivelygpu.yml -R $SDL3_REPO" >&2 + exit 1 +fi + # Serialize concurrent invocations (parallel target builds) on a lock dir, # the shell equivalent of the Global mutex used by sdl3.targets on Windows. LOCK="$SCRIPT_DIR/.sdl3.lock" @@ -53,17 +57,16 @@ cleanup() { trap cleanup EXIT # Re-check after acquiring the lock; another build may have just finished. -if [ -d "$STABLE" ]; then - relink +if cached; then exit 0 fi -DMG_URL="https://github.com/libsdl-org/SDL/releases/download/release-$SDL3_VERSION/SDL3-$SDL3_VERSION.dmg" +DMG_URL="https://github.com/$SDL3_REPO/releases/download/$SDL3_TAG/SDL3.dmg" -echo "==> Downloading SDL3 $SDL3_VERSION" +echo "==> Downloading SDL3 $SDL3_REPO@$SDL3_TAG ($sha)" curl -fL --retry 3 "$DMG_URL" -o "$TMP/SDL3.dmg" -echo "==> Mounting SDL3 $SDL3_VERSION" +echo "==> Mounting SDL3.dmg" mkdir -p "$MNT" hdiutil attach "$TMP/SDL3.dmg" -nobrowse -quiet -mountpoint "$MNT" @@ -73,8 +76,11 @@ if [ -z "$src" ]; then exit 1 fi +# Replace the cache, and the .stable/.local directories of the former use-sdl3.sh layout. echo "==> Caching SDL3.xcframework" -cp -R "$src" "$STABLE" -relink +rm -f "$STAMP" +rm -rf "$XCFRAMEWORK" "$SCRIPT_DIR/SDL3.xcframework.stable" "$SCRIPT_DIR/SDL3.xcframework.local" +cp -R "$src" "$XCFRAMEWORK" +echo "$sha" > "$STAMP" -echo "==> SDL3.xcframework $SDL3_VERSION ready at Frameworks/SDL3.xcframework" +echo "==> SDL3.xcframework $SDL3_TAG ready at Frameworks/SDL3.xcframework" diff --git a/Frameworks/link-sdl3-local.sh b/Frameworks/link-sdl3-local.sh deleted file mode 100755 index 4ad603f..0000000 --- a/Frameworks/link-sdl3-local.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env bash -# -# link-sdl3-local.sh — assembles Frameworks/SDL3.xcframework.local, an -# xcframework whose macOS slice is a live symlink into a locally-built SDL3 -# checkout, instead of the officially distributed binary cached by -# fetch-sdl3.sh. -# -# Defaults to Xcode/SDL/build/Release/SDL3.framework, produced by building the -# "SDL3" target/scheme in Xcode/SDL/SDL.xcodeproj with the Release -# configuration -- this is the same project, target, and configuration -# libsdl.org's own release process uses (see build-scripts/build-release.py's -# create_dmg() and build-scripts/release-info.json's "dmg" section), so it's -# the closest thing to a "vanilla local rebuild" of an official release, -# including your working-tree changes. If you build via CMake instead, point -# SDL3_LOCAL_BUILD at that framework instead. -# -# Because the macOS slice is a symlink (not a copy), rebuilding SDL3 in the -# local checkout is picked up immediately by Xcode -- there's no need to -# re-run this script after every SDL rebuild. Re-run it only if -# SDL3_LOCAL_BUILD's *path* changes, or after deleting -# Frameworks/SDL3.xcframework.local. -# -# Use use-sdl3.sh to toggle Frameworks/SDL3.xcframework between this and the -# official release fetched by fetch-sdl3.sh. -# -set -euo pipefail - -SDL3_LOCAL_BUILD="${SDL3_LOCAL_BUILD:-$HOME/Coding/SDL/Xcode/SDL/build/Release/SDL3.framework}" - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -STABLE="$SCRIPT_DIR/SDL3.xcframework.stable" -LOCAL="$SCRIPT_DIR/SDL3.xcframework.local" - -if [ ! -d "$SDL3_LOCAL_BUILD" ]; then - echo "error: $SDL3_LOCAL_BUILD not found (set SDL3_LOCAL_BUILD to override)" >&2 - exit 1 -fi - -# The official xcframework ships headers only at Headers/SDL3/*.h (so that a -# flat -I onto that Headers/ dir resolves the project's #include -# convention). A vanilla CMake-built SDL3.framework has no such nesting. -# Fix that up once, in place, with a self-referential symlink. "." is used -# (rather than an absolute/canonicalized path) so it resolves correctly -# regardless of the Headers/Versions/Current symlink chain used to reach it; -# macOS's BSD readlink has no reliable -f (canonicalize) flag to do that -# resolution ourselves. -HEADERS="$SDL3_LOCAL_BUILD/Headers" -if [ ! -e "$HEADERS/SDL_gpu.h" ]; then - echo "error: $HEADERS doesn't look like a built SDL3 framework (no SDL_gpu.h)." >&2 - echo " Is $SDL3_LOCAL_BUILD mid-rebuild? Finish 'cmake --build' there and re-run." >&2 - exit 1 -fi -if [ ! -e "$HEADERS/SDL3" ]; then - echo "==> Patching $HEADERS with a self-referential SDL3/ symlink" - ln -s . "$HEADERS/SDL3" -fi - -# The .stable cache is our template for Info.plist and the iOS slices, which -# the local checkout doesn't build. Make sure it exists. -[ -d "$STABLE" ] || "$SCRIPT_DIR/fetch-sdl3.sh" - -echo "==> Assembling Frameworks/SDL3.xcframework.local" -rm -rf "$LOCAL" -mkdir "$LOCAL" -cp "$STABLE/Info.plist" "$LOCAL/Info.plist" - -for slice in "$STABLE"/*/; do - slice="${slice%/}" - name="$(basename "$slice")" - case "$name" in - macos-*) - mkdir "$LOCAL/$name" - ln -s "$SDL3_LOCAL_BUILD" "$LOCAL/$name/SDL3.framework" - ;; - *) - # No local build for iOS/simulator slices; fall back to stable. - ln -s "../SDL3.xcframework.stable/$name" "$LOCAL/$name" - ;; - esac -done - -echo "==> Frameworks/SDL3.xcframework.local ready (macOS slice -> $SDL3_LOCAL_BUILD)" diff --git a/Frameworks/use-sdl3.sh b/Frameworks/use-sdl3.sh deleted file mode 100755 index 8e705bd..0000000 --- a/Frameworks/use-sdl3.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -# -# use-sdl3.sh — toggles Frameworks/SDL3.xcframework between the official -# stable release (fetch-sdl3.sh) and a locally-built SDL3 checkout -# (link-sdl3-local.sh). -# -# ObjectivelyGPU/Frameworks/SDL3.xcframework is the single copy of SDL3 that -# ObjectivelyGPU, ObjectivelyMVC, and Quetoo all link against (ObjectivelyMVC's -# own Frameworks/SDL3.xcframework is a symlink back to this one; Quetoo links -# this path directly). Running this script here is enough to flip SDL3 for -# all three projects at once -- nothing to run in the sibling repos. -# -# Usage: -# ./use-sdl3.sh stable # official release from libsdl.org (fetch-sdl3.sh) -# ./use-sdl3.sh local # your local SDL checkout (link-sdl3-local.sh) -# ./use-sdl3.sh # print which one is currently active -# -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -XCFRAMEWORK="$SCRIPT_DIR/SDL3.xcframework" - -status() { - if [ -L "$XCFRAMEWORK" ]; then - echo "SDL3.xcframework -> $(readlink "$XCFRAMEWORK")" - elif [ -d "$XCFRAMEWORK" ]; then - echo "SDL3.xcframework is a plain directory (not managed by use-sdl3.sh yet; run fetch-sdl3.sh)" - else - echo "SDL3.xcframework is not set up yet; run '$0 stable' or '$0 local'" - fi -} - -case "${1:-}" in - stable) - "$SCRIPT_DIR/fetch-sdl3.sh" - status - ;; - local) - "$SCRIPT_DIR/link-sdl3-local.sh" - ln -sfn SDL3.xcframework.local "$XCFRAMEWORK" - status - ;; - "") - status - ;; - *) - echo "usage: $0 [stable|local]" >&2 - exit 1 - ;; -esac diff --git a/ObjectivelyGPU.vs15/sdl3.targets b/ObjectivelyGPU.vs15/sdl3.targets index 912939e..fe261c8 100644 --- a/ObjectivelyGPU.vs15/sdl3.targets +++ b/ObjectivelyGPU.vs15/sdl3.targets @@ -2,15 +2,16 @@ - 3.4.12 - $(MSBuildThisFileDirectory)libs\SDL3-$(SDL3Version)\ + ObjectivelyGPU + $(MSBuildThisFileDirectory)libs\SDL3-$(SDL3Tag)\ x86 x64 @@ -23,9 +24,9 @@ - + + Command="powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference = 'Stop'; $m = New-Object System.Threading.Mutex($false, 'Global\ObjectivelySDL3'); [void]$m.WaitOne(); try { if (-not (Test-Path '$(SDL3Dir)include\SDL3\SDL.h')) { New-Item -ItemType Directory -Force libs | Out-Null; Invoke-WebRequest -Uri 'https://github.com/jdolan/SDL/releases/download/$(SDL3Tag)/SDL3-devel-VC.zip' -OutFile 'libs\sdl3.zip'; Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'libs\sdl3'; Expand-Archive -Force 'libs\sdl3.zip' 'libs\sdl3'; $d = %40(Get-ChildItem -Directory 'libs\sdl3'); if ($d.Count -ne 1) { throw 'SDL3-devel-VC.zip: expected one top-level directory' }; Remove-Item -Recurse -Force -ErrorAction SilentlyContinue '$(SDL3Dir.TrimEnd('\'))'; Move-Item $d[0].FullName '$(SDL3Dir.TrimEnd('\'))'; Remove-Item -Recurse 'libs\sdl3', 'libs\sdl3.zip' } } finally { $m.ReleaseMutex() }"" /> diff --git a/ObjectivelyGPU.xcodeproj/project.pbxproj b/ObjectivelyGPU.xcodeproj/project.pbxproj index ebe948c..174013b 100644 --- a/ObjectivelyGPU.xcodeproj/project.pbxproj +++ b/ObjectivelyGPU.xcodeproj/project.pbxproj @@ -202,8 +202,6 @@ CE1643412FF47B7D00863996 /* guide.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = guide.md; sourceTree = ""; }; CE1643422FF47B7D00863996 /* Hello.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = Hello.gif; sourceTree = ""; }; CE1643432FF47B7D00863996 /* HelloCompute.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = HelloCompute.gif; sourceTree = ""; }; - CE6049BB30055F5700B1C1E3 /* link-sdl3-local.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "link-sdl3-local.sh"; path = "Frameworks/link-sdl3-local.sh"; sourceTree = ""; }; - CE6049BC30055F5700B1C1E3 /* use-sdl3.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "use-sdl3.sh"; path = "Frameworks/use-sdl3.sh"; sourceTree = ""; }; CEA0030000000000000000F0 /* Objectively.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Objectively.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CEBA3F5E2FF30F1E00758CA6 /* Texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Texture.h; sourceTree = ""; }; CEBA3F5F2FF30F1E00758CA6 /* Texture.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Texture.c; sourceTree = ""; }; @@ -217,7 +215,7 @@ CEBA3F692FF3211F00758CA6 /* Shader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Shader.h; sourceTree = ""; }; CEBA3F6A2FF3211F00758CA6 /* Shader.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Shader.c; sourceTree = ""; }; CEBA3F742FF330A700758CA6 /* ComputePipeline.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ComputePipeline.c; sourceTree = ""; }; - CEBA3F7C2FF36E2300758CA6 /* fetch-sdl3.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "fetch-sdl3.sh"; sourceTree = ""; }; + CEBA3F7C2FF36E2300758CA6 /* fetch-sdl3.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = "fetch-sdl3.sh"; path = "Frameworks/fetch-sdl3.sh"; sourceTree = ""; }; CECF83942FEF65EB00CB0CCA /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; CECF83952FEF65FF00CB0CCA /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; CECF83962FEF65FF00CB0CCA /* ObjectivelyGPU.pc.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = ObjectivelyGPU.pc.in; sourceTree = ""; }; @@ -386,9 +384,7 @@ children = ( CEA0030000000000000000F0 /* Objectively.framework */, AA000000000000000000EE01 /* SDL3.xcframework */, - CE6049BB30055F5700B1C1E3 /* link-sdl3-local.sh */, CEBA3F7C2FF36E2300758CA6 /* fetch-sdl3.sh */, - CE6049BC30055F5700B1C1E3 /* use-sdl3.sh */, ); name = Frameworks; sourceTree = ""; diff --git a/Sources/ObjectivelyGPU/QueryPool.c b/Sources/ObjectivelyGPU/QueryPool.c index 4c9ea54..8f76421 100644 --- a/Sources/ObjectivelyGPU/QueryPool.c +++ b/Sources/ObjectivelyGPU/QueryPool.c @@ -26,6 +26,14 @@ #include "QueryPool.h" #include "RenderDevice.h" +#ifndef SDL_GPU_QUERY_API + #if defined(_MSC_VER) + #pragma message("SDL3 lacks SDL_GPU_QUERY_API: occlusion queries are disabled") + #else + #warning "SDL3 lacks SDL_GPU_QUERY_API: occlusion queries are disabled" + #endif +#endif + #define _Class _QueryPool #pragma mark - Object diff --git a/fetch-sdl3.sh b/fetch-sdl3.sh deleted file mode 100755 index d64a3a5..0000000 --- a/fetch-sdl3.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -# -# fetch-sdl3.sh — downloads the official SDL3 Apple xcframework from libsdl.org -# on demand and caches it under Frameworks/. -# -# This mirrors the Windows VS build (ObjectivelyGPU.vs15/sdl3.targets): CI and -# local developers share a single code path. SDL3.xcframework is downloaded -# once, on demand, and is .gitignored. Bump SDL3_VERSION to upgrade; delete -# Frameworks/SDL3.xcframework to force a re-download. -# -set -euo pipefail - -SDL3_VERSION="${SDL3_VERSION:-3.4.2}" - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -XCFRAMEWORK="$SCRIPT_DIR/SDL3.xcframework" - -# Already cached? Nothing to do. -[ -d "$XCFRAMEWORK" ] && exit 0 - -# Serialize concurrent invocations (parallel target builds) on a lock dir, -# the shell equivalent of the Global mutex used by sdl3.targets on Windows. -LOCK="$SCRIPT_DIR/.sdl3.lock" -while ! mkdir "$LOCK" 2>/dev/null; do - sleep 1 -done - -TMP="$(mktemp -d)" -MNT="$TMP/mnt" - -cleanup() { - hdiutil detach "$MNT" -quiet 2>/dev/null || true - rm -rf "$TMP" - rmdir "$LOCK" 2>/dev/null || true -} -trap cleanup EXIT - -# Re-check after acquiring the lock; another build may have just finished. -[ -d "$XCFRAMEWORK" ] && exit 0 - -DMG_URL="https://github.com/libsdl-org/SDL/releases/download/release-$SDL3_VERSION/SDL3-$SDL3_VERSION.dmg" - -echo "==> Downloading SDL3 $SDL3_VERSION" -curl -fL --retry 3 "$DMG_URL" -o "$TMP/SDL3.dmg" - -echo "==> Mounting SDL3 $SDL3_VERSION" -mkdir -p "$MNT" -hdiutil attach "$TMP/SDL3.dmg" -nobrowse -quiet -mountpoint "$MNT" - -src="$(find "$MNT" -maxdepth 2 -name SDL3.xcframework -type d | head -1)" -if [ -z "$src" ]; then - echo "error: SDL3.xcframework not found in $DMG_URL" >&2 - exit 1 -fi - -echo "==> Caching SDL3.xcframework" -cp -R "$src" "$XCFRAMEWORK" - -echo "==> SDL3.xcframework $SDL3_VERSION ready at Frameworks/SDL3.xcframework"