3.3 KiB
cargoxx
A Cargo-style frontend for modern C++ that uses Nix as the dependency
source of truth and generates CMake for the build. Users author projects
with C++23 modules and never touch CMake or flake.nix by hand.
Status: M6. Self-hosting (cargoxx builds itself from
Cargoxx.toml). Full auto-resolver chain (Conan / vcpkg / nix-config / CMake FindModule / pkg-config / brute-force fallback). Pre-v0.1; CLI is stable but the on-disk linkdb schema is not.
See SPEC.md for the user-facing contract and
TECH_SPEC.md for the implementation.
What it does
cargoxx new myapp # scaffold Cargoxx.toml + src/main.cpp
cd myapp
cargoxx add fmt # resolve fmt → write recipe to ~/.cache/cargoxx/linkdb.sqlite,
# pin nixpkgs rev into Cargoxx.lock
cargoxx build # generate build/CMakeLists.txt + flake.nix,
# then `nix develop -c cmake --build`
cargoxx run # build + exec
cargoxx test # build + ctest
The user never touches build/CMakeLists.txt or flake.nix. Both are
regenerated from Cargoxx.toml on every build.
How dependency resolution works
cargoxx add <pkg> (and cargoxx build on a missing dep) walks a probe
chain. The first probe whose verify-link build succeeds wins; its recipe
is confirmed in the SQLite overlay.
| # | Probe | Source |
|---|---|---|
| 1 | conan-center-index | exact + Levenshtein fuzzy ≤ ⌈len/4⌉ |
| 2 | microsoft/vcpkg ports | exact + Levenshtein fuzzy |
| 3 | nix-probe | <X>Config.cmake under pkgs.<pkg>.dev |
| 4 | cmake-findmodule | CMake's bundled Find*.cmake |
| 5 | pkg-config | <X>.pc under pkgs.<pkg>.dev/lib/pkgconfig |
| 6 | brute-force | every lib/lib*.{a,so,dylib} + include/ |
Package names match nixpkgs/devbox. Conan/vcpkg fuzzy match is internal only — the user-typed name is preserved end-to-end in the manifest, lockfile, and linkdb key.
Debugging a failed cargoxx add
Every probe's verify-link scratch project is preserved under
~/.cache/cargoxx/last-failure/<pkg>/<NN>-<probe>/. Re-run cmake inside
any subdir to reproduce, or just inspect the generated flake.nix and
build/CMakeLists.txt.
~/.cache/cargoxx/last-failure/sqlite/
01-vcpkg/ # vcpkg fuzzy candidate, failed
02-cmake-findmodule/ # FindSQLite3 candidate, won
Building from source
cargoxx is self-hosted, so the bootstrap path requires an existing cargoxx binary (release artifact or one built from a prior commit) plus a Nix toolchain.
nix develop
cargoxx build # regenerate build/CMakeLists.txt + root flake.nix
cmake -S build -B build/debug -G Ninja
cmake --build build/debug
The dev shell ships pkgs.gcc15Stdenv (g++ 15, libstdc++, with
import std; via bits/std.cc). cmake/ninja are also injected.
On a clean clone with an empty ~/.cache/cargoxx/linkdb.sqlite,
cargoxx build auto-resolves all three of cargoxx's own deps
(sqlite, reproc, catch2_3) on first invocation.
Manifest
[package]
name = "myapp"
version = "0.1.0"
edition = "cpp23"
[dependencies]
fmt = "10.2"
sqlite = "*"
[dev-dependencies]
catch2_3 = "*"
[build]
warnings_as_errors = true
include_dirs = ["third_party"]
sanitizers = ["address"]
See SPEC.md §4 for the full schema.