Skip to content

Commit

Permalink
Add an example showing Eyra's small code size
Browse files Browse the repository at this point in the history
Add an example showing the use of [min-sized-rust] techiques
to reduce code size.

As of this writing, using the same optimizations without Eyra,
using `x86_64-unknown-linux-musl`, produces a hello world binary
in 50776 bytes, while using them with Eyra uses just 37912 bytes.

[min-sized-rust]: https://github.com/johnthagen/min-sized-rust
  • Loading branch information
sunfishcode committed Oct 9, 2023
1 parent 1794164 commit 4c730f0
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 1 deletion.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ extern crate eyra;

to ensure that the Eyra libraries are linked in.

## Reducing code size

Eyra can be used with the techniques in [min-sized-rust] to produce very
small statically-linked binaries. Check out [the hello-world-small example].

[min-sized-rust]: https://github.com/johnthagen/min-sized-rust
[the hello-world-small example]: https://github.com/sunfishcode/eyra/tree/main/example-crates/hello-world-small/

## Background

Eyra is similar to [Mustang] and uses the same underlying code, but instead
Expand Down
2 changes: 2 additions & 0 deletions example-crates/hello-world-small/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
19 changes: 19 additions & 0 deletions example-crates/hello-world-small/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "hello-world-small"
version = "0.0.0"
edition = "2021"
publish = false

[dependencies]
eyra = { path = "../.." }

[profile.release]
# Enable options from min-sized-rust:
strip = true # Automatically strip symbols from the binary.
opt-level = "z" # Optimize for size.
lto = true
codegen-units = 1
panic = "abort"

# This is just an example crate, and not part of the c-ward workspace.
[workspace]
31 changes: 31 additions & 0 deletions example-crates/hello-world-small/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
This crate demonstrates the use of Eyra with a smaller binary size!

This is the same as the [hello-world] example, but enables some options
described in [min-sized-rust] to reduce the size of the final binary.

It uses the [workaround to support -Zbuild-std], and can be built with
a command like this:

```console
$ RUSTFLAGS="-Zlocation-detail=none -C relocation-model=static -Ctarget-feature=+crt-static" cargo +nightly run -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu --release
```

This applies all the techniques described on the [min-sized-rust] page
before [Remove `core::fmt` with `#![no_main]` and Careful Usage of `libstd`].

As of this writing, using all these same optimizations without Eyra, using
`x86_64-unknown-linux-musl` (which produces smaller statically-linked binaries
than `x86_64-unknown-linux-gnu`), compiles to 50776 bytes, while this Eyra
example currently compiles to 37912 bytes.

If you're interested in going further down the `#![no_main]`/`#![no_std]`
path, consider [using Origin directly] which can get down to 408 bytes. Or,
consider using [Origin Studio] if you want to go there but still have
`println!`.

[hello-world]: https://github.com/sunfishcode/eyra/tree/main/example-crates/hello-world/
[min-sized-rust]: https://github.com/johnthagen/min-sized-rust
[workaround to support -Zbuild-std]: https://github.com/sunfishcode/eyra/blob/main/README.md#compatibility-with--zbuild-std
[Remove `core::fmt` with `#![no_main]` and Careful Usage of `libstd`]: https://github.com/johnthagen/min-sized-rust#remove-corefmt-with-no_main-and-careful-usage-of-libstd
[using Origin directly]: https://github.com/sunfishcode/origin/tree/main/example-crates/tiny
[Origin Studio]: https://github.com/sunfishcode/origin-studio
4 changes: 4 additions & 0 deletions example-crates/hello-world-small/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
// Pass -nostartfiles to the linker.
println!("cargo:rustc-link-arg=-nostartfiles");
}
5 changes: 5 additions & 0 deletions example-crates/hello-world-small/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extern crate eyra;

fn main() {
println!("Hello, world!");
}
21 changes: 20 additions & 1 deletion tests/example_crates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn example_crate_hello_world() {
#[test]
fn example_crate_hello_world_lto() {
test_crate(
"hello-world",
"hello-world-lto",
&["--release"],
&[],
"Hello, world!\n",
Expand All @@ -71,6 +71,25 @@ fn example_crate_hello_world_lto() {
);
}

#[test]
fn example_crate_hello_world_small() {
test_crate(
"hello-world-small",
&[
"--release",
"-Zbuild-std=std,panic_abort",
"-Zbuild-std-features=panic_immediate_abort",
],
&[(
"RUSTFLAGS",
"-Zlocation-detail=none -Crelocation-model=static -Ctarget-feature=+crt-static",
)],
"Hello, world!\n",
"",
None,
);
}

#[test]
fn example_crate_extern_crate_hello_world() {
test_crate(
Expand Down

0 comments on commit 4c730f0

Please sign in to comment.