Add macOS (arm64) support: build fixes, shared ANGLE, and native launcher - #111
Add macOS (arm64) support: build fixes, shared ANGLE, and native launcher#111jucardi wants to merge 8 commits into
Conversation
…arget First-ever compile of SimpleGraphic + native Lua modules for arm64-osx. Bounded, platform-guarded fixes surfaced by the build, each upstreamable: - CMakeLists.txt: build luasocket from usocket.c on non-Windows, guard the wsock32/ws2_32 link libs and LUA_BUILD_AS_DLL define to WIN32, name the four Lua modules "<name>.so" (not "lib<name>.dylib") so require() resolves them, select zstd::libzstd_shared vs zstd::libzstd depending on which target the triplet actually provides, add LIBRARY DESTINATION "." to every install(TARGETS ...) (Unix .dylib/.so are LIBRARY artifacts, not RUNTIME, so they were landing in dist/lib/ instead of dist/), and fix a bug where the WIN32/else block for SIMPLEGRAPHIC_PLATFORM_SOURCES overwrote rather than appended to the list, silently dropping sys_macos.mm on APPLE. - cmake/FindLuaJIT.cmake: extend the vcpkg-branch search paths/names for where vcpkg installs LuaJIT on macOS (include/luajit-2.1, libluajit-5.1.a). - vcpkg-ports/ports/luajit/2026-07-20_1/configure: add the executable bit (was committed 100644, so the port's ./configure failed with "Permission denied" on POSIX; Windows CI never runs this script). - vcpkg-ports/ports/luajit/2026-07-20_1/portfile.cmake: on non-Windows, copy the real luajit binary from the buildtree instead of the self-referential symlink make install leaves behind, so vcpkg_copy_tools can find it. - engine/common/base64.h, base64.c: add missing <stddef.h>/<string.h>. - engine/render/r_texture.cpp: add missing <thread>/<algorithm>; fix std::min(4ull, ...) template deduction failures where size_t is `unsigned long` (macOS) rather than `unsigned long long`. - engine/render/r_main.cpp: replace a bare Windows Sleep() call with the existing sys->Sleep() cross-platform abstraction already used elsewhere in this file. - engine/common/common.cpp: move IndexUTF8ToUTF32 out of the #ifdef _WIN32 block it was accidentally nested in - it has no Windows dependencies and is called from cross-platform code, but was undefined (and unlinkable) on non-Windows platforms. - libs/luautf8 (submodule commit): add missing <limits.h> for INT_MAX. - libs/Lua-cURLv3 (submodule commit): skip the luaL_setfuncs compat shim when building against LuaJIT, which already provides it - avoids a duplicate-symbol link error under static linkage. Verified: build/dist/ contains libSimpleGraphic.dylib, lcurl.so, lua-utf8.so, socket.so, lzip.so, all Mach-O arm64.
Adds macos/main.mm (pob CLI launcher) and the pob CMake target. Resolves the Lua entry script (CLI arg / POB_SCRIPT_PATH / compile-time default), sets up LuaJIT search paths relative to the executable, captures a pob:// launch URL via Apple Events, and hands off to SimpleGraphic's RunLuaFileAsWin. Discovery fix: kInternetEventClass/kAEGetURL are declared in ApplicationServices/HIServices/InternetConfig.h, not pulled in transitively by CoreServices.h on this SDK; added the explicit ApplicationServices import.
GLFW's Cocoa EGL backend loads EGL/GLESv2 at runtime via
dlopen("libEGL.dylib")/dlopen("libGLESv2.dylib") (egl_context.c), mirroring
the libEGL.dll/libGLESv2.dll pair shipped alongside the Windows build. Under
the arm64-osx triplet's static linkage, ANGLE was compiled directly into
libSimpleGraphic.dylib with no standalone dylib for GLFW to find, so window
creation failed at runtime ("Could not create window, EGL: Library not
found") followed by a segfault.
Adds an overlay triplet (triplets/arm64-osx.cmake, same name so every other
port cache-hits) that forces dynamic linkage for the angle port only. Wires
the overlay into CMakeLists.txt via VCPKG_OVERLAY_TRIPLETS, sets
SimpleGraphic's install rpath to @loader_path, and installs the built ANGLE
dylibs into the same directory as libSimpleGraphic.dylib, aliased to the
canonical libEGL.dylib/libGLESv2.dylib names GLFW dlopens (the vcpkg build
names them liblibEGL_angle.dylib/liblibGLESv2_angle.dylib).
Windows/Linux unaffected: the overlay directory defines no triplet for those
platforms.
The non-Windows fallback in pob-wide-crt.patch defined _lua_getenvcopy(name) as strdup(getenv(name)) unconditionally. getenv() returns NULL for an unset variable, and strdup(NULL) is undefined behavior — it segfaulted inside lj_cf_os_getenv (os.getenv from Lua) the first time PoB's Lua code queried an environment variable that wasn't set. The Windows path already guarded against this; the POSIX macro did not. Changed to (getenv(name) ? strdup(getenv(name)) : NULL), matching the Windows path's NULL-safety. Upstreamable: yes, trivial NULL-safety fix; submodule/port-patch scope only, no behavior change when the variable is actually set.
…install - Wrap VCPKG_OVERLAY_TRIPLETS in APPLE guard to avoid spurious triplet overrides - Extract EGL/GLESv2 dylib names dynamically from glob results instead of hardcoding - Add validation that both required dylibs are present; fail early if missing - Remove old symlinks before creating new ones for idempotent install - Update comment to reflect @rpath-based install names Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Revert the luautf8 and Lua-cURLv3 submodule pointers to their upstream commits and replace the in-submodule fixes with equivalents in this repo's build: - lua-utf8: force-include <limits.h> on non-Windows (INT_MAX use) - lcurl: rename its local Lua 5.2-compat luaL_setfuncs shim on non-Windows to avoid a duplicate symbol against static LuaJIT The proper fixes are PR'd upstream (starwing/luautf8#62, Lua-cURL/Lua-cURLv3#197); once merged, bump the submodules and drop these workarounds.
…ildingCommunity#102 Two fixes from nelkonandparker's macOS port (PathOfBuildingCommunity#102) that this branch lacked: - Scale cursor coordinates by the framebuffer/window-size ratio so clicks and tooltips align on HiDPI (Retina) displays; the ratio is 1.0 on Windows, leaving its behavior unchanged. - Explicitly select ANGLE's Metal backend on macOS (GLFW init hint, APPLE-guarded) and request the port's metal feature for osx in the vcpkg manifest. Co-authored-by: nelkonandparker <nelkonandparker@users.noreply.github.com>
|
Following up on the maintainer question about how this relates to the earlier macOS efforts (#101/#102) and #107 — I did a hunk-by-hunk comparison. Summary: Independently identical fixes (good sign for both): the What this PR has that #102 doesn't:
What #102 had that this PR lacked — now ported, with credit to @nelkonandparker (commit 8102dab):
Not ported (judgment calls, happy to discuss): #102's Re #107: its Windows-CI-as-release-gate idea is complementary — this repo's existing Windows CI running on this PR serves the same purpose, and I'm happy to add a macOS build job using GitHub's free arm64 runners so both platforms are machine-checked without any maintainer needing a Mac. 🤖 Generated with Claude Code |
Summary
Makes SimpleGraphic build and run on macOS (arm64) — the first working build of the
__APPLE__code paths that already exist in-tree — and adds the missing macOS launcher executable (counterpart of the Windows frontend).Build fixes (all platform-guarded or provably Windows-neutral)
usocket.con POSIX (wsocket.c/ws2_32are WIN32-guarded); Lua modules getPREFIX "" SUFFIX ".so"on non-Windows sorequirefinds them;sys_macos.mmis no longer clobbered out of the platform sources list (set→list(APPEND)bug); zstd link target selected by availability (libzstd_sharedvslibzstd— static triplets only build the latter);install(TARGETS … LIBRARY DESTINATION)added for dylibs.configureshim now carries its executable bit (chmod +x, was 644 — never noticed because Windows CI takes the nmake path); the make-path install leftbin/luajitas a self-referential symlink (the versioned binary it points at is never installed) — the port now copies the real binary from the build tree; the wide-CRT patch's POSIX fallback_lua_getenvcopywasstrdup(getenv(name))with no NULL check —os.getenv("UNSET")segfaulted; now NULL-guarded (the Windows path already was). This last one affects any future Linux build too.base64.c,r_texture.cpp, guarded);IndexUTF8ToUTF32moved out of an#ifdef _WIN32block it never belonged in (pure byte-decoding, three cross-platform call sites);std::mintype mismatch (4ull→size_t(4), no-op on Windows);Sleep(1)→sys->Sleep(1)inr_main.cpp— disclosure: this is the one unguarded shared-path edit; it switches Windows from raw::Sleepto the codebase's ownsysabstraction (std::this_thread::sleep_for), the same pattern used at every other call site.ANGLE as shared libraries on macOS
GLFW loads EGL at runtime via
dlopen("libEGL.dylib")— the macOS analogue of thelibEGL.dll/libGLESv2.dllpair shipped on Windows. A vcpkg overlay triplet (APPLE-only) keeps every dependency static except ANGLE; install aliases the ANGLE dylibs to the canonical names GLFW expects, with names derived from the build (configure fails loudly if the port's naming drifts).macOS launcher (
pob)New
macos/main.mm+ CMake target: resolves the Lua entry script (CLI arg →POB_SCRIPT_PATH→ compile-time default), sets exe-relativeLUA_PATH/LUA_CPATH(LuaJIT's macOS defaults have no exe-relative entries, unlike Windows), captures apob://launch URL via Apple Events (best-effort at launch; delivery to a running instance not implemented), and calls the exportedRunLuaFileAsWin. Consumed by PathOfBuildingCommunity/PathOfBuilding#10159.Submodules: stock, no pointer changes
This PR builds with the unmodified upstream submodules — no pointer bumps, nothing to fetch from forks. Two upstream issues surfaced on macOS are handled with small, guarded build-level workarounds in this repo's CMake (both marked with removal notes):
INT_MAXwithout including<limits.h>→ force-include on non-Windows. Proper fix PR'd upstream: starwing/luautf8#62.luaL_setfuncsshim collides with static LuaJIT's export → the shim is renamed via a compile definition on non-Windows. Proper fix PR'd upstream: Lua-cURL/Lua-cURLv3#197.If/when the upstream PRs merge, bump the submodules and drop the two workaround blocks.
Testing
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 -DVCPKG_TARGET_TRIPLET=arm64-osx, then build + install.🤖 Generated with Claude Code