Building Programs (cargo build-sbf)
Compile on-chain programs to sBPF ELF with cargo build-sbf, inspect artifact size, and prepare .so files for deploy.
Recipe
Quick-reference recipe card - copy-paste ready.
cargo build-sbf
cargo build-sbf --release
ls -lh target/deploy/*.so
wc -c target/deploy/my_program.soWhen to reach for this:
- Native
solana-programcrates without Anchor wrapper. - CI compile steps before
solana program deploy. - Tracking binary size regressions against CU/rent budgets.
- Verifying release optimizations before mainnet.
Working Example
cd programs/my_native_program
cargo build-sbf --manifest-path Cargo.toml --sbf-out-dir ../../target/deploy
ls -lh ../../target/deploy/
file ../../target/deploy/my_native_program.so
# Anchor equivalent (calls build-sbf under the hood)
cd ../../
anchor build
ls -lh target/deploy/my_program.soWhat this demonstrates:
cargo build-sbfemits deployable.soELF for BPF Loader.--sbf-out-dircontrols output location for monorepos.anchor buildwraps the same pipeline with IDL generation.
Deep Dive
How It Works
- Source compiles to sBPF bytecode with Solana-specific sysroot and
#![no_std]constraints. - Release profile enables optimizations critical for CU and binary size.
- Output
.sosize drives programdata rent at deploy time. - Program keypair JSON is separate from the
.soartifact.
Build Flags
| Flag | Purpose |
|---|---|
--release | Optimized production binary |
--sbf-out-dir | Custom deploy output directory |
--features | Enable crate feature flags |
--tools-version | Platform tools override (advanced) |
bash Notes
# Show compile warnings that affect CU (unused imports still cost parse time)
cargo build-sbf 2>&1 | tee build.log
# Compare debug vs release size
cargo build-sbf && wc -c target/deploy/*.so
cargo build-sbf --release && wc -c target/deploy/*.soGotchas
- Deploying debug builds - 2-10x larger and slower. Fix: always
--releasefor devnet/mainnet deploys. - Exceeding max program size - loader rejects huge ELFs. Fix: strip logs, split logic, optimize types; see CU/size guides.
- Wrong output path - deploy command points at stale
.so. Fix: script deploy from fixedtarget/deploypath. - std crate on-chain - linking fails or bloats binary. Fix: use
solana-program/anchor-langAPIs only. - Toolchain mismatch - build-sbf from Agave 3.x with 4.x validator quirks. Fix: align with Agave 4.1.1 platform tools.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
anchor build | Anchor workspaces + IDL | Pure native crates |
cargo build-bpf (legacy) | Old tutorials | New Agave 4.x projects |
| CI Docker image with pinned tools | Reproducible builds | Fast local iteration |
solana-verify build | Verifiable hash pipeline | Quick devnet tests |
FAQs
What is the difference between build-sbf and build-bpf?
sbf is the current Solana bytecode naming; build-bpf is legacy alias in older docs.
Where does Anchor put artifacts?
target/deploy/<program>.so at workspace root after anchor build.
How big can a program be?
Loader enforces a maximum deploy size (check current Agave release notes) - optimize early if approaching limits.
Do tests use the same build?
anchor test and cargo test-sbf compile test harnesses; deploy still uses release .so you choose explicitly.
Can I cross-compile on Apple Silicon?
Agave platform tools ship host-specific binaries - use Agave installer for your OS/arch.
How do features affect size?
Optional modules via #[cfg(feature)] keep unused code out of the .so.
What causes long compile times?
LLVM sBPF backend and LTO - incremental builds help; clean when switching toolchains.
Should CI cache target/?
Cache target/deploy keyed on toolchain + lockfile for faster pipelines.
How do I inspect symbols?
Use llvm-objdump from platform tools bundle on the .so for entrypoint verification.
Does build-sbf run clippy?
No - run cargo clippy separately for off-chain crates; on-chain lints are limited.
Related
- Deploying Programs - consume
.sooutput - Verifiable Builds (solana-verify) - reproducible artifacts
- Toolchain Overview - platform tools origin
- CU and Size Optimization - shrink binaries
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.