Developers are strongly encouraged to use nix for managing the projects dependencies. This makes setup completely hassle free.
This requires installing Nix. To access the shell simply run:
# NOTE: you will have to enable the flake and nix-command experimental features.
nix develop
Additionally, the development environment can be loaded automatically when inside the project directory using direnv. After install, simply run:
direnv allow .
Editors like VS Code
have extensions like direnv for
interfacing with the direnv
shell. This is can be used so that non-terminal based text editors
pick up on the dependencies provided by the nix
dev shell.
Because this project uses bleeding edge C++, you may need to override the clangd
version being used by your editor
to version 19+. Otherwise, clangd
will choke on any code which uses C++ 26 features.
Build system targets that are only useful for developers of this project are
hidden if the dius_DEVELOPER_MODE
option is disabled. Enabling this
option makes tests and other developer targets and options available. Not
enabling this option means that you are a consumer of this project and thus you
have no need for these targets and options.
Developer mode is always set to on in CI workflows.
This project makes use of presets to simplify the process of configuring the project. As a developer, you are recommended to always have the latest CMake version installed to make use of the latest Quality-of-Life additions.
You have a few options to pass dius_DEVELOPER_MODE
to the configure
command, but this project prefers to use presets.
As a developer, you should create a CMakeUserPresets.json
file at the root of
the project:
{
"version": 2,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "dev",
"binaryDir": "${sourceDir}/build/dev",
"inherits": ["dev-mode", "docs", "ci-<os>"],
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
],
"buildPresets": [
{
"name": "dev",
"configurePreset": "dev",
"configuration": "Debug"
}
],
"testPresets": [
{
"name": "dev",
"configurePreset": "dev",
"configuration": "Debug",
"output": {
"outputOnFailure": true
}
}
]
}
You should replace <os>
in your newly created presets file with the name of
the operating system you have, which may be win64
, linux
or darwin
. You
can see what these correspond to in the
CMakePresets.json
file.
CMakeUserPresets.json
is also the perfect place in which you can put all
sorts of things that you would otherwise want to pass to the configure command
in the terminal.
Note Some editors are pretty greedy with how they open projects with presets. Some just randomly pick a preset and start configuring without your consent, which can be confusing. Make sure that your editor configures when you actually want it to, for example in CLion you have to make sure only the
dev-dev preset
hasEnable profile
ticked inFile > Settings... > Build, Execution, Deployment > CMake
and in Visual Studio you have to set the optionNever run configure step automatically
inTools > Options > CMake
prior to opening the project, after which you can manually configure usingProject > Configure Cache
.
If you followed the above instructions, then you can configure, build and test the project respectively with the following commands from the project root on any operating system with any build system:
cmake --preset=dev
cmake --build --preset=dev
ctest --preset=dev
If you are using a compatible editor (e.g. VSCode) or IDE (e.g. CLion, VS), you will also be able to select the above created user presets for automatic integration.
Please note that both the build and test commands accept a -j
flag to specify
the number of jobs to use, which should ideally be specified to the number of
threads your CPU has. You may also want to add that to your preset using the
jobs
property, see the presets documentation for more details.
These are targets you may invoke using the build command from above, with an
additional -t <target>
flag:
Available if ENABLE_COVERAGE
is enabled. This target processes the output of
the previously run tests when built with coverage configuration. The commands
this target runs can be found in the COVERAGE_TRACE_COMMAND
and
COVERAGE_HTML_COMMAND
cache variables. The trace command produces an info
file by default, which can be submitted to services with CI integration. The
HTML command uses the trace command's output to generate an HTML document to
<binary-dir>/coverage_html
by default.
Available if BUILD_DOCS
is enabled. Builds to documentation using
Doxygen. The output will go to <binary-dir>/docs/html
by default
(customizable using DOXYGEN_OUTPUT_DIRECTORY
).
When using the nix environment, the di library is automatically available to
the CMake build. However, this copy is immutable. If you need to make changes
to both libraries at once, a custom checkout of di can be used by creating
a symbolic link named di
in the root of this package. For instance, if your
di checkout is in a sibling directory of your dius checkout, run:
ln -s "$(realpath ../di)" di
The justfile
provides a CLI interface for interfacing with the project, and
can be used as an alternative to IDE support for CMake presets for developers
with more minimal setups.
The justfile
operates on a given CMake preset which is controlled by the
PRESET
environment variable. This defaults to the dev
preset you should've
setup already. If you add multiple presets to your CMakeUserPresets.json
file,
you can select which preset to use interactively by running:
eval $(just choose)
Whenever a new justfile
command is run, the selected preset will be auto-configured
if the build directory does not exist. Additionally, the compile_commands.json
for
the build configuration will be symlinked into the project directory. This ensures
clangd
will be configured properly for your preset (This happens automatically
when using a VS Code extension like ms-vscode.cpptools
).
Building and running the unit tests is as simple as:
just bt
To format all source files, use:
just format
To see an overview of all just
commands, simply run just
with no arguments.
just
There are several additional commands which should cover everything necessary to develop the project.