Project template for a C++ application and library, set up with Meson/Nix tooling, tests, documentation, and packaging.
Highlights:
- Modular layout (app + library)
- CI-ready
- Cross-build targets (aarch64, Windows, WASM)
- include/ Public library headers
- src/app/ Application sources
- src/lib/ Library implementation
- tests/ Unit tests
- assets/ Runtime assets
- scripts/ Build and tooling scripts
- Nix (recommended) or a C++20 toolchain + Meson + Ninja
- Optional: doxygen + graphviz for docs
If you use direnv:
direnv allowBuild (native, release):
make buildRun tests (native, debug build first):
make test# Usage: scripts/rename.sh <NewName> [NewLibName] [NewNamespace]
./scripts/rename.sh MyApp MyAppLib myappmake build # Native release build
make debug # Native debug build
make test # Run tests
make format # clang-format on sources
make check # clang-tidy (native debug builddir)make cross-aarch64
make cross-windows
make cross-wasmmake package-native
make package-aarch64
make package-windows
make package-wasmBuild the project as a proper Nix package (reproducible, isolated, Nix store output):
make nix-build # shortcut for: nix build ./nix#NixonCppThe result is available as a symlink ./result pointing into the Nix store:
result/bin/NixonCpp
result/lib/libNixonCppLib.*
result/include/NixonCppLib/
By default, nix-collect-garbage can remove cross-compilation toolchains
(aarch64, Windows, WASM) from the Nix store, forcing a full re-download on
the next build. Pin all dev shells as GC roots to prevent this:
make pin-shells # run once after cloning, and after 'nix flake update'This creates symlinks build/.gcroot-shell-{default,aarch64,windows,wasm}
that act as GC roots – as long as they exist, the garbage collector will
never remove the referenced store paths.
Note: The WASM shell uses a pinned nixpkgs commit (for Emscripten compatibility) and may take longer to download on the very first run.
- Online docs: https://tomasmark79.github.io/NixonCpp/html/index.html
- Generate locally:
make doxygenOutput: docs/html/index.html
Workspace tasks are defined in .vscode/tasks.json.
How to run:
- Use
Terminal: Run Task(orTasks: Run Task) and pick one of the tasks below.
Common tasks:
Direct Build (native debug)(default build task)Project Build Tasks(interactive picker: Build/Configure/Test/Package + arch + buildtype)clang-formatclang-tidyLaunch Application (native)/Launch Application (native release)Launch Emscripten Server/Launch Emscripten Server (release)
Optional keybindings:
- A suggested keybinding setup is provided in .vscode/keybindings.json.
- Copy it into your user keybindings file (Linux default:
~/.config/Code/User/keybindings.json).
This repo is Codespaces-ready via a devcontainer using Nix.
- Ensure the devcontainer is used: .devcontainer/devcontainer.json
- After the container is created, the post-create step prefetches the Nix dev shell.
- Build + test as usual:
make debugmake test
Notes:
- WebAssembly dev server uses port
6931(auto-forwarded by the devcontainer). - Native builds can work without Nix if you install Meson/Ninja + a C++20 toolchain, but cross builds require Nix.
Example (debug builddir):
meson configure build/builddir-debug -Dbuild_tests=enabledMIT