From installation to building, testing, and running your first project. Task-oriented how-tos are in 63-guides.md, the manifest reference in 10-manifest.md, and the command reference in 60-cli.md.
There are no binary releases yet; build from source. You need:
| Requirement | Used for |
|---|---|
A Rust toolchain (cargo) |
building dowel itself |
| A C compiler | compiling your project; the default is cc on PATH |
| A C++ compiler | only for projects with C++ sources; the default is c++ on PATH |
ninja |
the default backend; without it, the sequential backend (--backend=direct) works |
git clone https://github.com/sabas0ba/dowel
cd dowel
cargo build --release
export PATH="$PWD/target/release:$PATH"
dowel --version
If you need to pin or switch versions, dowelup acquires and manages dowel
itself (61-acquisition.md).
examples/hello is a two-package setup: a static
library (libgreet) and an executable that uses it (app).
cd examples/hello/app
dowel check # report diagnostics only; does not build
dowel build # plan and build (ninja by default)
./.dowel/build/*/bin/app
cd ../libgreet
dowel test # build and run the test targets
dowel new myapp
cd myapp
dowel build
./.dowel/build/*/bin/myapp
dowel new scaffolds a working bin package (--lib for a library, which
comes with a passing dowel test target). What it generates is exactly the
minimal form below — two files plus a source. dowel.toml holds package
information (strict TOML read and written by machines) and dowel.build
holds target definitions (written by humans); the reasons for the split are
in 10-manifest.md.
myapp/
├── dowel.toml
├── dowel.build
└── src/
└── main.c
dowel.toml:
[package]
name = "myapp"
version = "0.1.0"
edition = "2026"
dowel.build:
[bin.myapp]
sources = glob("src/*.c")
dowel check
dowel build
./.dowel/build/*/bin/myapp
Build outputs and intermediates go under .dowel/ (add it to your git
ignore). Build directories are separated per configuration (--config).
Deleting .dowel/ is always safe: correctness is never lost, only the cached
speedup (see the store section of 60-cli.md).
dowel add libs/util # scaffold a library and declare the dependency
dowel add --git https://github.com/x/y # declare a git dependency, pinned to HEAD's sha
dowel add creates a library package in a subdirectory (or, with --git,
declares an external repository pinned to a full commit sha) and appends the
[[dependencies]] entry to your dowel.toml; wiring it into a target
(below) stays your choice, and the command prints the exact line to add.
Dependencies between packages are declared in dowel.toml — as a local
path, as a git URL pinned to a full commit sha, or as a version
constraint resolved through the system pkg-config
(11-toml-reference.md). Which target uses a
dependency is written in dowel.build.
app/dowel.toml:
[[dependencies]]
name = "libgreet"
path = "../libgreet"
app/dowel.build:
[bin.app.private]
deps = [dep("libgreet")]
On the library side, what propagates to dependents (public) and what applies
only to the library itself (private) are separated by block:
[lib.greet]
sources = glob("src/**.c")
[lib.greet.public]
includes = [dir("include")] # also affects the compilation of app
[lib.greet.private]
includes = [dir("src")] # affects only this library; invisible to app
dowel why traces where a propagated value came from:
dowel why app:app includes
[test.unit]
sources = glob("tests/*.c")
[test.unit.private]
deps = [target("greet")]
dowel test builds and runs them, treating exit status 0 as success. This
follows the C convention; no test harness is imposed.
dowel test
dowel test --nocapture # pass test output through
dowel test --failed --fail-fast # only what failed last time, stop at the first failure
dowel check — on every save. Runs through planning and reports diagnostics
only, without executing anything, so it is fastdowel build / dowel test — verify for realdowel why <target> <property> — answers “why does this value look like
this” with the propagation pathDOWEL_LOG=debug dowel build — answers “why did this rebuild” in the logIf you write manifests in an editor, there is a language server (dowel lsp;
63-guides.md section 6). Diagnostics carry locations and
stable codes, and unknown names come with suggestions.
dowelup) —
61-acquisition.md