Skip to content

Commit 2b26a38

Browse files
committed
Format README.md
1 parent 8db1b57 commit 2b26a38

File tree

1 file changed

+51
-38
lines changed

1 file changed

+51
-38
lines changed

README.md

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ $ strip target/release/min-sized-rust
5555

5656
[Cargo defaults its optimization level to `3` for release builds][cargo-profile],
5757
which optimizes the binary for **speed**. To instruct Cargo to optimize for minimal binary
58-
**size**, use the `z` optimization level in
58+
**size**, use the `z` optimization level in
5959
[`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html):
6060

6161
[cargo-profile]: https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles
@@ -70,15 +70,15 @@ the
7070
[`opt-level` documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level):
7171

7272
> It is recommended to experiment with different levels to find the right balance for your project.
73-
There may be surprising results, such as ... the `"s"` and `"z"` levels not being necessarily
74-
smaller.
73+
> There may be surprising results, such as ... the `"s"` and `"z"` levels not being necessarily
74+
> smaller.
7575
7676
# Enable Link Time Optimization (LTO)
7777

7878
![Minimum Rust: 1.0](https://img.shields.io/badge/Minimum%20Rust%20Version-1.0-brightgreen.svg)
7979

80-
By default,
81-
[Cargo instructs compilation units to be compiled and optimized in isolation][cargo-profile].
80+
By default,
81+
[Cargo instructs compilation units to be compiled and optimized in isolation][cargo-profile].
8282
[LTO](https://llvm.org/docs/LinkTimeOptimization.html) instructs the linker to optimize at the
8383
link stage. This can, for example, remove dead code and often times reduces binary size.
8484

@@ -94,14 +94,14 @@ lto = true
9494
![Minimum Rust: 1.28](https://img.shields.io/badge/Minimum%20Rust%20Version-1.28-brightgreen.svg)
9595
![Maximum Rust: 1.31](https://img.shields.io/badge/Maximum%20Rust%20Version-1.31-brightgreen.svg)
9696

97-
As of Rust 1.32,
98-
[`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html).
99-
**If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this
97+
As of Rust 1.32,
98+
[`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html).
99+
**If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this
100100
feature**.
101101

102102
**Prior to Rust 1.32**, to improve performance on some platforms Rust bundled
103-
[jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often
104-
outperforms the default system allocator. Bundling jemalloc added around 200KB
103+
[jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often
104+
outperforms the default system allocator. Bundling jemalloc added around 200KB
105105
to the resulting binary, however.
106106

107107
To remove `jemalloc` on Rust 1.28 - Rust 1.31, add this code to the top of `main.rs`:
@@ -116,7 +116,7 @@ static A: System = System;
116116
# Reduce Parallel Code Generation Units to Increase Optimization
117117

118118
[By default][cargo-profile], Cargo specifies 16 parallel codegen units for release builds.
119-
This improves compile times, but prevents some optimizations.
119+
This improves compile times, but prevents some optimizations.
120120

121121
Set this to `1` in `Cargo.toml` to allow for maximum size reduction optimizations:
122122

@@ -130,12 +130,12 @@ codegen-units = 1
130130
![Minimum Rust: 1.10](https://img.shields.io/badge/Minimum%20Rust%20Version-1.10-brightgreen.svg)
131131

132132
> **Note**: Up to this point, the features discussed to reduce binary size did not have an
133-
impact on the behaviour of the program (only its execution speed). This feature does
134-
have an impact on behavior.
133+
> impact on the behaviour of the program (only its execution speed). This feature does
134+
> have an impact on behavior.
135135
136-
[By default][cargo-profile], when Rust code encounters a situation when it must call `panic!()`,
137-
it unwinds the stack and produces a helpful backtrace. The unwinding code, however, does require
138-
extra binary size. `rustc` can be instructed to abort immediately rather than unwind, which
136+
[By default][cargo-profile], when Rust code encounters a situation when it must call `panic!()`,
137+
it unwinds the stack and produces a helpful backtrace. The unwinding code, however, does require
138+
extra binary size. `rustc` can be instructed to abort immediately rather than unwind, which
139139
removes the need for this extra unwinding code.
140140

141141
Enable this in `Cargo.toml`:
@@ -166,7 +166,7 @@ $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build --release
166166
![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg)
167167

168168
> **Note**: See also [Xargo](https://github.com/japaric/xargo), the predecessor to `build-std`.
169-
[Xargo is currently in maintenance status](https://github.com/japaric/xargo/issues/193).
169+
[Xargo is currently in maintenance status](https://github.com/japaric/xargo/issues/193).
170170

171171
> Example project is located in the [`build_std`](build_std) folder.
172172
@@ -179,10 +179,10 @@ aggressively optimize for size.
179179

180180
1. The prebuilt `libstd` is optimized for speed, not size.
181181

182-
2. It's not possible to remove portions of `libstd` that are not used in a particular application
182+
2. It's not possible to remove portions of `libstd` that are not used in a particular application
183183
(e.g. LTO and panic behaviour).
184184

185-
This is where [`build-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std)
185+
This is where [`build-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std)
186186
comes in. The `build-std` feature is able to compile `libstd` with your application from the
187187
source. It does this with the `rust-src` component that `rustup` conveniently provides.
188188

@@ -214,7 +214,7 @@ On macOS, the final stripped binary size is reduced to 51KB.
214214
![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg)
215215

216216
Even if `panic = "abort"` is specified in `Cargo.toml`, `rustc` will still include panic strings
217-
and formatting code in final binary by default.
217+
and formatting code in final binary by default.
218218
[An unstable `panic_immediate_abort` feature](https://github.com/rust-lang/rust/pull/55011)
219219
has been merged into the `nightly` `rustc` compiler to address this.
220220

@@ -235,29 +235,27 @@ On macOS, the final stripped binary size is reduced to 30KB.
235235

236236
> Example project is located in the [`no_main`](no_main) folder.
237237
238-
> This section was contributed in part by [@vi](https://github.com/vi)
239-
240238
Up until this point, we haven't restricted what utilities we used from `libstd`. In this section
241239
we will restrict our usage of `libstd` in order to reduce binary size further.
242240

243-
If you want an executable smaller than 20 kilobytes, Rust's string formatting code,
244-
[`core::fmt`](https://doc.rust-lang.org/core/fmt/index.html) must
245-
be removed. `panic_immediate_abort` only removes some usages of this code. There is a lot of other
241+
If you want an executable smaller than 20 kilobytes, Rust's string formatting code,
242+
[`core::fmt`](https://doc.rust-lang.org/core/fmt/index.html) must
243+
be removed. `panic_immediate_abort` only removes some usages of this code. There is a lot of other
246244
code that uses formatting in some cases. That includes Rust's "pre-main" code in `libstd`.
247245

248-
By using a C entry point (by adding the `#![no_main]` attribute) , managing stdio manually, and
249-
carefully analyzing which chunks of code you or your dependencies include, you can sometimes
246+
By using a C entry point (by adding the `#![no_main]` attribute) , managing stdio manually, and
247+
carefully analyzing which chunks of code you or your dependencies include, you can sometimes
250248
make use of `libstd` while avoiding bloated `core::fmt`.
251249

252-
Expect the code to be hacky and unportable, with more `unsafe{}`s than usual. It feels like
250+
Expect the code to be hacky and unportable, with more `unsafe{}`s than usual. It feels like
253251
`no_std`, but with `libstd`.
254252

255-
Start with an empty executable, ensure
256-
[`xargo bloat --release --target=...`](https://github.com/RazrFalcon/cargo-bloat) contains no
257-
`core::fmt` or something about padding. Add (uncomment) a little bit. See that `xargo bloat` now
258-
reports drastically more. Review source code that you've just added. Probably some external crate or
253+
Start with an empty executable, ensure
254+
[`xargo bloat --release --target=...`](https://github.com/RazrFalcon/cargo-bloat) contains no
255+
`core::fmt` or something about padding. Add (uncomment) a little bit. See that `xargo bloat` now
256+
reports drastically more. Review source code that you've just added. Probably some external crate or
259257
a new `libstd` function is used. Recurse into that with your review process
260-
(it requires `[replace]` Cargo dependencies and maybe digging in `libstd`), find out why it
258+
(it requires `[replace]` Cargo dependencies and maybe digging in `libstd`), find out why it
261259
weighs more than it should. Choose alternative way or patch dependencies to avoid unnecessary
262260
features. Uncomment a bit more of your code, debug exploded size with `xargo bloat` and so on.
263261

@@ -306,8 +304,8 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! {
306304
Up until this point, all size-reducing techniques were Rust-specific. This section describes
307305
a language-agnostic binary packing tool that is an option to reduce binary size further.
308306

309-
[UPX](https://github.com/upx/upx) is a powerful tool for creating a self contained, compressed
310-
binary with no addition runtime requirements. It claims to typically reduce binary size by 50-70%,
307+
[UPX](https://github.com/upx/upx) is a powerful tool for creating a self-contained, compressed
308+
binary with no addition runtime requirements. It claims to typically reduce binary size by 50-70%,
311309
but the actual result depends on your executable.
312310

313311
```bash
@@ -319,7 +317,7 @@ heuristic-based anti-virus software because malware often uses UPX.
319317

320318
# Tools
321319

322-
- [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the
320+
- [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the
323321
space in your executable.
324322
- [`cargo-unused-features`](https://github.com/TimonPost/cargo-unused-features) - Find and prune
325323
enabled but potentially unused feature flags from your project.
@@ -329,8 +327,8 @@ heuristic-based anti-virus software because malware often uses UPX.
329327

330328
# Containers
331329

332-
Sometimes it's advantageous to deploy Rust into containers
333-
(e.g. [Docker](https://www.docker.com/)). There are several great existing resources to help
330+
Sometimes it's advantageous to deploy Rust into containers
331+
(e.g. [Docker](https://www.docker.com/)). There are several great existing resources to help
334332
create minimum sized container images that run Rust binaries.
335333

336334
- [Official `rust:alpine` image](https://hub.docker.com/_/rust)
@@ -359,20 +357,35 @@ create minimum sized container images that run Rust binaries.
359357
- [Shrinking `.wasm` Code Size][shrinking-wasm-code-size]
360358

361359
[151-byte-static-linux-binary]: https://mainisusuallyafunction.blogspot.com/2015/01/151-byte-static-linux-binary-in-rust.html
360+
362361
[why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html
362+
363363
[fmt-unreasonably-expensive]: https://jamesmunns.com/blog/fmt-unreasonably-expensive/
364+
364365
[tiny-windows-exe]: https://www.codeslow.com/2019/12/tiny-windows-executable-in-rust.html
366+
365367
[tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/
368+
366369
[gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/
370+
367371
[optimizing-rust-binary-size]: https://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html
372+
368373
[minimizing-mender-rust]: https://mender.io/blog/building-mender-rust-in-yocto-and-minimizing-the-binary-size
374+
369375
[optimize-with-cargo-and-semver]: https://oknozor.github.io/blog/optimize-rust-binary-size/
376+
370377
[tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075
378+
371379
[avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/
380+
372381
[a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/
382+
373383
[dark-side-of-inlining]: https://nickb.dev/blog/the-dark-side-of-inlining-and-monomorphization/
384+
374385
[making-rust-binaries-smaller-by-default]: https://kobzol.github.io/rust/cargo/2024/01/23/making-rust-binaries-smaller-by-default.html
386+
375387
[min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows
388+
376389
[shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html
377390

378391
# Organizations

0 commit comments

Comments
 (0)