Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ set_target_properties(box2dxt PROPERTIES
OUTPUT_NAME "box2dxt"
)

# --- Linux loader assist (spike, opt-in) -----------------------------------
# Build the library under its BARE deploy name (box2dxt.so / box2dxt.dylib)
# instead of libbox2dxt.*. Dropping the prefix makes CMake stamp the ELF/Mach-O
# soname as "box2dxt.so" -- the exact name OXT hands to dlopen at run time.
# That match is what lets a script PRELOAD the file by absolute path (see
# b2LoadNativeLib in src/box2dxt.lcb) and have the engine's later bare-name
# bind resolve to the already-resident copy. glibc matches an already-loaded
# object by soname, NOT by filename, so renaming libbox2dxt.so -> box2dxt.so
# on disk is NOT enough; the soname has to be box2dxt.so too. As a bonus it
# removes the rename-on-deploy step. OFF keeps the historical libbox2dxt.*
# (rename-on-deploy) until the preload path is confirmed in OXT.
option(BOX2DXT_BARE_SONAME "Emit the library under its bare deploy name so its soname matches what OXT dlopens (Linux loader assist)" OFF)
if(BOX2DXT_BARE_SONAME)
set_target_properties(box2dxt PROPERTIES PREFIX "")
endif()

# Keep our own shim warning-clean (these flags apply only to box2d_lc.c).
if(MSVC)
target_compile_options(box2dxt PRIVATE /W3)
Expand Down
55 changes: 55 additions & 0 deletions src/box2dxt.lcb
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,25 @@ private foreign handler _query_normal_x(in pI as CInt) returns CDouble binds to
private foreign handler _query_normal_y(in pI as CInt) returns CDouble binds to "c:box2dxt>b2lc_query_normal_y!cdecl"
private foreign handler _query_fraction(in pI as CInt) returns CDouble binds to "c:box2dxt>b2lc_query_fraction!cdecl"

-- ---- native loader assist (Linux) ----------------------------------
-- The ONLY two bindings that do NOT target the box2dxt shim: they bind to
-- the platform's own dynamic loader (dlopen/dlerror), resolved from the
-- host process's global symbol table. That is the whole point -- they must
-- be callable BEFORE box2dxt.so is loadable, so a script can preload the
-- shim by absolute path. On Linux the engine hands the bare name
-- "box2dxt.so" to dlopen and never searches the stack's folder; preloading
-- the exact file first puts it in the process, so the engine's later
-- bare-name load finds the already-resident copy (matched by soname --
-- build with -DBOX2DXT_BARE_SONAME=ON so that soname is "box2dxt.so").
-- Bindings resolve on first use, so these are harmless dead weight on
-- Windows/macOS as long as nothing calls them there (the engine already
-- finds the library next to the stack on those platforms).
-- If OXT cannot bind "c:>dlopen", swap the empty library token for your
-- libc: glibc >= 2.34 -> "c:libc.so.6>dlopen!cdecl"; older glibc or where
-- dlopen still lives in libdl -> "c:libdl.so.2>dlopen!cdecl".
private foreign handler _dlopen(in pPath as ZStringNative, in pFlags as CInt) returns optional Pointer binds to "c:>dlopen!cdecl"
private foreign handler _dlerror() returns optional ZStringNative binds to "c:>dlerror!cdecl"

-- small bool -> int helper (no foreign call, so no unsafe needed)
private handler bi(in pB as Boolean) returns Integer
if pB then
Expand Down Expand Up @@ -475,6 +494,42 @@ private handler checkABI()
end if
end handler

-- ---- native loader assist -------------------------------------------
-- Preload the native shim by ABSOLUTE path so the engine's later bare-name
-- load resolves to the already-resident copy. Lets a Linux script point at
-- box2dxt.so sitting next to the stack (no /usr/lib, no sudo, no
-- LD_LIBRARY_PATH). Returns 1 on success, 0 on failure (then call
-- b2LoadNativeLibError for the reason). The library MUST have been built
-- with a soname of "box2dxt.so" (see -DBOX2DXT_BARE_SONAME) or the match
-- fails silently. Flags 258 = RTLD_NOW (2) | RTLD_GLOBAL (256) on Linux:
-- resolve every symbol now and expose them globally so the bare-name
-- bindings bind to them. Intended for Linux; gate the call to Linux when
-- wiring it into the Kit (the dlopen binding will not resolve on Windows).
public handler b2LoadNativeLib(in pPath as String) returns Integer
variable tHandle as optional Pointer
unsafe
put _dlopen(pPath, 258) into tHandle
end unsafe
if tHandle is nothing then
return 0
end if
return 1
end handler

-- The last loader error string ("" if none) -- makes a failed
-- b2LoadNativeLib self-diagnosing (wrong path vs. could-not-load) instead
-- of a bare 0.
public handler b2LoadNativeLibError() returns String
variable tErr as optional String
unsafe
put _dlerror() into tErr
end unsafe
if tErr is nothing then
return ""
end if
return tErr
end handler

-- ---- world ----------------------------------------------------------
public handler b2NewWorld(in pGravityX as Number, in pGravityY as Number, in pAllowSleep as Boolean, in pContinuous as Boolean) returns Integer
variable tR as Integer
Expand Down
Loading