zargo

Crates.iozargo
lib.rszargo
version0.1.1
created_at2025-12-08 17:36:47.695038+00
updated_at2025-12-09 13:07:53.743762+00
descriptionThe sysroot manager that lets you build and customize `std`
homepage
repositoryhttps://github.com/fereidani/zargo
max_upload_size
id1974111
size134,080
Khashayar Fereidani (fereidani)

documentation

https://github.com/fereidani/zargo#zargo

README

Crates.io License CI Docs

๐Ÿš€ 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.

๐Ÿ“‹ Dependencies

  • The rust-src component, which you can install with rustup component add rust-src.

  • Rust and Cargo.

๐Ÿ“ฆ Installation

cargo install zargo

๐Ÿš€ Usage

๐Ÿ”ฅ no_std

zargo 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

๐Ÿ“š std

You 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

๐Ÿงช Dev channel

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.

โš™๏ธ Compiling the sysroot with custom rustc flags

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"]

๐ŸŽฏ Compiling the sysroot for a custom target

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

๐Ÿ”„ Multi-stage builds

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

๐Ÿ“ฆ Creating a sysroot with custom crates

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

๐Ÿ”ง Patching sysroot crates

Zargo supports the patch feature from Cargo:

[patch.crates-io.libc]
path = "path/to/custom/libc"

โœ… Check-only sysroot build

Zargo supports performing a 'check build' of the sysroot via the zargo-check command:

zargo-check build --target thumbv6m-none-eabi

โš ๏ธ Caveats / gotchas

  • 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.

๐Ÿ“„ License

Licensed under either of

at your option.

๐Ÿค Contribution

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.

Commit count: 0

cargo fmt