Mavros is a toolchain for compiling Noir to R1CS with additional functionality for use with Spartan. It provides a complete pipeline from Noir source to the output of the eventual circuit, and is designed with mobile proving workflows in mind.
This project uses Nix flakes to provide a
pinned build environment with all the tools you need to build the project. Assuming you have nix
installed, simply make shell to drop into your user shell inside the build environment, or run
nix develop --command <your-command-here> to run a specific command in the build environment.
You can use one of the two following methods to experiment with Mavros.
- Running
make installwill build and install Mavros to your cargo binary directory. - Running
make releasewill build Mavros to./target/release/mavros.
Run make to get an overview of the available utilities and targets. For complete guidance please
see our contributing guidelines. See usage below for more
information on how to use Mavros.
To use Mavros, navigate to the root of a Noir project (the directory containing Nargo.toml) in
your shell. Then run mavros compile.
This will produce the following two files inside the project's target/ directory:
| File | Contents |
|---|---|
target/basic.json |
ABI and the program binary (binary) containing the witgen and AD entry points |
target/r1cs.bin |
Serialised R1CS constraint system (bincode) |
Pass --include-debug-info to additionally write target/basic.debug.json. This standalone,
versioned source map records VM bytecode word offsets, function names, and Noir source locations;
the executable bytecode in basic.json remains byte-for-byte unchanged. Source paths are relative
to the Noir package root by default; pass --absolute-paths to retain absolute paths.
Run the full compiler and VM pipeline with --profile to generate interactive per-function
FlameGraphs:
mavros --root . --profileThe command writes folded-stack inputs and SVGs under mavros_debug/flamegraphs/ for four
dimensions: constraint_size, witness_size, witgen_time, and ad_time. The two time profiles
use the VM's deterministic simulated instruction count rather than wall-clock samples, so profiles
can be compared across machines and runs. Profiling automatically enables the VM debug mapping
needed to recover Noir function names. Shared lookup-table allocations appear under a separate
<lookup tables> branch; the cost of each lookup remains attributed to its callsite.
The command also writes witgen_time.cpuprofile and ad_time.cpuprofile. Load either file from the
Chrome DevTools Performance panel to inspect it with the DevTools flame chart and call tree. These
profiles preserve execution order and use deterministic instruction intervals rather than wall-clock
time. Runs of up to 100,000 instructions contain one sample per instruction; larger runs use
bounded, deterministic stratified sampling to avoid periodic sampling bias while keeping file size
practical.
SVG rendering uses Brendan Gregg's FlameGraph
flamegraph.pl. It is pinned and available in nix develop; outside the Nix shell, install
FlameGraph and put flamegraph.pl on PATH. When the script is unavailable, Mavros still writes
the folded profiles and Chrome .cpuprofile files and skips only the SVGs.
For advanced usage and the CLI options, run mavros --help. To output the witness generation binary
for WASM-capable platforms, please see the WASM output
section in our contributing docs.
When pointed at a workspace, Mavros honors default-member. Without a default, the CLI runs or
compiles every binary member in manifest order; library members remain available as dependencies.
Each binary uses its own Prover.toml and mavros_debug directory. A failed member makes the
workspace run fail, while the remaining members are still checked.
When mavros compile resolves a package root different from the supplied path, relative output
paths use that package root, including for a single default member. The defaults then produce
<member>/target/basic.json and <member>/target/r1cs.bin. Absolute output paths and paths
containing .. are rejected for multi-binary compilations. Point Mavros directly at a member
directory to compile just that package with the usual output-path behavior.
The functional test runner reports each selected binary workspace member as a separate test, with its own checks, circuit size, and artifact sizes. Libraries are not separate executable tests.
cd my-noir-project
mavros compile
# → target/basic.json
# → target/r1cs.binFor the current status of Mavros' support for various Noir constructs, see the status doc that is generated by CI on every update. This provides information on how far the Mavros pipeline gets for each Noir test.