# 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): ```cmake 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 ```sh # 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-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: ```cmake 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. ```cmake 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}/_js.h` and defines: ```c 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)`