Skip to main content
The jolt build command compiles Rust code into RISC-V binaries optimized for proving in the Jolt zkVM.

Usage

jolt build [OPTIONS] [-- CARGO_ARGS...]

Build Modes

--std
boolean
default:"false"
Build with Rust standard library support (std mode).
  • Uses riscv64imac-zero-linux-musl target
  • Includes musl libc and gcc runtime libraries
  • Automatically downloads and installs required toolchain
  • Larger binary size but full std features
jolt build --std
--no-std
boolean
default:"true"
Build without standard library (no_std mode). This is the default.
  • Uses riscv64imac-unknown-none-elf target
  • Minimal runtime, smaller binaries
  • Requires #![no_std] in guest code
jolt build --no-std

Toolchain Options

--musl-lib-path
path
Path to custom musl libc installation.If not specified, Jolt will automatically download or build musl. Use this to provide a pre-built musl library.
jolt build --std --musl-lib-path /opt/musl/lib
--gcc-lib-path
path
Path to custom GCC runtime libraries (libgcc).Used in std mode for exception handling and runtime support. If not specified, Jolt will build it automatically.
jolt build --std --gcc-lib-path /opt/gcc/lib
--fully
boolean
default:"false"
Force full toolchain build from source, even if binaries are available.Useful for:
  • Reproducible builds
  • Custom toolchain patches
  • Verifying build from source
jolt build --std --fully

Debugging and Backtrace

--backtrace
string
default:"auto"
Controls symbol preservation and frame pointer generation for debugging.Values:
  • auto - Preserve symbols in debug/dev profiles, strip in release
  • enable - Always preserve symbols (skips -Cstrip=symbols)
  • dwarf - Preserve symbols + enable frame pointers (-Cforce-frame-pointers=yes)
  • frame-pointers - Enable frame pointers without DWARF
  • disable - Always strip symbols
# Enable backtraces for release builds
jolt build --release --backtrace enable

# Full DWARF debug info
jolt build --backtrace dwarf
The JOLT_BACKTRACE=1 environment variable is often more convenient than --backtrace enable for ad-hoc debugging, as it doesn’t require rebuild flags.

Cargo Integration

CARGO_ARGS
string[]
Additional arguments passed directly to cargo build.All arguments after -- are forwarded to cargo:
# Release build
jolt build -- --release

# Build specific package
jolt build -- -p my-guest

# Verbose output
jolt build -- --verbose

# Multiple args
jolt build -- --release --target-dir custom-target

Environment Variables

Optimization Level

JOLT_GUEST_OPT
string
default:"3"
Controls optimization level for guest code via -Copt-level.Valid values:
  • 0 - No optimizations
  • 1 - Basic optimizations
  • 2 - Some optimizations
  • 3 - All optimizations (default)
  • s - Optimize for size
  • z - Optimize for size, more aggressive
JOLT_GUEST_OPT=s jolt build

Backtrace Control

JOLT_BACKTRACE
string
Enables symbol preservation for debugging without modifying build flags.
  • 1 - Preserve symbols, enable tracer backtraces
  • full - Include register dumps and cycle counts
# Ad-hoc debugging without rebuild
JOLT_BACKTRACE=1 cargo run --release
Unlike --backtrace enable, this triggers a guest rebuild automatically while keeping your existing cargo build flags intact.

Target-Specific CFLAGS

The build system automatically sets:
CFLAGS_riscv64imac_unknown_none_elf="-mcmodel=medany"
CFLAGS_riscv64imac_zero_linux_musl="-mcmodel=medany"
You can extend these by setting the environment variable:
export CFLAGS_riscv64imac_unknown_none_elf="-mcmodel=medany -O3"
jolt build

Rust Flags

Jolt automatically adds these rustflags to guest builds:
  • -Cpasses=lower-atomic - Lower atomic operations to library calls
  • -Cpanic=abort - Panic = abort (no unwinding)
  • -Copt-level=<N> - Optimization level from JOLT_GUEST_OPT
  • -Cllvm-args=-enable-machine-outliner=never - Disable broken RISC-V outliner
  • --cfg=getrandom_backend="custom" - Use custom entropy source
  • -Cstrip=symbols - Strip symbols (unless backtrace enabled)
  • -Cforce-frame-pointers=yes - Only with --backtrace dwarf/frame-pointers

Build Process

The build happens in several stages:
  1. Workspace detection - Finds the Cargo workspace root
  2. Toolchain setup - Downloads/builds musl and gcc libs (std mode only)
  3. Target spec generation - Creates custom RISC-V target JSON
  4. Linker script - Generates memory layout from embedded template
  5. Cargo build - Compiles guest with custom rustflags
  6. Post-processing - Strips symbols if configured

Examples

Basic Build

Build with default settings (no_std, opt-level 3):
jolt build

Release Build

Build with cargo release profile:
jolt build -- --release

Std Mode Build

Build with standard library:
jolt build --std -- --release

Debug Build with Backtraces

Build with symbols for debugging:
jolt build --backtrace enable
Or use the environment variable:
JOLT_BACKTRACE=1 jolt build

Optimize for Size

Minimize binary size:
JOLT_GUEST_OPT=z jolt build -- --release

Custom Toolchain

Use pre-built toolchain components:
jolt build --std \
  --musl-lib-path /opt/riscv/musl/lib \
  --gcc-lib-path /opt/riscv/gcc/lib \
  -- --release

Reproducible Build

Build toolchain from source:
jolt build --std --fully -- --release

Output Location

Built binaries are placed in the standard cargo target directory: No-std mode:
target/riscv64imac-unknown-none-elf/release/guest
target/riscv64imac-unknown-none-elf/debug/guest
Std mode:
target/riscv64imac-zero-linux-musl/release/guest
target/riscv64imac-zero-linux-musl/debug/guest

Troubleshooting

Toolchain Download Failures

If automatic toolchain installation fails:
# Build from source
jolt build --std --fully

# Or provide paths to pre-built components
jolt build --std --musl-lib-path /path/to/musl --gcc-lib-path /path/to/gcc

Optimization Errors

If you encounter “Invalid JOLT_GUEST_OPT value” errors:
# Valid values only: 0, 1, 2, 3, s, z
JOLT_GUEST_OPT=3 jolt build

Linker Errors

For linker errors in std mode:
# Try rebuilding toolchain
jolt build --std --fully

# Check CFLAGS
export CFLAGS_riscv64imac_zero_linux_musl="-mcmodel=medany"
jolt build --std

Performance Considerations

Optimization Level

  • Use JOLT_GUEST_OPT=3 (default) for best proving performance
  • Use JOLT_GUEST_OPT=z or s only if binary size is critical
  • Lower optimization levels (0, 1, 2) increase trace length and proving time

Symbol Stripping

  • Stripped binaries are smaller and faster to load
  • Only preserve symbols when debugging is needed
  • JOLT_BACKTRACE=1 is zero-cost at runtime (only affects build)

Frame Pointers

  • --backtrace dwarf adds frame pointer overhead (~500 cycles for std guests)
  • Only needed for DWARF unwinding or external tooling
  • JOLT_BACKTRACE=1 provides backtraces without this cost

jolt run

Run the built binary on the emulator

jolt new

Create a new Jolt project

Build docs developers (and LLMs) love