| Crates.io | zargo |
| lib.rs | zargo |
| version | 0.1.1 |
| created_at | 2025-12-08 17:36:47.695038+00 |
| updated_at | 2025-12-09 13:07:53.743762+00 |
| description | The sysroot manager that lets you build and customize `std` |
| homepage | |
| repository | https://github.com/fereidani/zargo |
| max_upload_size | |
| id | 1974111 |
| size | 134,080 |
zargo๐ง The sysroot manager that lets you build and customize
std
Note: Zargo is a hard fork of xargo.
Zargo builds and manages "sysroots" (cf. rustc --print sysroot). Making it
easy to cross compile Rust crates for targets that don't have binary
releases of the standard crates, like the thumbv*m-none-eabi* targets. And
it also lets you build a customized std crate, e.g. compiled with -C panic=abort, for your target.
The rust-src component, which you can install with rustup component add rust-src.
Rust and Cargo.
cargo install zargo
no_stdzargo has the exact same CLI as cargo.
# This Just Works
zargo build --target thumbv6m-none-eabi
Compiling core v0.0.0 (file://$SYSROOT/lib/rustlib/src/rust/src/libcore)
Finished release [optimized] target(s) in 11.61 secs
Compiling lib v0.1.0 (file://$PWD)
Finished debug [unoptimized + debuginfo] target(s) in 0.5 secs
zargo will cache the sysroot, in this case the core crate, so the next
build command will be (very) fast.
$ zargo build --target thumbv6m-none-eabi
Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
By default, zargo will only compile the core crate for the target. If you
need a bigger subset of the standard crates, specify the dependencies in a
Zargo.toml at the root of your Cargo project (right next to Cargo.toml).
# Alternatively you can use [build.dependencies]
# the syntax is the same as Cargo.toml's; you don't need to specify path or git
[target.thumbv6m-none-eabi.dependencies]
collections = {}
$ zargo build --target thumbv6m-none-eabi
Compiling core v0.0.0 (file://$SYSROOT/lib/rustlib/src/rust/src/libcore)
Compiling alloc v0.0.0 (file://$SYSROOT/lib/rustlib/src/rust/src/liballoc)
Compiling std_unicode v0.0.0 (file://$SYSROOT/lib/rustlib/src/rust/src/libstd_unicode)
Compiling collections v0.0.0 (file://$SYSROOT/lib/rustlib/src/rust/src/libcollections)
Finished release [optimized] target(s) in 15.26 secs
Compiling lib v0.1.0 (file://$PWD)
Finished debug [unoptimized + debuginfo] target(s) in 0.5 secs
stdYou can compile a customized std crate as well, just specify which Cargo
features to enable.
# Build `std` with `-C panic=abort` (default) and with jemalloc as the default
# allocator
[target.i686-unknown-linux-gnu.dependencies.std]
features = ["jemalloc"]
# Needed to compile `std` with `-C panic=abort`
[profile.release]
panic = "abort"
zargo run --target i686-unknown-linux-gnu --release
If you'd like to know what zargo is doing under the hood, pass the verbose,
-v, flag to it.
zargo build --target thumbv6m-none-eabi -v
To use zargo with a development version of rustc (compiled from source), set the ZARGO_RUST_SRC environment variable to specify the location of your Rust source code.
# `$ZARGO_RUST_SRC` must point to the `library` subfolder of a Rust checkout.
export ZARGO_RUST_SRC=/path/to/rust/library
zargo build --target msp430-none-elf
โ ๏ธ NOTE This also works with the nightly channel but it's not recommended as the Rust source may diverge from what your compiler is able to compile as it may make use of newer features that your compiler doesn't understand.
Zargo uses the same custom rustc flags that apply to the target Cargo project.
So you can use either the RUSTFLAGS env variable or a .cargo/config
configuration file to specify custom rustc flags.
# build the sysroot with debug information
RUSTFLAGS='-g' zargo build --target x86_64-unknown-linux-gnu
# Alternatively
[build]
rustflags = ["-g"]
At some point you may want to develop a program for a target that's not officially supported by rustc. Zargo's got your back! It supports custom targets via target specifications files, which are not really documented anywhere other than in the compiler source code.
For example, let's say that you want to cross compile a program for a PowerPC Linux systems that uses uclibc instead of glibc. You can start by dumping the specification of a similar target into a file:
rustc -Z unstable-options --print target-spec-json --target powerpc-unknown-linux-gnu | tee powerpc-unknown-linux-uclibc.json
Once you have your target specification file you only have to call Zargo with the right target triple:
zargo build --target powerpc-unknown-linux-uclibc
Some standard crates have implicit dependencies between them. To compile a sysroot that contains such crates you can perform the build in stages:
[dependencies.std]
stage = 0
[dependencies.test]
stage = 1
Zargo lets you create a sysroot with custom crates:
# First build some standard crates.
[dependencies.alloc]
[dependencies.panic_abort]
[dependencies.panic_unwind]
# Then build our custom facade.
[dependencies.std]
git = "https://github.com/rust3ds/ctru-rs"
stage = 1
Zargo supports the patch feature from Cargo:
[patch.crates-io.libc]
path = "path/to/custom/libc"
Zargo supports performing a 'check build' of the sysroot via the zargo-check command:
zargo-check build --target thumbv6m-none-eabi
Zargo won't build a sysroot when used with stable or beta Rust. This is
because std and other standard crates depend on unstable features so it's
not possible to build the sysroot with stable or beta.
std is built as rlib and dylib. The dylib needs a panic library and an
allocator. If you do not specify the panic-unwind feature, you have to set
panic = "abort" in Cargo.toml.
To build without the jemalloc feature include the following in Zargo.toml:
[dependencies.std]
features = ["force_alloc_system"]
It's recommended that the --target option is always used for zargo.
Remember that core and std will get implicitly linked to your crate but all the other sysroot
crates will not.
Remember that rustc will always implicitly link compiler_builtins into your final binary.
Care must be taken not to end up with any "top-level" crates (core, std, compiler-builtins)
twice in the sysroot.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.