diff --git a/.efrocachemap b/.efrocachemap
index 6b8f9e1d..c64dd4d4 100644
--- a/.efrocachemap
+++ b/.efrocachemap
@@ -4068,53 +4068,53 @@
"build/assets/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/2d/ef/5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/b0/8a/55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/86/5b/2af4d1e26a1a8073c89acb06e599",
- "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/bb/c7/4ef93af038e8d0e78e6bbf2d8ccd",
- "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/00/69/d9d791018f665d404d4a07f3b73f",
- "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/43/2d/00ead34e49771ecae25eee72a639",
- "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ab/41/21d782497286df6450d6e248bdf1",
- "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/80/6d/62ee994bd6ea597b57a456518ace",
- "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/da/82/493db6580f691ed32372644ecb49",
- "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7e/cf/9c8f54e170da2e8b4303f61f0257",
- "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2f/d8/b3da2bf81c5a1d1388085caf840d",
- "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/9b/5f/1f6c7b07de1000c279a0702a83bf",
- "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/f3/6f/9d86182a6a4677cdc9fd9c1f7f19",
- "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ec/fe/7fe44e1fefbb6325e466fb0278bc",
- "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/c7/db/2b3ca393aad03121e7fa5cccd604",
- "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/ac/fa/0ee96e9ab51427dd0a8eaaf55546",
- "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/64/fd/108739d12925982818c16e4f69cc",
- "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ba/65/d557f47ec557ff66d5077278947d",
- "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/5a/d2/fd994e6ab6ea8315b51db3cbb274",
- "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/ff/aa/390c8329a0a1245bb61b72cf607b",
- "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/eb/2d/9b7e35156943a56521ae9ad07bf0",
- "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/20/fe/7ee64a746e94fd32ac152ecb20b1",
- "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/12/ec/6115f93a4b254cf4fa82522ee10a",
- "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/4e/69/3d3715ffb88e61962dff80e52fa0",
- "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/df/78/f138dbf92a93dcd647831fb8fde4",
- "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/4e/69/3d3715ffb88e61962dff80e52fa0",
- "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/df/78/f138dbf92a93dcd647831fb8fde4",
- "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/4d/45/84cd8d36933f680c4c5ea6ed56e3",
- "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/31/e8/ebc78517b4f6c3dba799d96b6770",
- "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/4d/45/84cd8d36933f680c4c5ea6ed56e3",
- "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/31/e8/ebc78517b4f6c3dba799d96b6770",
- "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/16/31/fa50eca4cccba5819aba7598cdd2",
- "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/80/f5/1e75ca051bcc9cf5622443368820",
- "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/16/31/fa50eca4cccba5819aba7598cdd2",
- "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/80/f5/1e75ca051bcc9cf5622443368820",
- "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/34/26/fe4dacd23b76a39c024e220a6851",
- "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/84/7d/952ba7e47c98635853b6b3e046fa",
- "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/ad/de/141e3f5ea646f9d359a7edc40524",
- "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/84/7d/952ba7e47c98635853b6b3e046fa",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/23/f5/0cd5ec1a07a88f1ce69ffe46bbb4",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/6b/b7/0f20ebfc4aa3ce82b614f7c8553e",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/47/a1/87cfabb76c5af6922b36cae8585b",
- "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/5f/67/ca0e32734c731f1c1b6383f56aac",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/f3/e0/56006952bb54b29d7e6e319baa06",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/6a/fc/495578c6c0b4aea6b863be6dd367",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/5b/6a/e888f3a56a6b2af2ed638046767a",
- "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/d8/9a/6df73bd62b784c8ce277e0c704b4",
+ "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/43/bb/f3b6fb14420485630241bd274a38",
+ "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/c4/3f/63320f9c16adcbd31b7b6cb319a7",
+ "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/5f/7d/b5487416ecf67311f555440eb0f7",
+ "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/94/26/f73beeec4e0aa810f6b53cf03b09",
+ "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/c0/73/01d793d8bdac3cdcb283cff8926a",
+ "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/18/2e/991e4832cba394133a81a015d77c",
+ "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/ef/77/96846f61fd0d213103def1d52b29",
+ "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/05/e9/749f0b02f10682dc8fa53166f633",
+ "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/4d/2e/4d2c8b42b702472b771ff39fa172",
+ "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/86/fe/2f8bfb8e724da409f22b169b45e0",
+ "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/09/52/0357755448188a270c314cb87b15",
+ "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/d0/be/2f53922bc6a539c39cf43f777537",
+ "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/23/df/36ebc5359eed5cff6b1c8e2d2b16",
+ "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/e9/92/e2ca53a5a9ead72d55fde408c6f2",
+ "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/3d/36/e9d0ad1f63c2c4566ea3f26bea72",
+ "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/39/8b/74a52274ca432a4aedda6341ca78",
+ "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/a4/ee/be57b1e322c830df0bcd0591bf11",
+ "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/0e/6f/ab42d4dd63dc057445a8a97b29ea",
+ "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/51/a4/1635aa809982cb1df226e0db12ee",
+ "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/fb/ec/5dcb24d613b2c0913123c9dfa5c9",
+ "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/b3/a2/5da0c4dc65f469e4a476e0395eb5",
+ "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/a9/9a/adb83188f9c7d7b51dafd0f8b8a8",
+ "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/b3/a2/5da0c4dc65f469e4a476e0395eb5",
+ "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/a9/9a/adb83188f9c7d7b51dafd0f8b8a8",
+ "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/27/f4/269f5d37a8e3938c0acdab299833",
+ "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/7b/f3/f98278c9654a972baf65d5f04c12",
+ "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/27/f4/269f5d37a8e3938c0acdab299833",
+ "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/7b/f3/f98278c9654a972baf65d5f04c12",
+ "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/c7/a2/40728a3ebfb3006c7a47b698214f",
+ "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/84/19/a1bbbf42c50329f0cd1377d103bb",
+ "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/c7/a2/40728a3ebfb3006c7a47b698214f",
+ "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/84/19/a1bbbf42c50329f0cd1377d103bb",
+ "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/53/e4/455c68ee50813fe89e3002cf1fe8",
+ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/59/fe/a3e369f2db87a305641e74ae70ab",
+ "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/be/df/60063a6845e8654958f1a3e37867",
+ "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "https://files.ballistica.net/cache/ba1/59/fe/a3e369f2db87a305641e74ae70ab",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/91/9a/8b2f4a2f0ffc38128512a7b77498",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/4e/5f/96bad4aad35e8c50111a88bdca3c",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/bb/6a/85a98907597e4a2d2b312c0d2a1d",
+ "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/2e/f7/0252c1e7f9edc0e55423dcf91953",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/f0/78/e5d8083aac564b5993aac16832bf",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/10/e8/6abb7ac9d3425ddf295cf867e7eb",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/16/5a/174c7c46187abc923655fda133ea",
+ "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/6d/f3/074bc3f3a466ca0dbec3b18acf76",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/f8/85/fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/f8/cd/3af311ac63147882590123b78318",
- "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/3e/7a/203e2a5d2b5bb42cfe3fd2fe16c2",
+ "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/ee/dd/ad968b176000e31c65be6206a2bc",
"src/ballistica/base/mgen/pyembed/binding_base_app.inc": "https://files.ballistica.net/cache/ba1/c2/f2/cb8d052d76a1f4abe163cab2276e",
"src/ballistica/classic/mgen/pyembed/binding_classic.inc": "https://files.ballistica.net/cache/ba1/3c/eb/412513963f0818ab39c58bf292e3",
"src/ballistica/core/mgen/pyembed/binding_core.inc": "https://files.ballistica.net/cache/ba1/9d/0a/3c9636138e35284923e0c8311c69",
diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml
index 1fc38916..4f4cc54f 100644
--- a/.idea/dictionaries/ericf.xml
+++ b/.idea/dictionaries/ericf.xml
@@ -538,8 +538,10 @@
cmodel
cmodule
cmodules
+ cmpbd
cmpf
cmplen
+ cmpnf
cnode
codecsmodule
codedata
@@ -1737,6 +1739,7 @@
maxw
maxwait
maxwidth
+ mbname
mbstowcs
mbytecount
mdiv
@@ -1778,6 +1781,7 @@
miniplayer
minlog
minping
+ minsizerel
minusbutton
minval
minver
@@ -2434,6 +2438,7 @@
reimported
relfut
relpath
+ relwithdebinfo
remainingchecks
remoteapp
rendertarget
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a5b3bc9e..f9adce9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-### 1.7.24 (build 21188, api 8, 2023-07-22)
+### 1.7.24 (build 21195, api 8, 2023-07-25)
- Due to the cleanup done in 1.7.20, it is now possible to build and run
Ballistica as a 'pure' Python app consisting of binary Python modules loaded
@@ -11,6 +11,13 @@
default for certain situations such as server builds or possibly Linux builds
if it seems beneficial. We'll see. Modular mode should work on Linux and Mac
currently; other platforms remain monolithic-only for now.
+- Changed builds such as `cmake` and `cmake-server` to be more like the new
+ `cmake-monolithic` setup; there is now a `staged` dir that built binaries are
+ symlinked into instead of just dumping a `ba_data` into the cmake build dir.
+ This keeps things a bit cleaner with fewer build-related files interspersed
+ with the stuff that Ballistica expects to be there at runtime. This also
+ allows an elegant `-dist` flag to be used with the staging command to copy
+ files instead of symlinking them.
- Changed path wrangling a bit in baenv.py. All ballistica Python paths
(including python-site-packages) are now placed before any other existing
Python paths. This should provide a more consistent environment and means
@@ -29,11 +36,14 @@
-win-Win32 -debug .`. Please holler if you run into any broken asset-staging
calls in the Makefile/etc.
- `FeatureSet.has_native_python_module` has been renamed to
- `FeatureSet.has_python_binary_module` for better consistency with related
+ `FeatureSet.has_python_binary_module` to be more consistently with related
functionality.
- Renamed `stage_assets` to `stage_build` and the module it lives in from
`assetstaging` to simply `staging`. The staging stuff now covers more things
than simply asset files so this is a more accurate name.
+- Added `babase.fatal_error()`. Mod code should generally never use this, but it
+ can be useful for core engine code to directly and clearly point out problems
+ that cannot be recovered from.
### 1.7.23 (build 21178, api 8, 2023-07-19)
diff --git a/Makefile b/Makefile
index b5007ca9..e1967dc3 100644
--- a/Makefile
+++ b/Makefile
@@ -1005,29 +1005,32 @@ windows-clean-list:
# Set the following from the command line to influence the build:
-# This can be Debug or Release.
+# This can be Debug, Release, RelWithDebInfo, or MinSizeRel.
CMAKE_BUILD_TYPE ?= Debug
# Build and run the cmake build.
cmake: cmake-build
- @cd build/cmake/$(CM_BT_LC) && ./ballisticakit
+ @cd build/cmake/$(CM_BT_LC)/staged && ./ballisticakit
# Build and run the cmake build under the gdb debugger.
# Sets up the ballistica environment to do things like abort() out to the
# debugger on errors instead of trying to cleanly exit.
cmake-gdb: cmake-build
- @cd build/cmake/$(CM_BT_LC) && BA_DEBUGGER_ATTACHED=1 gdb ./ballisticakit
+ @cd build/cmake/$(CM_BT_LC)/staged && \
+ BA_DEBUGGER_ATTACHED=1 gdb ./ballisticakit
# Build and run the cmake build under the lldb debugger.
# Sets up the ballistica environment to do things like abort() out to the
# debugger on errors instead of trying to cleanly exit.
cmake-lldb: cmake-build
- @cd build/cmake/$(CM_BT_LC) && BA_DEBUGGER_ATTACHED=1 lldb ./ballisticakit
+ @cd build/cmake/$(CM_BT_LC)/staged && \
+ BA_DEBUGGER_ATTACHED=1 lldb ./ballisticakit
# Build but don't run it.
cmake-build: assets-cmake resources cmake-binary
- @$(STAGE_BUILD) -cmake -$(CM_BT_LC) build/cmake/$(CM_BT_LC)
- @tools/pcommand echo BLD Build complete: BLU build/cmake/$(CM_BT_LC)
+ @$(STAGE_BUILD) -cmake -$(CM_BT_LC) -builddir build/cmake/$(CM_BT_LC) \
+ build/cmake/$(CM_BT_LC)/staged
+ @tools/pcommand echo BLD Build complete: BLU build/cmake/$(CM_BT_LC)/staged
cmake-binary: meta
@tools/pcommand cmake_prep_dir build/cmake/$(CM_BT_LC)
@@ -1041,21 +1044,22 @@ cmake-clean:
rm -rf build/cmake/$(CM_BT_LC)
cmake-server: cmake-server-build
- @cd build/cmake/server-$(CM_BT_LC) && ./ballisticakit_server
+ @cd build/cmake/server-$(CM_BT_LC)/staged && ./ballisticakit_server
cmake-server-build: assets-server meta cmake-server-binary
- @$(STAGE_BUILD) -cmakeserver -$(CM_BT_LC) build/cmake/server-$(CM_BT_LC)
+ @$(STAGE_BUILD) -cmakeserver -$(CM_BT_LC) \
+ -builddir build/cmake/server-$(CM_BT_LC) \
+ build/cmake/server-$(CM_BT_LC)/staged
@tools/pcommand echo BLD \
- Server build complete: BLU build/cmake/server-$(CM_BT_LC)
+ Server build complete: BLU build/cmake/server-$(CM_BT_LC)/staged
cmake-server-binary: meta
- @tools/pcommand cmake_prep_dir build/cmake/server-$(CM_BT_LC)/dist
- @cd build/cmake/server-$(CM_BT_LC)/dist && test -f Makefile \
+ @tools/pcommand cmake_prep_dir build/cmake/server-$(CM_BT_LC)
+ @cd build/cmake/server-$(CM_BT_LC) && test -f Makefile \
|| cmake -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) -DHEADLESS=true \
$(shell pwd)/ballisticakit-cmake
- @tools/pcommand update_cmake_prefab_lib server $(CM_BT_LC) build/cmake/server-$(CM_BT_LC)/dist
- @cd build/cmake/server-$(CM_BT_LC)/dist && $(MAKE) -j$(CPUS) \
- ballisticakitbin
+ @tools/pcommand update_cmake_prefab_lib server $(CM_BT_LC) build/cmake/server-$(CM_BT_LC)
+ @cd build/cmake/server-$(CM_BT_LC) && $(MAKE) -j$(CPUS) ballisticakitbin
cmake-server-clean:
rm -rf build/cmake/server-$(CM_BT_LC)
diff --git a/ballisticakit-cmake/.idea/dictionaries/ericf.xml b/ballisticakit-cmake/.idea/dictionaries/ericf.xml
index 9955c59e..17b0f860 100644
--- a/ballisticakit-cmake/.idea/dictionaries/ericf.xml
+++ b/ballisticakit-cmake/.idea/dictionaries/ericf.xml
@@ -337,7 +337,9 @@
cmesh
cmodule
cmodules
+ cmpbd
cmplen
+ cmpnf
codedata
codewarrior
codewarrior's
@@ -1014,6 +1016,7 @@
maxtries
maxwait
maxwidth
+ mbname
mbstowcs
mdpath
mediump
@@ -1042,6 +1045,7 @@
minlog
minping
minsdl
+ minsizerel
mipmapcount
mipmaps
mkflags
@@ -1435,6 +1439,7 @@
reimported
relfut
reloadmedia
+ relwithdebinfo
rendererdata
rendertarget
renormalize
diff --git a/ballisticakit-cmake/.idea/runConfigurations/ballisticakit.xml b/ballisticakit-cmake/.idea/runConfigurations/ballisticakit.xml
deleted file mode 100644
index 2e94e7a1..00000000
--- a/ballisticakit-cmake/.idea/runConfigurations/ballisticakit.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/config/toolconfigsrc/dir-locals.el b/config/toolconfigsrc/dir-locals.el
index 099927ae..30c7cf5a 100644
--- a/config/toolconfigsrc/dir-locals.el
+++ b/config/toolconfigsrc/dir-locals.el
@@ -5,8 +5,11 @@
((c++-mode (eval . (flycheck-mode)))
- (python-mode (jedi:server-args . ("--sys-path" "__EFRO_PROJECT_ROOT__/tools"
- "--sys-path" "__EFRO_PROJECT_ROOT__/src/assets/ba_data/python"))
+ (python-ts-mode (jedi:server-args . ("--sys-path" "__EFRO_PROJECT_ROOT__/tools"
+ "--sys-path" "__EFRO_PROJECT_ROOT__/src/assets/ba_data/python"
+ "--sys-path" "__EFRO_PROJECT_ROOT__/build/dummymodules"
+ ;; "--log-level" "DEBUG" "--log" "/Users/ericf/Desktop/jedilog"
+ ))
(python-black-extra-args . __PYTHON_BLACK_EXTRA_ARGS__))
;; Shorter name in projectile status bar to save valuable space.
diff --git a/src/assets/ba_data/python/babase/__init__.py b/src/assets/ba_data/python/babase/__init__.py
index c5e0e436..52bf7cb5 100644
--- a/src/assets/ba_data/python/babase/__init__.py
+++ b/src/assets/ba_data/python/babase/__init__.py
@@ -1,10 +1,11 @@
# Released under the MIT License. See LICENSE for details.
#
-"""Common shared ballistica components.
+"""Common shared Ballistica components.
-Often this package does not need to be used directly. Instead one can
-use versioned packages such as bascenev1 or bauiv1 which reexpose a more
-focused set of the stuff contained here.
+For modding purposes, this package should generally not be used directly.
+Instead one should use purpose-built packages such as bascenev1 or bauiv1
+which themselves import various functionality from here and reexpose it in
+a more focused way.
"""
# pylint: disable=redefined-builtin
@@ -38,6 +39,7 @@ from _babase import (
do_once,
env,
fade_screen,
+ fatal_error,
get_display_resolution,
get_low_level_config_value,
get_max_graphics_quality,
@@ -199,6 +201,7 @@ __all__ = [
'Existable',
'existing',
'fade_screen',
+ 'fatal_error',
'garbage_collect',
'get_display_resolution',
'get_ip_address_type',
diff --git a/src/assets/ba_data/python/babase/_apputils.py b/src/assets/ba_data/python/babase/_apputils.py
index 90896dc1..67aa9cf0 100644
--- a/src/assets/ba_data/python/babase/_apputils.py
+++ b/src/assets/ba_data/python/babase/_apputils.py
@@ -443,42 +443,3 @@ class AppHealthMonitor(AppSubsystem):
def on_app_resume(self) -> None:
assert _babase.in_logic_thread()
self._running = True
-
-
-def on_too_many_file_descriptors() -> None:
- """Called when too many file descriptors are open; trying to debug."""
-
- real_time = _babase.apptime()
-
- def _do_log() -> None:
- pid = os.getpid()
- try:
- fdcount: int | str = len(os.listdir(f'/proc/{pid}/fd'))
- except Exception as exc:
- fdcount = f'? ({exc})'
- logging.warning(
- 'TOO MANY FDS at %.2f. We are pid %d. FDCount is %s.',
- real_time,
- pid,
- fdcount,
- )
-
- Thread(target=_do_log, daemon=True).start()
-
- # import io
- # from efro.debug import printtypes
-
- # with io.StringIO() as fstr:
- # fstr.write('Too many FDs.\n')
- # printtypes(file=fstr)
- # fstr.seek(0)
- # logging.warning(fstr.read())
- # import socket
-
- # objs: list[Any] = []
- # for obj in gc.get_objects():
- # if isinstance(obj, socket.socket):
- # objs.append(obj)
- # test = open('/Users/ericf/.zshrc', 'r', encoding='utf-8')
- # reveal_type(test)
- # print('FOUND', len(objs))
diff --git a/src/assets/ba_data/python/babase/_env.py b/src/assets/ba_data/python/babase/_env.py
index 9fabca2c..08b13d3b 100644
--- a/src/assets/ba_data/python/babase/_env.py
+++ b/src/assets/ba_data/python/babase/_env.py
@@ -19,7 +19,12 @@ _g_babase_app_started = False # pylint: disable=invalid-name
def on_native_module_import() -> None:
- """Called by _babase when it is imported; does some sanity checking/etc."""
+ """Called when _babase is being imported.
+
+ This code should do as little as possible; we want to defer all
+ environment modifications until we actually commit to running an
+ app.
+ """
import _babase
import baenv
@@ -28,7 +33,8 @@ def on_native_module_import() -> None:
assert not _g_babase_imported
_g_babase_imported = True
- # If we have a log_handler set up, wire it up to feed _babase its output.
+ # If we have a log_handler set up, wire it up to feed _babase its
+ # output.
envconfig = baenv.get_config()
if envconfig.log_handler is not None:
_feed_logs_to_babase(envconfig.log_handler)
@@ -63,8 +69,13 @@ def on_native_module_import() -> None:
)
-def setup_env_for_app_run() -> None:
- """Set stuff such as interrupt handlers for a run of the app."""
+def on_main_thread_start_app() -> None:
+ """Called in the main thread when we're starting an app.
+
+ We use this opportunity to set up the Python runtime environment
+ as we like it for running our app stuff. This includes things like
+ signal-handling, garbage-collection, and logging.
+ """
import gc
import baenv
import _babase
@@ -145,7 +156,7 @@ def on_app_launching() -> None:
assert _babase.in_logic_thread()
- # Let the user know if the app python dir is a custom one.
+ # Let the user know if the app Python dir is a custom one.
user_sys_scripts_dir = baenv.get_user_system_scripts_dir()
if user_sys_scripts_dir is not None:
_babase.screenmessage(
diff --git a/src/assets/ba_data/python/babase/_hooks.py b/src/assets/ba_data/python/babase/_hooks.py
index 68d8f028..8b35d67a 100644
--- a/src/assets/ba_data/python/babase/_hooks.py
+++ b/src/assets/ba_data/python/babase/_hooks.py
@@ -149,16 +149,6 @@ def purchase_already_in_progress_error() -> None:
)
-def gear_vr_controller_warning() -> None:
- from babase._language import Lstr
-
- if not _babase.app.headless_mode:
- _babase.getsimplesound('error').play()
- _babase.screenmessage(
- Lstr(resource='usesExternalControllerText'), color=(1, 0, 0)
- )
-
-
def uuid_str() -> str:
import uuid
@@ -249,12 +239,6 @@ def set_last_ad_network(sval: str) -> None:
_babase.app.classic.ads.last_ad_network_set_time = time.time()
-def no_game_circle_message() -> None:
- from babase._language import Lstr
-
- _babase.screenmessage(Lstr(resource='noGameCircleText'), color=(1, 0, 0))
-
-
def google_play_purchases_not_available_message() -> None:
from babase._language import Lstr
diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py
index bfb35009..de491631 100644
--- a/src/assets/ba_data/python/baenv.py
+++ b/src/assets/ba_data/python/baenv.py
@@ -51,7 +51,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be
# using.
-TARGET_BALLISTICA_BUILD = 21188
+TARGET_BALLISTICA_BUILD = 21195
TARGET_BALLISTICA_VERSION = '1.7.24'
diff --git a/src/ballistica/base/networking/network_reader.cc b/src/ballistica/base/networking/network_reader.cc
index 62f53f3a..0b538acd 100644
--- a/src/ballistica/base/networking/network_reader.cc
+++ b/src/ballistica/base/networking/network_reader.cc
@@ -133,7 +133,6 @@ void NetworkReader::DoSelect(bool* can_read_4, bool* can_read_6) {
// Try to get a clean error instead of a crash if we exceed our
// open file descriptor limit (except on windows where FD_SETSIZE
// is apparently a dummy value).
- CheckFDThreshold(sd4_);
if (sd4_ < 0 || sd4_ >= FD_SETSIZE) {
FatalError("Socket/File Descriptor Overflow (sd4="
+ std::to_string(sd4_) + ", FD_SETSIZE="
@@ -148,7 +147,6 @@ void NetworkReader::DoSelect(bool* can_read_4, bool* can_read_6) {
// Try to get a clean error instead of a crash if we exceed our
// open file descriptor limit (except on windows where FD_SETSIZE
// is apparently a dummy value).
- CheckFDThreshold(sd6_);
if (sd6_ < 0 || sd6_ >= FD_SETSIZE) {
FatalError("Socket/File Descriptor Overflow (sd6="
+ std::to_string(sd6_) + ", FD_SETSIZE="
@@ -174,27 +172,6 @@ void NetworkReader::DoSelect(bool* can_read_4, bool* can_read_6) {
}
}
-void NetworkReader::CheckFDThreshold(int val) {
- if (passed_fd_threshold_) {
- return;
- }
-
- // Let's trigger when we pass 2/3 of the FD limit.
- if (val < FD_SETSIZE * 2 / 3) {
- return;
- }
-
- // If we pass the threshold, do a one-time dump of info
- // to try and debug it.
- passed_fd_threshold_ = true;
- g_base->logic->event_loop()->PushCall([] {
- assert(g_base->InLogicThread());
- g_base->python->objs()
- .Get(BasePython::ObjID::kOnTooManyFileDescriptorsCall)
- .Call();
- });
-}
-
auto NetworkReader::RunThread() -> int {
if (!g_core->HeadlessMode()) {
remote_server_ = std::make_unique();
diff --git a/src/ballistica/base/networking/network_reader.h b/src/ballistica/base/networking/network_reader.h
index d5e81c22..1b2c9ede 100644
--- a/src/ballistica/base/networking/network_reader.h
+++ b/src/ballistica/base/networking/network_reader.h
@@ -33,7 +33,6 @@ class NetworkReader {
auto sd6() const { return sd6_; }
private:
- void CheckFDThreshold(int val);
void DoSelect(bool* can_read_4, bool* can_read_6);
void DoPoll(bool* can_read_4, bool* can_read_6);
void OpenSockets();
diff --git a/src/ballistica/base/python/base_python.cc b/src/ballistica/base/python/base_python.cc
index 1423a61f..2386ce41 100644
--- a/src/ballistica/base/python/base_python.cc
+++ b/src/ballistica/base/python/base_python.cc
@@ -136,10 +136,10 @@ void BasePython::OnMainThreadStartApp() {
auto gil{Python::ScopedInterpreterLock()};
// Set up some env stuff (interrupt handlers, etc.)
auto result = g_base->python->objs()
- .Get(BasePython::ObjID::kSetupEnvForAppRunCall)
+ .Get(BasePython::ObjID::kOnMainThreadStartAppCall)
.Call();
if (!result.Exists()) {
- FatalError("babase._env.setup_env_for_app_run() failed.");
+ FatalError("babase._env.on_main_thread_start_app() failed.");
}
}
diff --git a/src/ballistica/base/python/base_python.h b/src/ballistica/base/python/base_python.h
index b9b8df23..b912402f 100644
--- a/src/ballistica/base/python/base_python.h
+++ b/src/ballistica/base/python/base_python.h
@@ -48,7 +48,6 @@ class BasePython {
kErrorMessageCall,
kPurchaseNotValidErrorCall,
kPurchaseAlreadyInProgressErrorCall,
- kGearVRControllerWarningCall,
kVROrientationResetCBMessageCall,
kVROrientationResetMessageCall,
kHandleV1CloudLogCall,
@@ -62,7 +61,6 @@ class BasePython {
kDismissWiiRemotesWindowCall,
kUnavailableMessageCall,
kSetLastAdNetworkCall,
- kNoGameCircleMessageCall,
kGooglePlayPurchasesNotAvailableMessageCall,
kGooglePlayServicesNotAvailableMessageCall,
kEmptyCall,
@@ -98,11 +96,10 @@ class BasePython {
kImplicitSignInCall,
kImplicitSignOutCall,
kLoginAdapterGetSignInTokenResponseCall,
- kOnTooManyFileDescriptorsCall,
kPreEnv,
kOpenURLWithWebBrowserModuleCall,
kOnNativeModuleImportCall,
- kSetupEnvForAppRunCall,
+ kOnMainThreadStartAppCall,
kPushApplyAppConfigCall,
kLast // Sentinel; must be at end.
};
diff --git a/src/ballistica/base/python/methods/python_methods_misc.cc b/src/ballistica/base/python/methods/python_methods_misc.cc
index 8a19a481..8dbc6b6f 100644
--- a/src/ballistica/base/python/methods/python_methods_misc.cc
+++ b/src/ballistica/base/python/methods/python_methods_misc.cc
@@ -1254,31 +1254,6 @@ static PyMethodDef PyAndroidGetExternalFilesDirDef = {
#pragma clang diagnostic pop
-// --------------------- android_show_wifi_settings ----------------------------
-
-static auto PyAndroidShowWifiSettings(PyObject* self, PyObject* args,
- PyObject* keywds) -> PyObject* {
- BA_PYTHON_TRY;
- static const char* kwlist[] = {nullptr};
- if (!PyArg_ParseTupleAndKeywords(args, keywds, "",
- const_cast(kwlist))) {
- return nullptr;
- }
- g_core->platform->AndroidShowWifiSettings();
- Py_RETURN_NONE;
- BA_PYTHON_CATCH;
-}
-
-static PyMethodDef PyAndroidShowWifiSettingsDef = {
- "android_show_wifi_settings", // name
- (PyCFunction)PyAndroidShowWifiSettings, // method
- METH_VARARGS | METH_KEYWORDS, // flags
-
- "android_show_wifi_settings() -> None\n"
- "\n"
- "(internal)",
-};
-
// ------------------------------- do_once -------------------------------------
static auto PyDoOnce(PyObject* self, PyObject* args, PyObject* keywds)
@@ -1445,6 +1420,36 @@ static PyMethodDef PyOpenDirExternallyDef = {
"Open the provided dir in the default external app.",
};
+// ----------------------------- fatal_error -----------------------------------
+
+static auto PyFatalError(PyObject* self, PyObject* args, PyObject* keywds)
+ -> PyObject* {
+ BA_PYTHON_TRY;
+ const char* message;
+ static const char* kwlist[] = {"message", nullptr};
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "s",
+ const_cast(kwlist), &message)) {
+ return nullptr;
+ }
+ FatalError(message);
+ Py_RETURN_NONE;
+ BA_PYTHON_CATCH;
+}
+
+static PyMethodDef PyFatalErrorDef = {
+ "fatal_error", // name
+ (PyCFunction)PyFatalError, // method
+ METH_VARARGS | METH_KEYWORDS, // flags
+
+ "fatal_error(message: str) -> None\n"
+ "\n"
+ "Trigger a fatal error. Use this in situations where it is not possible\n"
+ "for the engine to continue on in a useful way. This can sometimes\n"
+ "help provide more clear information at the exact source of a problem\n"
+ "as compared to raising an Exception. In the vast majority of cases,\n"
+ "however, Exceptions should be preferred.",
+};
+
// -----------------------------------------------------------------------------
auto PythonMethodsMisc::GetMethods() -> std::vector {
@@ -1456,7 +1461,6 @@ auto PythonMethodsMisc::GetMethods() -> std::vector {
PyDoOnceDef,
PyGetAppDef,
PyAndroidGetExternalFilesDirDef,
- PyAndroidShowWifiSettingsDef,
PySetInternalLanguageKeysDef,
PySetAnalyticsScreenDef,
PyLoginAdapterGetSignInTokenDef,
@@ -1500,6 +1504,7 @@ auto PythonMethodsMisc::GetMethods() -> std::vector {
PyHasTouchScreenDef,
PyNativeStackTraceDef,
PyOpenDirExternallyDef,
+ PyFatalErrorDef,
};
}
diff --git a/src/ballistica/core/platform/core_platform.cc b/src/ballistica/core/platform/core_platform.cc
index 2c95cc5f..7244b2f1 100644
--- a/src/ballistica/core/platform/core_platform.cc
+++ b/src/ballistica/core/platform/core_platform.cc
@@ -489,6 +489,8 @@ auto CorePlatform::IsRunningOnDesktop() -> bool {
}
void CorePlatform::SleepMillisecs(millisecs_t ms) {
+ // If we're holding the Python GIL, release it while we sleep.
+ Python::ScopedInterpreterLockRelease release;
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
@@ -851,10 +853,6 @@ void CorePlatform::SignOutV1() {
Log(LogLevel::kError, "SignOutV1() unimplemented");
}
-void CorePlatform::AndroidShowWifiSettings() {
- Log(LogLevel::kError, "AndroidShowWifiSettings() unimplemented");
-}
-
void CorePlatform::SetHardwareCursorVisible(bool visible) {
// FIXME: Forward this to app?..
#if BA_SDL_BUILD
diff --git a/src/ballistica/core/platform/core_platform.h b/src/ballistica/core/platform/core_platform.h
index 794d9a11..16b08f18 100644
--- a/src/ballistica/core/platform/core_platform.h
+++ b/src/ballistica/core/platform/core_platform.h
@@ -248,7 +248,6 @@ class CorePlatform {
virtual void AndroidShowAppInvite(const std::string& title,
const std::string& message,
const std::string& code);
- virtual void AndroidShowWifiSettings();
virtual auto AndroidGetExternalFilesDir() -> std::string;
#pragma mark PERMISSIONS -------------------------------------------------------
diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc
index beed0254..328b3a6f 100644
--- a/src/ballistica/shared/ballistica.cc
+++ b/src/ballistica/shared/ballistica.cc
@@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica {
// These are set automatically via script; don't modify them here.
-const int kEngineBuildNumber = 21188;
+const int kEngineBuildNumber = 21195;
const char* kEngineVersion = "1.7.24";
#if BA_MONOLITHIC_BUILD
diff --git a/src/ballistica/shared/python/python.cc b/src/ballistica/shared/python/python.cc
index 05226da1..139cccb6 100644
--- a/src/ballistica/shared/python/python.cc
+++ b/src/ballistica/shared/python/python.cc
@@ -399,16 +399,21 @@ Python::ScopedInterpreterLock::~ScopedInterpreterLock() { delete impl_; }
class Python::ScopedInterpreterLockRelease::Impl {
public:
Impl() {
- assert(HaveGIL());
- // Release the GIL.
- thread_state_ = PyEval_SaveThread();
+ had_gil_ = HaveGIL();
+ if (had_gil_) {
+ // Release the GIL.
+ thread_state_ = PyEval_SaveThread();
+ }
}
~Impl() {
- // Restore the GIL.
- PyEval_RestoreThread(thread_state_);
+ if (had_gil_) {
+ // Restore the GIL.
+ PyEval_RestoreThread(thread_state_);
+ }
}
private:
+ bool had_gil_{};
PyThreadState* thread_state_{};
};
diff --git a/src/ballistica/shared/python/python.h b/src/ballistica/shared/python/python.h
index 7b43a1d8..a4245004 100644
--- a/src/ballistica/shared/python/python.h
+++ b/src/ballistica/shared/python/python.h
@@ -55,8 +55,8 @@ class Python {
Impl* impl_{};
};
- /// Use this for cases where we *do* hold the GIL but want to release
- /// it for some operation.
+ /// Use this for cases where, if we *do* hold the Python GIL, we want to
+ /// temporarily release it.
class ScopedInterpreterLockRelease {
public:
ScopedInterpreterLockRelease();
diff --git a/src/meta/babasemeta/pyembed/binding_base.py b/src/meta/babasemeta/pyembed/binding_base.py
index 7be7ca04..821d7b1c 100644
--- a/src/meta/babasemeta/pyembed/binding_base.py
+++ b/src/meta/babasemeta/pyembed/binding_base.py
@@ -31,7 +31,6 @@ values = [
_hooks.error_message, # kErrorMessageCall
_hooks.purchase_not_valid_error, # kPurchaseNotValidErrorCall
_hooks.purchase_already_in_progress_error, # kPurchaseAlreadyInProgressErrorCall
- _hooks.gear_vr_controller_warning, # kGearVRControllerWarningCall
_hooks.orientation_reset_cb_message, # kVROrientationResetCBMessageCall
_hooks.orientation_reset_message, # kVROrientationResetMessageCall
_apputils.handle_v1_cloud_log, # kHandleV1CloudLogCall
@@ -44,7 +43,6 @@ values = [
_hooks.purchases_restored_message, # kPurchasesRestoredMessageCall
_hooks.unavailable_message, # kUnavailableMessageCall
_hooks.set_last_ad_network, # kSetLastAdNetworkCall
- _hooks.no_game_circle_message, # kNoGameCircleMessageCall
_hooks.google_play_purchases_not_available_message, # kGooglePlayPurchasesNotAvailableMessageCall
_hooks.google_play_services_not_available_message, # kGooglePlayServicesNotAvailableMessageCall
_hooks.empty_call, # kEmptyCall
@@ -85,7 +83,6 @@ values = [
_hooks.implicit_sign_out, # kImplicitSignOutCall
_hooks.login_adapter_get_sign_in_token_response, # kLoginAdapterGetSignInTokenResponseCall
_hooks.open_url_with_webbrowser_module, # kOpenURLWithWebBrowserModuleCall
- _apputils.on_too_many_file_descriptors, # kOnTooManyFileDescriptorsCall
_env.on_native_module_import, # kOnNativeModuleImportCall
- _env.setup_env_for_app_run, # kSetupEnvForAppRunCall
+ _env.on_main_thread_start_app, # kOnMainThreadStartAppCall
]
diff --git a/tools/batools/apprun.py b/tools/batools/apprun.py
index 99b51b68..e3e3640a 100755
--- a/tools/batools/apprun.py
+++ b/tools/batools/apprun.py
@@ -99,6 +99,7 @@ def acquire_binary(assets: bool, purpose: str) -> str:
(equivalent to 'make cmake-server-build'). To do so, set environment
variable BA_APP_RUN_BUILD_HEADLESS=1.
"""
+ import textwrap
binary_build_command: list[str]
if os.environ.get('BA_APP_RUN_ENABLE_BUILDS') == '1':
@@ -120,7 +121,9 @@ def acquire_binary(assets: bool, purpose: str) -> str:
flush=True,
)
binary_build_command = ['make', 'cmake-server-binary']
- binary_path = 'build/cmake/server-debug/dist/ballisticakit_headless'
+ binary_path = (
+ 'build/cmake/server-debug/staged/dist/ballisticakit_headless'
+ )
else:
# Using default gui builds.
if assets:
@@ -136,13 +139,22 @@ def acquire_binary(assets: bool, purpose: str) -> str:
flush=True,
)
binary_build_command = ['make', 'cmake-binary']
- binary_path = 'build/cmake/debug/ballisticakit'
+ binary_path = 'build/cmake/debug/staged/ballisticakit'
else:
# Ok; going with prefab headless stuff.
+
+ # Let the user know how to use their own binaries instead.
+ note = '\n' + textwrap.fill(
+ 'NOTE: You can set env-var BA_APP_RUN_ENABLE_BUILDS=1'
+ f' to use locally-built binaries for {purpose}'
+ ' instead of prefab ones. This will properly reflect any changes'
+ ' you\'ve made to the C/C++ layer.',
+ 80,
+ )
if assets:
print(
f'{Clr.SMAG}Fetching prefab binary & assets for'
- f' {purpose}...{Clr.RST}',
+ f' {purpose}...{note}{Clr.RST}',
flush=True,
)
binary_path = (
@@ -157,7 +169,8 @@ def acquire_binary(assets: bool, purpose: str) -> str:
binary_build_command = ['make', 'prefab-server-release-build']
else:
print(
- f'{Clr.SMAG}Fetching prefab binary for {purpose}...{Clr.RST}',
+ f'{Clr.SMAG}Fetching prefab binary for {purpose}...'
+ f'{note}{Clr.RST}',
flush=True,
)
binary_path = (
diff --git a/tools/batools/dummymodule.py b/tools/batools/dummymodule.py
index 52705cd5..0c18cd71 100755
--- a/tools/batools/dummymodule.py
+++ b/tools/batools/dummymodule.py
@@ -925,7 +925,7 @@ def generate_dummy_modules(projroot: str) -> None:
)
binary_path = apprun.acquire_binary(
- assets=True, purpose='dummy modules generation'
+ assets=True, purpose='dummy-module generation'
)
pycmd = (
@@ -961,8 +961,8 @@ def generate_dummy_modules(projroot: str) -> None:
flush=True,
)
try:
- # Note: ask Python to not scatter __pycache__ files throughout
- # our build output.
+ # Note: Ask Python to kindly not scatter __pycache__ files
+ # throughout our build output.
subprocess.run(
[binary_path, '--command', pycmd],
env=dict(os.environ, PYTHONDONTWRITEBYTECODE='1'),
diff --git a/tools/batools/staging.py b/tools/batools/staging.py
index 55772619..aaf91c11 100755
--- a/tools/batools/staging.py
+++ b/tools/batools/staging.py
@@ -1,6 +1,6 @@
# Released under the MIT License. See LICENSE for details.
#
-"""Stage assets for a build."""
+"""Stage files for builds."""
from __future__ import annotations
@@ -19,9 +19,9 @@ if TYPE_CHECKING:
# Suffix for the pyc files we include in stagings. We're using
# deterministic opt pyc files; see PEP 552.
#
-# Note: this means anyone
-# wanting to modify .py files in a build will need to wipe out the
-# existing .pyc files first or the changes will be ignored.
+# Note: this means anyone wanting to modify .py files in a build will
+# need to wipe out the existing .pyc files first or the changes will be
+# ignored.
OPT_PYC_SUFFIX = 'cpython-' + PYVER.replace('.', '') + '.opt-1.pyc'
@@ -57,6 +57,8 @@ class AssetStager:
self.include_fonts = True
self.include_json = True
self.include_pylib = False
+ self.include_monolithic_binary = False
+ self.monolithic_binary_name: str | None = None
self.pylib_src_name: str | None = None
self.include_payload_file = False
self.tex_suffix: str | None = None
@@ -74,7 +76,7 @@ class AssetStager:
# We can now use simple speedy timestamp based updates since we no
# longer have to try to preserve timestamps to get .pyc files to
- # behave (hooray!)
+ # behave (hooray!).
# Do our stripped down pylib dir for platforms that use that.
if self.include_pylib:
@@ -119,14 +121,19 @@ class AssetStager:
self.dist_mode = extract_flag(args, '-dist')
# Require either -debug or -release in args.
+ # (or a few common variants from cmake, etc.)
if '-debug' in args:
self.debug = True
assert '-release' not in args
- elif '-release' in args:
+ elif any(
+ val in args
+ for val in ['-release', '-minsizerel', '-relwithdebinfo']
+ ):
self.debug = False
else:
raise RuntimeError(
- "Expected either '-debug' or '-release' in args."
+ "Expected some form of '-debug' or '-release' in args"
+ f' ({args=}).'
)
if platform_arg == '-android':
@@ -136,6 +143,9 @@ class AssetStager:
elif platform_arg == '-cmake':
self.dst = args[-1]
self.tex_suffix = '.dds'
+ # Link/copy in a binary *if* builddir is provided.
+ self.include_monolithic_binary = self.builddir is not None
+ self.monolithic_binary_name = 'ballisticakit'
elif platform_arg == '-cmakemodular':
self.dst = args[-1]
self.tex_suffix = '.dds'
@@ -147,6 +157,9 @@ class AssetStager:
self.include_textures = False
self.include_audio = False
self.include_meshes = False
+ # Link/copy in a binary *if* builddir is provided.
+ self.include_monolithic_binary = self.builddir is not None
+ self.monolithic_binary_name = 'ballisticakit_headless'
elif platform_arg == '-xcode-mac':
self.src = os.environ['SOURCE_ROOT'] + '/build/assets'
@@ -455,6 +468,9 @@ class AssetStager:
]
subprocess.run(cmd, check=True)
+ if self.include_monolithic_binary:
+ self._sync_monolithic_binary()
+
if self.include_python_dylib:
self._sync_python_dylib()
@@ -494,6 +510,31 @@ class AssetStager:
)
subprocess.run(['chmod', '+x', path], check=True)
+ def _copy_or_symlink_file(self, srcpath: str, dstpath: str) -> None:
+ # Copy the file in for dist mode; otherwise set up a symlink for
+ # faster iteration.
+ if self.dist_mode:
+ # Blow away any symlink.
+ if os.path.islink(dstpath):
+ os.unlink(dstpath)
+ if not os.path.isfile(dstpath):
+ subprocess.run(['cp', srcpath, dstpath], check=True)
+ else:
+ if not os.path.islink(dstpath):
+ relpath = os.path.relpath(srcpath, os.path.dirname(dstpath))
+ subprocess.run(['ln', '-sf', relpath, dstpath], check=True)
+
+ def _sync_monolithic_binary(self) -> None:
+ if self.builddir is None:
+ raise RuntimeError("This staging type requires '-builddir' arg.")
+ if self.monolithic_binary_name is None:
+ raise RuntimeError('monolithic-binary-name is not set.')
+
+ mbname = self.monolithic_binary_name
+ self._copy_or_symlink_file(
+ f'{self.builddir}/{mbname}', f'{self.dst}/{mbname}'
+ )
+
def _sync_python_dylib(self) -> None:
# pylint: disable=too-many-locals
from batools.featureset import FeatureSet
@@ -534,22 +575,7 @@ class AssetStager:
built_so_path = f'{self.builddir}/{soname}'
staged_so_path = f'{dylib_staging_dir}/{soname}'
- # Copy the file in for dist mode; otherwise set up a symlink for
- # faster iteration.
- if self.dist_mode:
- # Blow away any symlink.
- if os.path.islink(staged_so_path):
- os.unlink(staged_so_path)
- if not os.path.isfile(staged_so_path):
- subprocess.run(
- ['cp', built_so_path, staged_so_path], check=True
- )
- else:
- if not os.path.islink(staged_so_path):
- relpath = os.path.relpath(built_so_path, dylib_staging_dir)
- subprocess.run(
- ['ln', '-sf', relpath, staged_so_path], check=True
- )
+ self._copy_or_symlink_file(built_so_path, staged_so_path)
# Ok, now we want to create symlinks for each of our featureset
# Python modules. All of our stuff lives in the same .so and we