Xargo v0.3.0 released: Build Your Own `std`


#1

Greetings, Rustaceans!

I’m here to announce Xargo 0.3.0.

If you didn’t know, Xargo is a drop-in Cargo replacement (same CLI as Cargo) that builds and manages a “sysroot” for each compilation target. In practice, people use it build the core crate “on the fly” when working with targets that don’t have binary releases of the standard crates, like the thumbv*m-none-eabi* targets.

$ xargo 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

Version 0.3.0 gives Xargo a new feature: the Xargo.toml file, which can be used to specify which crates of the std facade to build and “how” to build them (i.e. which of their Cargo features to enable).

This version also lifts an artificial restriction xargo used to have: it now works with any built-in target.

In practice, the combination of these changes lets you build a custom version of the std crate and link your programs against that custom std.

The main use case I see right now is building programs that abort on panic (-C panic=abort) but with zero landing pads (the std that rustup installs contains landing pads as it was compiled with -C panic=unwind) which would result in smaller (and probably faster) binaries.

$ cat Xargo.toml
[target.i686-unknown-linux-gnu.dependencies.std]
features = ["jemalloc"]

$ tail -n3 Cargo.toml
[profile.release]
lto = true
panic = "abort"

# 2.3% smaller binary
$ xargo build --target i686-unknown-linux-gnu --release

Other potential applications could be re-building std to include MIR (for miri consumption) or re-building std to enable sanitizer support.

I’ll leave it up to you, folks, to figure out novel applications for this tool. :slight_smile:


#2

Wonderful. This is an awesome set of changes.


#3

Awesome! This will be monumental to working on Rust OS’s like Redox.


#4

So, just to be clear here: this still means you need to implement panic_fmt, right? Because even though there’s no landing pads, it still calls the handler before aborting.


#5

Yes, that’s correct. You have to implement “panic_fmt” in both cases.

-C panic=abort actually means “can’t unwind” because it doesn’t produce landing pads.

-C panic=unwind actually means “can unwind” because it produces landing pads.

In either case, you don’t have to necessarily handle panics by unwinding or aborting, you have other options: block (loop {}) or trigger a breakpoint or process::exit, etc.