Files
dusk/.claude/build.md
T
2026-06-16 12:29:36 -05:00

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

  1. Create src/.../myfile.c (and myfile.h if needed).
  2. Open the CMakeLists.txt in the same directory.
  3. Add myfile.c to the target_sources(...) block.
  4. 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 the src/dusk/ structure.
  • Enable with -DDUSK_BUILD_TESTS=ON.
  • Uses cmocka; include dusktest.h in every test file.
  • Every test must assert memoryGetAllocatedCount() == 0 at teardown to catch allocator leaks.
  • Test function signature: static void test_something(void **state)