π§ 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-srccomponent, which you can install withrustup component add rust-src. -
Rust and Cargo.
cargo install zargozargo 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 secsBy 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 secsYou 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 --releaseIf 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 -vTo 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.jsonOnce you have your target specification file you only have to call Zargo with the right target triple:
zargo build --target powerpc-unknown-linux-uclibcSome 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 = 1Zargo 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 = 1Zargo 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
stdand other standard crates depend on unstable features so it's not possible to build the sysroot with stable or beta. -
stdis built as rlib and dylib. The dylib needs a panic library and an allocator. If you do not specify thepanic-unwindfeature, you have to setpanic = "abort"inCargo.toml. -
To build without the
jemallocfeature include the following inZargo.toml:[dependencies.std] features = ["force_alloc_system"]
-
It's recommended that the
--targetoption is always used forzargo. -
Remember that
coreandstdwill get implicitly linked to your crate but all the other sysroot crates will not. -
Remember that rustc will always implicitly link
compiler_builtinsinto 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
- Apache License, Version 2.0 (LICENSE-APACHE
- MIT license LICENSE-MIT
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.