3.4 KiB
Build System
Dusk uses CMake exclusively. Every source subdirectory owns its own
CMakeLists.txt; the root file only wires them together.
Golden rule
Never add source files to the root CMakeLists.txt directly.
Every .c file is registered in the CMakeLists.txt that lives in
the same directory (or a direct parent within the same module):
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
myfile.c
)
Configuration variables
| Variable | Purpose |
|---|---|
DUSK_TARGET_SYSTEM |
Selects the platform (see .claude/platforms.md) |
DUSK_BUILD_TESTS |
Enables the test suite (ON / OFF) |
CMAKE_TOOLCHAIN_FILE |
Cross-compiler toolchain for console targets |
CMAKE_BUILD_TYPE |
Debug / Release / RelWithDebInfo |
Typical configure + build
# Linux debug build
cmake -B build -DDUSK_TARGET_SYSTEM=linux -DCMAKE_BUILD_TYPE=Debug
cmake --build build
# Linux with tests
cmake -B build \
-DDUSK_TARGET_SYSTEM=linux \
-DDUSK_BUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE=Debug
cmake --build build
ctest --test-dir build
Module layout convention
Each logical module under src/ gets its own directory:
src/dusk/ Platform-agnostic core
src/dusk<platform>/ Platform-specific impl (one dir per target)
Within a module, subdirectories mirror subsystem boundaries
(asset/, entity/, script/, etc.). Each subdirectory has its own
CMakeLists.txt that is add_subdirectory()-included by its parent.
Adding a new source file
- Create
src/.../myfile.c(andmyfile.hif needed). - Open the
CMakeLists.txtin the same directory. - Add
myfile.cto thetarget_sources(...)block. - Do not touch any parent or root
CMakeLists.txt.
Platform-conditional sources
Wrap platform-only files in a generator expression or if() block:
if(DUSK_TARGET_SYSTEM STREQUAL "psp")
target_sources(${DUSK_LIBRARY_TARGET_NAME}
PUBLIC
mypspfile.c
)
endif()
Embedding JS files (dusk_embed_js)
Source: cmake/modules/duskjs2c.cmake
The dusk_embed_js() CMake function embeds a .js source file as a
C string constant in a generated header. It is used to ship script
module code alongside the engine binary without a separate file load.
dusk_embed_js(
TARGET ${DUSK_LIBRARY_TARGET_NAME}
JS_FILE path/to/mymodule.js
# NAME is optional; defaults to uppercase stem + "_JS"
# e.g. "mymodule.js" -> "MYMODULE_JS"
NAME MY_CUSTOM_NAME
)
The generated header is placed in
${DUSK_GENERATED_HEADERS_DIR}/<stem>_js.h and defines:
static const char MY_CUSTOM_NAME[] = "... js source ...";
static const size_t MY_CUSTOM_NAME_SIZE = sizeof(MY_CUSTOM_NAME) - 1;
Under the hood it calls python -m tools.js2c from the repo root.
The header is generated at build time; include it in the .c file
that registers the JS module, then pass NAME and NAME_SIZE to
jerry_eval() (or the equivalent module load helper).
Tests
- Test files live in
test/mirroring thesrc/dusk/structure. - Enable with
-DDUSK_BUILD_TESTS=ON. - Uses cmocka; include
dusktest.hin every test file. - Every test must assert
memoryGetAllocatedCount() == 0at teardown to catch allocator leaks. - Test function signature:
static void test_something(void **state)