[](https://crates.io/crates/zargo)
[](https://github.com/rust-lang/zargo)
[](https://github.com/rust-lang/zargo/actions)
[](https://docs.rs/zargo)
# ๐ `zargo`
> ๐ง The sysroot manager that lets you build and customize `std`
**Note:** Zargo is a hard fork of [xargo](https://github.com/japaric/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
```bash
cargo install zargo
```
## ๐ Usage
### ๐ฅ `no_std`
`zargo` has the exact same CLI as `cargo`.
```bash
# 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.
```bash
$ 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`).
```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 = {}
```
```bash
$ 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.
```toml
# Build `std` with `-C panic=abort` (default) and with jemalloc as the default
# allocator
[target.i686-unknown-linux-gnu.dependencies.std]
features = ["jemalloc"]
```
```toml
# Needed to compile `std` with `-C panic=abort`
[profile.release]
panic = "abort"
```
```bash
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.
```bash
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.
```bash
# `$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.
```bash
# build the sysroot with debug information
RUSTFLAGS='-g' zargo build --target x86_64-unknown-linux-gnu
```
```toml
# 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][spec-docs].
[spec-docs]: https://github.com/rust-lang/rust/blob/256e497fe63bf4b13f7c0b58fa17360ca849c54d/src/librustc_back/target/mod.rs#L228-L409
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:
```bash
Once you have your target specification file you only have to call Zargo with
the right target triple:
```bash
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:
```toml
[dependencies.std]
stage = 0
[dependencies.test]
stage = 1
```
### ๐ฆ Creating a sysroot with custom crates
Zargo lets you create a sysroot with custom crates:
```toml
# 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:
```toml
[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:
```bash
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`:
```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
- Apache License, Version 2.0 ([LICENSE-APACHE](./LICENSE-APACHE)
- MIT license [LICENSE-MIT](./LICENSE-MIT)
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.