-
Notifications
You must be signed in to change notification settings - Fork 2
user_impl_workflow
This page explains where you implement your extension logic, how the generated CMake project is intended to be used, and how the workflow differs by target.
extgen generates the bridge code and build system. The extension logic itself always lives in the src/ folder (plus target-specific glue for some platforms).
After running extgen, the folder structure is:
-
code_gen/- generated bridge code (do not hand-edit) -
cmake/- helper scripts (packaging, xcframework, etc.) -
src/- your implementation lives here-
src/CMakeLists.txt- controls which files build per platform -
src/native/,src/ios/,src/tvos/, etc. - platform implementations
-
-
third_party/- optional integration point for SDKs and libraries
The general workflow:
- Edit GMIDL to define the public API.
- Run extgen to regenerate bindings and the project.
- Implement platform behavior in
src/. - Build via CMake presets or via IDE toolchains.
The root CMakeLists.txt provides platform classification booleans:
set(EXTGEN_IS_IOS FALSE)
set(EXTGEN_IS_TVOS FALSE)
set(EXTGEN_IS_APPLE_MOBILE FALSE)
set(EXTGEN_IS_PS4 FALSE)
set(EXTGEN_IS_PS5 FALSE)
set(EXTGEN_IS_SWITCH FALSE)
if(EXTGEN_PLATFORM_SWITCH)
set(EXTGEN_IS_SWITCH TRUE)
endif()
if(APPLE)
if(CMAKE_OSX_SYSROOT MATCHES "iphone")
set(EXTGEN_IS_IOS TRUE)
set(EXTGEN_IS_APPLE_MOBILE TRUE)
elseif(CMAKE_OSX_SYSROOT MATCHES "appletv")
set(EXTGEN_IS_TVOS TRUE)
set(EXTGEN_IS_APPLE_MOBILE TRUE)
endif()
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "ORBIS")
set(EXTGEN_IS_PS4 TRUE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Prospero")
set(EXTGEN_IS_PS5 TRUE)
endif()Use these in src/CMakeLists.txt to control which files compile, which defines are added, and which files belong to each platform.
The following preprocessor defines are set automatically:
| Define | Platform |
|---|---|
OS_SWITCH |
Nintendo Switch |
OS_WINDOWS |
Windows |
OS_ANDROID |
Android |
OS_IOS |
iOS |
OS_TVOS |
tvOS |
OS_PS4 |
PlayStation 4 |
OS_PS5 |
PlayStation 5 |
When building an XCFramework, the packaging step requires a list of public headers. extgen places these variables in src/CMakeLists.txt:
set(EXT_PUBLIC_HEADERS_IOS
"${CMAKE_SOURCE_DIR}/src/ios/${PROJECT_NAME}_ios.h;${CMAKE_SOURCE_DIR}/code_gen/ios/${PROJECT_NAME}Internal_ios.h"
CACHE STRING "Semicolon-separated list of public headers to embed in the iOS xcframework")
set(EXT_PUBLIC_HEADERS_TVOS
"${CMAKE_SOURCE_DIR}/src/tvos/${PROJECT_NAME}_tvos.h;${CMAKE_SOURCE_DIR}/code_gen/tvos/${PROJECT_NAME}Internal_tvos.h"
CACHE STRING "Semicolon-separated list of public headers to embed in the tvOS xcframework")Important
Keep this list correct if you change your src/ios or src/tvos layout. xcodebuild -create-xcframework requires a headers folder; extgen collects these files into that folder during packaging.
- No C/C++ library build
- Pure Java/Kotlin glue code emitted into the target output folder (default:
../AndroidSource/...)
Implement platform behavior in the generated Java/Kotlin layer.
A module-named file is generated:
../AndroidSource/Java/<ModuleName>.java
And an internal interface:
../AndroidSource/Java/code_gen/<ModuleName>Interface.java
Your implementation should implement that interface. When you regenerate, compile errors immediately surface any missing functions.
This applies to: Windows, macOS, Linux, Xbox, PS4/PS5, Nintendo Switch, Android (JNI mode), iOS/tvOS (Native mode).
In src/, typically:
-
src/native/- shared native implementation -
src/windows/,src/macos/, etc. - optional platform splits -
src/ios/,src/tvos/- platform wrappers if needed
if(WIN32)
file(GLOB TARGET_SRCS CONFIGURE_DEPENDS "${SRC_DIR}/native/*.cpp" "${SRC_DIR}/windows/*.cpp")
elseif(APPLE)
if(EXTGEN_IS_IOS)
file(GLOB TARGET_SRCS CONFIGURE_DEPENDS "${SRC_DIR}/native/*.cpp" "${SRC_DIR}/ios/*.mm")
elseif(EXTGEN_IS_TVOS)
file(GLOB TARGET_SRCS CONFIGURE_DEPENDS "${SRC_DIR}/native/*.cpp" "${SRC_DIR}/tvos/*.mm")
else()
file(GLOB TARGET_SRCS CONFIGURE_DEPENDS "${SRC_DIR}/native/*.cpp" "${SRC_DIR}/macos/*.mm")
endif()
elseif(ANDROID)
file(GLOB TARGET_SRCS CONFIGURE_DEPENDS "${SRC_DIR}/native/*.cpp")
else()
file(GLOB TARGET_SRCS CONFIGURE_DEPENDS "${SRC_DIR}/native/*.cpp")
endif()
target_sources(${PROJECT_NAME} PRIVATE ${TARGET_SRCS})- Most targets build a shared library.
- iOS/tvOS build a static slice that is packaged into an XCFramework.
The integration into the GameMaker-generated Xcode project is handled automatically via a dedicated CMake build target.
extgen --config config.jsonRun configure via preset or manually. No manual Xcode steps are needed at this stage.
From GameMaker, build for iOS/tvOS with Suppress Run enabled. This generates the Xcode project for the game.
In your CMake configuration or preset, set:
set(EXT_GM_XCODEPROJ_OVERRIDE
"~/GameMakerStudio2/GM_IOS/YourGame/YourGame/YourGame.xcodeproj"
CACHE FILEPATH "" FORCE)
set(EXT_GM_APP_TARGET_OVERRIDE "" CACHE STRING "" FORCE)| Variable | Purpose |
|---|---|
EXT_GM_XCODEPROJ_OVERRIDE |
Path to the GameMaker-generated .xcodeproj
|
EXT_GM_APP_TARGET_OVERRIDE |
Optional override for the app target name |
EXT_GM_XCODEPROJ_OVERRIDE is a FILEPATH cache variable, so CMake expands ~, normalizes the path, and validates it correctly in GUIs and presets.
cmake --build <build-folder> --target integrate_gamemakerThis target adds the extension project to the GameMaker Xcode project, creates the required project references, adds the static library dependency, links it into the correct GameMaker target, and handles repeated runs safely (idempotent).
Open the .xcodeproj or workspace. The extension is already integrated - build for device or simulator, debug on real hardware, and edit extension source directly from the injected reference.
The integration adds a project reference, not copied files, so edits made in Xcode edit the real extension source.
- Edit GMIDL.
- Run
extgen. - Implement logic in
src/. - Export from GameMaker (Suppress Run).
- Run the integration target:
cmake --build <build-folder> --target integrate_gamemaker - Open Xcode and build/debug.
Re-export from GameMaker, then re-run the integration target whenever the game project changes.
cmake --build <build-folder> --target package_ios_xcframework
cmake --build <build-folder> --target package_tvos_xcframeworkProduces <ExtensionName>.xcframework and a zipped distribution artifact (if configured).
Console target setup - SDK paths, environment variables, presets, and output artifacts - is covered in the dedicated Console Setup page.
| Target | Where you implement | What you build |
|---|---|---|
| Android (Java/Kotlin) | Android output folder (../AndroidSource/...) |
No native lib |
| Desktop + Consoles + JNI |
src/ via CMakeLists |
Shared library |
| Nintendo Switch |
src/ + user-configured SDK paths |
.nro + .nrr + .nrs
|
| PS4 / PS5 |
src/ + user-configured SDK paths |
_ps4.prx / _ps5.prx
|
| iOS/tvOS Native mode |
src/ + XCFramework packaging |
XCFramework |
| iOS/tvOS ObjC/Swift modes |
src/ + Xcode dev workflow |
XCFramework |
- Keep core logic platform-agnostic in
src/native/. Use platform folders only for wrappers and entry points. - Keep
src/CMakeLists.txtexplicit about which sources compile on which platform. - Maintain the XCFramework public header list for Apple targets whenever you change the
src/iosorsrc/tvoslayout. - For console targets (Switch, PS4, PS5): never commit SDK paths. Always use
CMakeUserPresets.json(gitignored). See Console Setup. - Use the provided preprocessor defines (
OS_SWITCH,OS_WINDOWS, etc.) for platform-specific code. - Regenerate often. Compile errors after regeneration indicate which functions need updating - treat them as a checklist.
GameMaker 2026