From e386a678166aeb0f751e97c4c3874f1ea55d49ed Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 23 Jul 2022 09:20:42 -0400 Subject: [PATCH 01/48] Add editorconfig --- .editorconfig | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a24d209 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*] +max_line_length = 100 From 4aaf578fd9b57729d51b84a116369a6901c634b7 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 23 Jul 2022 09:22:01 -0400 Subject: [PATCH 02/48] =?UTF-8?q?Add=20reference=20to=20Tighten=20rust?= =?UTF-8?q?=E2=80=99s=20belt:=20shrinking=20embedded=20Rust=20binaries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9921627..b2cf5ee 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,7 @@ create minimum sized Docker containers that run Rust binaries. - [Tiny Windows executable in Rust - 2019][tiny-windows-exe] - [Making a really tiny WebAssembly graphics demos - 2019][tiny-webassembly-graphics] - [Reducing the size of the Rust GStreamer plugin - 2020][gstreamer-plugin] +- [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size [why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html @@ -331,6 +332,7 @@ create minimum sized Docker containers that run Rust binaries. [tiny-windows-exe]: https://www.codeslow.com/2019/12/tiny-windows-executable-in-rust.html [tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/ [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ +[tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows From d3fd38f0f6e909db5b4698f685f446f8bef632f7 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Thu, 28 Jul 2022 19:40:51 -0400 Subject: [PATCH 03/48] Update copyright year --- LICENSE.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 6fc1709..d4e7692 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2018-2021 John Hagen +Copyright (c) 2018-2022 John Hagen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. \ No newline at end of file +IN THE SOFTWARE. From b86e715e0c811fa908f0ac037c5e1bc070ec7f12 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 14 Aug 2022 19:50:52 -0400 Subject: [PATCH 04/48] Update CI to actions/checkout@v3 (#40) --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b2ec948..5a8067b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: toolchain: [ stable, 1.28.0, nightly ] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.toolchain }} @@ -28,7 +28,7 @@ jobs: toolchain: [ stable, 1.30.0, nightly ] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: ${{ matrix.toolchain }} @@ -43,7 +43,7 @@ jobs: project_dir: [ build_std, no_main ] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: nightly From 8cbbe15c96a174c8b9e561461a669826892a9164 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 14 Aug 2022 20:04:32 -0400 Subject: [PATCH 05/48] Remove actions-rs/cargo (#42) --- .github/workflows/build.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5a8067b..762b1b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,10 +16,8 @@ jobs: with: toolchain: ${{ matrix.toolchain }} override: true - - uses: actions-rs/cargo@v1 - with: - command: build - args: --release --all-features + - name: Build + run: cargo build --release --all-features no_std: name: no_std strategy: From e29108d2803d0b2afcc1471709644e2b87d26c8d Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 14 Aug 2022 20:12:04 -0400 Subject: [PATCH 06/48] Remove usages of deprecated actions-rs (#43) --- .github/workflows/build.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 762b1b4..1151757 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,10 +12,9 @@ jobs: runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} - override: true - name: Build run: cargo build --release --all-features no_std: @@ -27,10 +26,9 @@ jobs: runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} - override: true - name: Build working-directory: no_std run: cargo build --release --all-features @@ -42,10 +40,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 + - uses: dtolnay/rust-toolchain@master with: toolchain: nightly - override: true - name: Build working-directory: ${{ matrix.project_dir }} run: > From d4611cb9be0abfdb56383045aad4c29e24c2e6e5 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 22 Oct 2022 19:11:42 -0400 Subject: [PATCH 07/48] Add reference to Avoiding allocations in Rust to shrink Wasm modules --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b2cf5ee..c027bbf 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,7 @@ create minimum sized Docker containers that run Rust binaries. - [Making a really tiny WebAssembly graphics demos - 2019][tiny-webassembly-graphics] - [Reducing the size of the Rust GStreamer plugin - 2020][gstreamer-plugin] - [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] +- [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size [why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html @@ -333,6 +334,7 @@ create minimum sized Docker containers that run Rust binaries. [tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/ [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 +[avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows From f6f4002220cd59a4535d60decf458276070c1dde Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 26 Oct 2022 15:04:18 -0400 Subject: [PATCH 08/48] Add reference to "A very small Rust binary indeed" --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c027bbf..907cad7 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,7 @@ create minimum sized Docker containers that run Rust binaries. - [Reducing the size of the Rust GStreamer plugin - 2020][gstreamer-plugin] - [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] +- [A very small Rust binary indeed - 2022][a-very-small-rust-binary] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size [why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html @@ -335,6 +336,7 @@ create minimum sized Docker containers that run Rust binaries. [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ +[a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows From d6b3dd411af7fd5bf62ff7818778e88851dc6c2d Mon Sep 17 00:00:00 2001 From: johnthagen Date: Thu, 27 Oct 2022 08:24:35 -0400 Subject: [PATCH 09/48] Add reference to cargo-unusued-features --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 907cad7..79e42db 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,8 @@ heuristic-based anti-virus software because malware often uses UPX. - [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the space in your executable. +- [`cargo-unused-features`](https://github.com/TimonPost/cargo-unused-features) - Find and prune + enabled, but, potentially unused feature flags from your project. - [`momo`](https://github.com/llogiq/momo) - `proc_macro` crate to help keeping the code footprint of generic methods in check. - [Twiggy](https://rustwasm.github.io/twiggy/index.html) - A code size profiler for Wasm. From 2d0160b8c76103cf2551bdff257d54775d97db4d Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 28 Oct 2022 13:51:08 -0400 Subject: [PATCH 10/48] Fix grammar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79e42db..1725e63 100644 --- a/README.md +++ b/README.md @@ -301,7 +301,7 @@ heuristic-based anti-virus software because malware often uses UPX. - [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the space in your executable. - [`cargo-unused-features`](https://github.com/TimonPost/cargo-unused-features) - Find and prune - enabled, but, potentially unused feature flags from your project. + enabled but potentially unused feature flags from your project. - [`momo`](https://github.com/llogiq/momo) - `proc_macro` crate to help keeping the code footprint of generic methods in check. - [Twiggy](https://rustwasm.github.io/twiggy/index.html) - A code size profiler for Wasm. From eb92787500f586761849e5100dadf188f975f67f Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 1 Nov 2022 15:41:40 -0400 Subject: [PATCH 11/48] Add reference to "151-byte static Linux binary in Rust" --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 1725e63..533c3af 100644 --- a/README.md +++ b/README.md @@ -319,6 +319,7 @@ create minimum sized Docker containers that run Rust binaries. # References +- [151-byte static Linux binary in Rust - 2015][151-byte-static-linux-binary] - [Why is a Rust executable large? - 2016][why-rust-binary-large] - [Freestanding Rust Binary - 2018](https://os.phil-opp.com/freestanding-rust-binary/) - [Tiny Rocket - 2018](https://jamesmunns.com/blog/tinyrocket/) @@ -331,6 +332,7 @@ create minimum sized Docker containers that run Rust binaries. - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size +[151-byte-static-linux-binary]: https://mainisusuallyafunction.blogspot.com/2015/01/151-byte-static-linux-binary-in-rust.html [why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html [fmt-unreasonably-expensive]: https://jamesmunns.com/blog/fmt-unreasonably-expensive/ [tiny-windows-exe]: https://www.codeslow.com/2019/12/tiny-windows-executable-in-rust.html From b50f068de3b2d7283f30a936a96638a303b3a659 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 6 Nov 2022 16:13:28 -0500 Subject: [PATCH 12/48] Improve wording about container images --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 533c3af..329ea48 100644 --- a/README.md +++ b/README.md @@ -310,7 +310,7 @@ heuristic-based anti-virus software because malware often uses UPX. Sometimes it's advantageous to deploy Rust into containers (e.g. [Docker](https://www.docker.com/)). There are several great existing resources to help -create minimum sized Docker containers that run Rust binaries. +create minimum sized container images that run Rust binaries. - [mini-docker-rust](https://github.com/kpcyrd/mini-docker-rust) - [rust-musl-builder](https://github.com/emk/rust-musl-builder) From 43065669edd1a8395a2fc4321d90d5d440140aaf Mon Sep 17 00:00:00 2001 From: johnthagen Date: Mon, 7 Nov 2022 06:52:22 -0500 Subject: [PATCH 13/48] Add reference to optimizing Rust binary size article --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 329ea48..83596a7 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,7 @@ create minimum sized container images that run Rust binaries. - [Tiny Windows executable in Rust - 2019][tiny-windows-exe] - [Making a really tiny WebAssembly graphics demos - 2019][tiny-webassembly-graphics] - [Reducing the size of the Rust GStreamer plugin - 2020][gstreamer-plugin] +- [Optimizing Rust Binary Size - 2020][optimizing-rust-binary-size] - [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] @@ -338,6 +339,7 @@ create minimum sized container images that run Rust binaries. [tiny-windows-exe]: https://www.codeslow.com/2019/12/tiny-windows-executable-in-rust.html [tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/ [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ +[optimizing-rust-binary-size]: https://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ From 5a65a4b49ad85f9dcb7fb963476037691e15fd1c Mon Sep 17 00:00:00 2001 From: johnthagen Date: Mon, 7 Nov 2022 07:12:02 -0500 Subject: [PATCH 14/48] Pin macos CI to macos-11 (#50) --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1151757..3a344ef 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,7 +7,8 @@ jobs: name: Default strategy: matrix: - platform: [ ubuntu-latest, macos-latest, windows-latest ] + # TODO: Fix libc build issues on macos-latest, which is now macos-12. + platform: [ ubuntu-latest, macos-11, windows-latest ] toolchain: [ stable, 1.28.0, nightly ] runs-on: ${{ matrix.platform }} steps: @@ -21,7 +22,7 @@ jobs: name: no_std strategy: matrix: - platform: [ ubuntu-latest, macos-latest ] + platform: [ ubuntu-latest, macos-11 ] toolchain: [ stable, 1.30.0, nightly ] runs-on: ${{ matrix.platform }} steps: From 1f8158e6a54c1d40b22880167d8e1cafabdea7c1 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 8 Nov 2022 12:43:57 -0500 Subject: [PATCH 15/48] Drop Rust 1.28 and 1.30 from CI (#51) * Drop Rust 1.28 and 1.30 from CI * Cargo update --- .github/workflows/build.yml | 9 ++++----- Cargo.toml | 1 + build_std/Cargo.toml | 2 +- no_main/Cargo.toml | 2 +- no_std/Cargo.lock | 12 +++++++----- no_std/Cargo.toml | 1 + 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3a344ef..a7aab8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,9 +7,8 @@ jobs: name: Default strategy: matrix: - # TODO: Fix libc build issues on macos-latest, which is now macos-12. - platform: [ ubuntu-latest, macos-11, windows-latest ] - toolchain: [ stable, 1.28.0, nightly ] + platform: [ ubuntu-latest, macos-latest, windows-latest ] + toolchain: [ stable, nightly ] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 @@ -22,8 +21,8 @@ jobs: name: no_std strategy: matrix: - platform: [ ubuntu-latest, macos-11 ] - toolchain: [ stable, 1.30.0, nightly ] + platform: [ ubuntu-latest, macos-latest ] + toolchain: [ stable, nightly ] runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 diff --git a/Cargo.toml b/Cargo.toml index 1db9e9d..25b75c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "min-sized-rust" version = "0.1.0" authors = ["johnthagen "] +edition = "2021" license-file = "LICENSE.txt" [dependencies] diff --git a/build_std/Cargo.toml b/build_std/Cargo.toml index f80c8ce..b33bfe1 100644 --- a/build_std/Cargo.toml +++ b/build_std/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "build_std" version = "0.1.0" -edition = "2018" +edition = "2021" license = "MIT" [dependencies] diff --git a/no_main/Cargo.toml b/no_main/Cargo.toml index cb3b7d6..20004a7 100644 --- a/no_main/Cargo.toml +++ b/no_main/Cargo.toml @@ -2,7 +2,7 @@ name = "no_main" version = "0.1.0" authors = ["johnthagen ", "Vitaly '_Vi' Shukela "] -edition = "2018" +edition = "2021" license = "MIT" [dependencies] diff --git a/no_std/Cargo.lock b/no_std/Cargo.lock index 4879888..a9ed9a7 100644 --- a/no_std/Cargo.lock +++ b/no_std/Cargo.lock @@ -1,14 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + [[package]] name = "libc" -version = "0.2.99" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "min-sized-no_std" version = "0.1.0" dependencies = [ - "libc 0.2.99 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] - -[metadata] -"checksum libc 0.2.99 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" diff --git a/no_std/Cargo.toml b/no_std/Cargo.toml index 3d6c47b..108db3f 100644 --- a/no_std/Cargo.toml +++ b/no_std/Cargo.toml @@ -2,6 +2,7 @@ name = "min-sized-no_std" version = "0.1.0" authors = ["johnthagen "] +edition = "2021" license = "MIT" [dependencies] From c5f90f3054d550f6b37abc217ef4a12c89f5d6d8 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 21 Dec 2022 08:46:00 -0500 Subject: [PATCH 16/48] Replace `rust-musl-builder` with official Rust alpine image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83596a7..ebf9b99 100644 --- a/README.md +++ b/README.md @@ -312,8 +312,8 @@ Sometimes it's advantageous to deploy Rust into containers (e.g. [Docker](https://www.docker.com/)). There are several great existing resources to help create minimum sized container images that run Rust binaries. +- [Official `rust:alpine` image](https://hub.docker.com/_/rust) - [mini-docker-rust](https://github.com/kpcyrd/mini-docker-rust) -- [rust-musl-builder](https://github.com/emk/rust-musl-builder) - [muslrust](https://github.com/clux/muslrust) - [docker-slim](https://github.com/docker-slim/docker-slim) - Minify Docker images From fdfd162f63a1e6dbaad4e866dc0d3089f4214a1e Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 13 Jan 2023 13:24:41 -0500 Subject: [PATCH 17/48] Remove link to StackOverflow post now that it has the most votes --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index ebf9b99..f1d4dac 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,6 @@ [github-actions-badge]: https://github.com/johnthagen/min-sized-rust/workflows/build/badge.svg -> To help this project reach more users, consider upvoting the -> [`min-sized-rust` Stack Overflow answer](https://stackoverflow.com/a/54842093/1398841). - This repository demonstrates how to minimize the size of a Rust binary. By default, Rust optimizes for execution speed, compilation speed, and ease of debugging From 810aa527e8112df7643577bb1ad193f8d5cfdf32 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 13 May 2023 15:54:51 -0400 Subject: [PATCH 18/48] Remove outdated Travis CI badge links --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index f1d4dac..55cb8a2 100644 --- a/README.md +++ b/README.md @@ -341,7 +341,3 @@ create minimum sized container images that run Rust binaries. [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows - - -[travis-build-status]: https://travis-ci.com/johnthagen/min-sized-rust -[travis-build-status-svg]: https://travis-ci.com/johnthagen/min-sized-rust.svg?branch=master From e413cf99be8b7509d8c34f6ea63f6a34924042c5 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 13 Sep 2023 09:13:32 -0400 Subject: [PATCH 19/48] Document rustc `-Zlocation-detail` flag (#54) --- .github/workflows/build.yml | 2 +- README.md | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7aab8a..0bb8ae4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -47,5 +47,5 @@ jobs: working-directory: ${{ matrix.project_dir }} run: > rustup component add rust-src; - cargo +nightly build -Z build-std=std,panic_abort --target x86_64-unknown-linux-gnu --release; + RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort --target x86_64-unknown-linux-gnu --release; cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu --release; diff --git a/README.md b/README.md index 55cb8a2..c3fa527 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,22 @@ Enable this in `Cargo.toml`: panic = "abort" ``` +# Remove Location Details + +![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) + +By default, Rust includes file, line, and column information for `panic!()` and `[track_caller]` +to provide more useful traceback information. This information requires space in the binary and +thus increases the size of the compiled binaries. + +To remove this file, line, and column information, use the unstable +[`rustc` `-Zlocation-detail`](https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md#location-detail-control) +flag: + +```bash +$ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build --release +``` + # Optimize `libstd` with `build-std` ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) @@ -180,7 +196,7 @@ host: x86_64-apple-darwin # Use that target triple when building with build-std. # Add the =std,panic_abort to the option to make panic = "abort" Cargo.toml option work. # See: https://github.com/rust-lang/wg-cargo-std-aware/issues/56 -$ cargo +nightly build -Z build-std=std,panic_abort --target x86_64-apple-darwin --release +$ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort --target x86_64-apple-darwin --release ``` On macOS, the final stripped binary size is reduced to 51KB. From 9285ddab4c649cfc36d6adb57674aec8a30ae24b Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 17 Oct 2023 11:47:15 -0400 Subject: [PATCH 20/48] Add note about opt-level surprising results --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c3fa527..3a356dc 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,14 @@ which optimizes the binary for **speed**. To instruct Cargo to optimize for mini opt-level = "z" # Optimize for size. ``` +Note that in some cases the `"s"` level may result in a smaller binary than `"z"`, as explained in +the +[`opt-level` documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level): + +> It is recommended to experiment with different levels to find the right balance for your project. +There may be surprising results, such as ... the `"s"` and `"z"` levels not being necessarily +smaller. + # Enable Link Time Optimization (LTO) ![Minimum Rust: 1.0](https://img.shields.io/badge/Minimum%20Rust%20Version-1.0-brightgreen.svg) From 73fefce2169303bc4e9e537a54e5655bdc22be88 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 28 Oct 2023 18:44:04 -0400 Subject: [PATCH 21/48] Add reference to "Optimize Rust binaries size with cargo and Semver" --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a356dc..14644e8 100644 --- a/README.md +++ b/README.md @@ -342,13 +342,13 @@ create minimum sized container images that run Rust binaries. - [151-byte static Linux binary in Rust - 2015][151-byte-static-linux-binary] - [Why is a Rust executable large? - 2016][why-rust-binary-large] -- [Freestanding Rust Binary - 2018](https://os.phil-opp.com/freestanding-rust-binary/) - [Tiny Rocket - 2018](https://jamesmunns.com/blog/tinyrocket/) - [Formatting is Unreasonably Expensive for Embedded Rust - 2019][fmt-unreasonably-expensive] - [Tiny Windows executable in Rust - 2019][tiny-windows-exe] - [Making a really tiny WebAssembly graphics demos - 2019][tiny-webassembly-graphics] - [Reducing the size of the Rust GStreamer plugin - 2020][gstreamer-plugin] - [Optimizing Rust Binary Size - 2020][optimizing-rust-binary-size] +- [Optimize Rust binaries size with cargo and Semver - 2021][optimize-with-cargo-and-semver] - [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] @@ -361,6 +361,7 @@ create minimum sized container images that run Rust binaries. [tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/ [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ [optimizing-rust-binary-size]: https://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html +[optimize-with-cargo-and-semver]: https://oknozor.github.io/blog/optimize-rust-binary-size/ [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ From 78c7a5c50dfd6bd833f6e6317d9584579a7a032f Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 28 Oct 2023 18:46:27 -0400 Subject: [PATCH 22/48] Add reference to "Minimizing Mender-Rust" --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 14644e8..e234f79 100644 --- a/README.md +++ b/README.md @@ -348,6 +348,7 @@ create minimum sized container images that run Rust binaries. - [Making a really tiny WebAssembly graphics demos - 2019][tiny-webassembly-graphics] - [Reducing the size of the Rust GStreamer plugin - 2020][gstreamer-plugin] - [Optimizing Rust Binary Size - 2020][optimizing-rust-binary-size] +- [Minimizing Mender-Rust - 2020][minimizing-mender-rust] - [Optimize Rust binaries size with cargo and Semver - 2021][optimize-with-cargo-and-semver] - [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] @@ -361,6 +362,7 @@ create minimum sized container images that run Rust binaries. [tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/ [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ [optimizing-rust-binary-size]: https://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html +[minimizing-mender-rust]: https://mender.io/blog/building-mender-rust-in-yocto-and-minimizing-the-binary-size [optimize-with-cargo-and-semver]: https://oknozor.github.io/blog/optimize-rust-binary-size/ [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ From 5ea2f2b2c266ff8a2afa9df9aac8f23af9b63e30 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sat, 28 Oct 2023 18:48:58 -0400 Subject: [PATCH 23/48] Add reference to "Shrinking .wasm Code Size" --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e234f79..9373b22 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,7 @@ create minimum sized container images that run Rust binaries. - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size +- [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] [151-byte-static-linux-binary]: https://mainisusuallyafunction.blogspot.com/2015/01/151-byte-static-linux-binary-in-rust.html [why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html @@ -368,3 +369,4 @@ create minimum sized container images that run Rust binaries. [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows +[shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html From 392ddcf606ace3a60d5db91328e2ee11d1ef0d25 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 1 Dec 2023 08:25:28 -0500 Subject: [PATCH 24/48] Add reference to wg-binary-size working group --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 9373b22..2fe6b05 100644 --- a/README.md +++ b/README.md @@ -370,3 +370,9 @@ create minimum sized container images that run Rust binaries. [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html + +# Organizations + +- [wg-binary-size]: Working group for improving the size of Rust programs and libraries. + +[wg-binary-size]: https://github.com/rust-lang/wg-binary-size From c4be196dc6ff1eb0e0ee881e0131c78ec1ee1217 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 29 Dec 2023 12:09:53 -0500 Subject: [PATCH 25/48] Add reference to The dark side of inlining and monomorphization --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2fe6b05..b63397a 100644 --- a/README.md +++ b/README.md @@ -353,6 +353,7 @@ create minimum sized container images that run Rust binaries. - [Tighten rust’s belt: shrinking embedded Rust binaries - 2022][tighten-rusts-belt] - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] +- [The dark side of inlining and monomorphization - 2023][dark-side-of-inlining] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size - [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] @@ -368,6 +369,7 @@ create minimum sized container images that run Rust binaries. [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ +[dark-side-of-inlining]: https://nickb.dev/blog/the-dark-side-of-inlining-and-monomorphization/ [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html From 8db1b5764b481e79b4ccedc953d3bdc188f120c6 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 24 Jan 2024 13:26:12 -0500 Subject: [PATCH 26/48] Add reference to Making Rust binaries smaller by default (#58) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b63397a..fe865b3 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,7 @@ create minimum sized container images that run Rust binaries. - [Avoiding allocations in Rust to shrink Wasm modules - 2022][avoiding-allocations-shrink-wasm] - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] - [The dark side of inlining and monomorphization - 2023][dark-side-of-inlining] +- [Making Rust binaries smaller by default - 2024][making-rust-binaries-smaller-by-default] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size - [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] @@ -370,6 +371,7 @@ create minimum sized container images that run Rust binaries. [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ [dark-side-of-inlining]: https://nickb.dev/blog/the-dark-side-of-inlining-and-monomorphization/ +[making-rust-binaries-smaller-by-default]: https://kobzol.github.io/rust/cargo/2024/01/23/making-rust-binaries-smaller-by-default.html [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html From 2b26a38848dd0045a777ccd1a68fa62d84b87062 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 14 Feb 2024 08:17:00 -0500 Subject: [PATCH 27/48] Format README.md --- README.md | 89 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index fe865b3..825dddc 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ $ strip target/release/min-sized-rust [Cargo defaults its optimization level to `3` for release builds][cargo-profile], which optimizes the binary for **speed**. To instruct Cargo to optimize for minimal binary -**size**, use the `z` optimization level in +**size**, use the `z` optimization level in [`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html): [cargo-profile]: https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles @@ -70,15 +70,15 @@ the [`opt-level` documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level): > It is recommended to experiment with different levels to find the right balance for your project. -There may be surprising results, such as ... the `"s"` and `"z"` levels not being necessarily -smaller. +> There may be surprising results, such as ... the `"s"` and `"z"` levels not being necessarily +> smaller. # Enable Link Time Optimization (LTO) ![Minimum Rust: 1.0](https://img.shields.io/badge/Minimum%20Rust%20Version-1.0-brightgreen.svg) -By default, -[Cargo instructs compilation units to be compiled and optimized in isolation][cargo-profile]. +By default, +[Cargo instructs compilation units to be compiled and optimized in isolation][cargo-profile]. [LTO](https://llvm.org/docs/LinkTimeOptimization.html) instructs the linker to optimize at the link stage. This can, for example, remove dead code and often times reduces binary size. @@ -94,14 +94,14 @@ lto = true ![Minimum Rust: 1.28](https://img.shields.io/badge/Minimum%20Rust%20Version-1.28-brightgreen.svg) ![Maximum Rust: 1.31](https://img.shields.io/badge/Maximum%20Rust%20Version-1.31-brightgreen.svg) -As of Rust 1.32, -[`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html). -**If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this +As of Rust 1.32, +[`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html). +**If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this feature**. **Prior to Rust 1.32**, to improve performance on some platforms Rust bundled -[jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often -outperforms the default system allocator. Bundling jemalloc added around 200KB +[jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often +outperforms the default system allocator. Bundling jemalloc added around 200KB to the resulting binary, however. 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; # Reduce Parallel Code Generation Units to Increase Optimization [By default][cargo-profile], Cargo specifies 16 parallel codegen units for release builds. -This improves compile times, but prevents some optimizations. +This improves compile times, but prevents some optimizations. Set this to `1` in `Cargo.toml` to allow for maximum size reduction optimizations: @@ -130,12 +130,12 @@ codegen-units = 1 ![Minimum Rust: 1.10](https://img.shields.io/badge/Minimum%20Rust%20Version-1.10-brightgreen.svg) > **Note**: Up to this point, the features discussed to reduce binary size did not have an -impact on the behaviour of the program (only its execution speed). This feature does -have an impact on behavior. +> impact on the behaviour of the program (only its execution speed). This feature does +> have an impact on behavior. -[By default][cargo-profile], when Rust code encounters a situation when it must call `panic!()`, -it unwinds the stack and produces a helpful backtrace. The unwinding code, however, does require -extra binary size. `rustc` can be instructed to abort immediately rather than unwind, which +[By default][cargo-profile], when Rust code encounters a situation when it must call `panic!()`, +it unwinds the stack and produces a helpful backtrace. The unwinding code, however, does require +extra binary size. `rustc` can be instructed to abort immediately rather than unwind, which removes the need for this extra unwinding code. Enable this in `Cargo.toml`: @@ -166,7 +166,7 @@ $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build --release ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) > **Note**: See also [Xargo](https://github.com/japaric/xargo), the predecessor to `build-std`. - [Xargo is currently in maintenance status](https://github.com/japaric/xargo/issues/193). +[Xargo is currently in maintenance status](https://github.com/japaric/xargo/issues/193). > Example project is located in the [`build_std`](build_std) folder. @@ -179,10 +179,10 @@ aggressively optimize for size. 1. The prebuilt `libstd` is optimized for speed, not size. -2. It's not possible to remove portions of `libstd` that are not used in a particular application +2. It's not possible to remove portions of `libstd` that are not used in a particular application (e.g. LTO and panic behaviour). -This is where [`build-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std) +This is where [`build-std`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std) comes in. The `build-std` feature is able to compile `libstd` with your application from the source. It does this with the `rust-src` component that `rustup` conveniently provides. @@ -214,7 +214,7 @@ On macOS, the final stripped binary size is reduced to 51KB. ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) Even if `panic = "abort"` is specified in `Cargo.toml`, `rustc` will still include panic strings -and formatting code in final binary by default. +and formatting code in final binary by default. [An unstable `panic_immediate_abort` feature](https://github.com/rust-lang/rust/pull/55011) has been merged into the `nightly` `rustc` compiler to address this. @@ -235,29 +235,27 @@ On macOS, the final stripped binary size is reduced to 30KB. > Example project is located in the [`no_main`](no_main) folder. -> This section was contributed in part by [@vi](https://github.com/vi) - Up until this point, we haven't restricted what utilities we used from `libstd`. In this section we will restrict our usage of `libstd` in order to reduce binary size further. -If you want an executable smaller than 20 kilobytes, Rust's string formatting code, -[`core::fmt`](https://doc.rust-lang.org/core/fmt/index.html) must -be removed. `panic_immediate_abort` only removes some usages of this code. There is a lot of other +If you want an executable smaller than 20 kilobytes, Rust's string formatting code, +[`core::fmt`](https://doc.rust-lang.org/core/fmt/index.html) must +be removed. `panic_immediate_abort` only removes some usages of this code. There is a lot of other code that uses formatting in some cases. That includes Rust's "pre-main" code in `libstd`. -By using a C entry point (by adding the `#![no_main]` attribute) , managing stdio manually, and -carefully analyzing which chunks of code you or your dependencies include, you can sometimes +By using a C entry point (by adding the `#![no_main]` attribute) , managing stdio manually, and +carefully analyzing which chunks of code you or your dependencies include, you can sometimes make use of `libstd` while avoiding bloated `core::fmt`. -Expect the code to be hacky and unportable, with more `unsafe{}`s than usual. It feels like +Expect the code to be hacky and unportable, with more `unsafe{}`s than usual. It feels like `no_std`, but with `libstd`. -Start with an empty executable, ensure -[`xargo bloat --release --target=...`](https://github.com/RazrFalcon/cargo-bloat) contains no -`core::fmt` or something about padding. Add (uncomment) a little bit. See that `xargo bloat` now -reports drastically more. Review source code that you've just added. Probably some external crate or +Start with an empty executable, ensure +[`xargo bloat --release --target=...`](https://github.com/RazrFalcon/cargo-bloat) contains no +`core::fmt` or something about padding. Add (uncomment) a little bit. See that `xargo bloat` now +reports drastically more. Review source code that you've just added. Probably some external crate or a new `libstd` function is used. Recurse into that with your review process -(it requires `[replace]` Cargo dependencies and maybe digging in `libstd`), find out why it +(it requires `[replace]` Cargo dependencies and maybe digging in `libstd`), find out why it weighs more than it should. Choose alternative way or patch dependencies to avoid unnecessary features. Uncomment a bit more of your code, debug exploded size with `xargo bloat` and so on. @@ -306,8 +304,8 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { Up until this point, all size-reducing techniques were Rust-specific. This section describes a language-agnostic binary packing tool that is an option to reduce binary size further. -[UPX](https://github.com/upx/upx) is a powerful tool for creating a self contained, compressed -binary with no addition runtime requirements. It claims to typically reduce binary size by 50-70%, +[UPX](https://github.com/upx/upx) is a powerful tool for creating a self-contained, compressed +binary with no addition runtime requirements. It claims to typically reduce binary size by 50-70%, but the actual result depends on your executable. ```bash @@ -319,7 +317,7 @@ heuristic-based anti-virus software because malware often uses UPX. # Tools -- [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the +- [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the space in your executable. - [`cargo-unused-features`](https://github.com/TimonPost/cargo-unused-features) - Find and prune enabled but potentially unused feature flags from your project. @@ -329,8 +327,8 @@ heuristic-based anti-virus software because malware often uses UPX. # Containers -Sometimes it's advantageous to deploy Rust into containers -(e.g. [Docker](https://www.docker.com/)). There are several great existing resources to help +Sometimes it's advantageous to deploy Rust into containers +(e.g. [Docker](https://www.docker.com/)). There are several great existing resources to help create minimum sized container images that run Rust binaries. - [Official `rust:alpine` image](https://hub.docker.com/_/rust) @@ -359,20 +357,35 @@ create minimum sized container images that run Rust binaries. - [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] [151-byte-static-linux-binary]: https://mainisusuallyafunction.blogspot.com/2015/01/151-byte-static-linux-binary-in-rust.html + [why-rust-binary-large]: https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html + [fmt-unreasonably-expensive]: https://jamesmunns.com/blog/fmt-unreasonably-expensive/ + [tiny-windows-exe]: https://www.codeslow.com/2019/12/tiny-windows-executable-in-rust.html + [tiny-webassembly-graphics]: https://cliffle.com/blog/bare-metal-wasm/ + [gstreamer-plugin]: https://www.collabora.com/news-and-blog/blog/2020/04/28/reducing-size-rust-gstreamer-plugin/ + [optimizing-rust-binary-size]: https://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html + [minimizing-mender-rust]: https://mender.io/blog/building-mender-rust-in-yocto-and-minimizing-the-binary-size + [optimize-with-cargo-and-semver]: https://oknozor.github.io/blog/optimize-rust-binary-size/ + [tighten-rusts-belt]: https://dl.acm.org/doi/abs/10.1145/3519941.3535075 + [avoiding-allocations-shrink-wasm]: https://nickb.dev/blog/avoiding-allocations-in-rust-to-shrink-wasm-modules/ + [a-very-small-rust-binary]: https://darkcoding.net/software/a-very-small-rust-binary-indeed/ + [dark-side-of-inlining]: https://nickb.dev/blog/the-dark-side-of-inlining-and-monomorphization/ + [making-rust-binaries-smaller-by-default]: https://kobzol.github.io/rust/cargo/2024/01/23/making-rust-binaries-smaller-by-default.html + [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows + [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html # Organizations From 66a1fd90eead93d9e0472a3a1a88e185ae8c1761 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 14 Feb 2024 11:59:37 -0500 Subject: [PATCH 28/48] Remove trailing space in code snippet --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 825dddc..9fb2114 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ $ rustup component add rust-src --toolchain nightly Build using `build-std`: ```bash -# Find your host's target triple. +# Find your host's target triple. $ rustc -vV ... host: x86_64-apple-darwin From e493017f67a0a6291e5935d40b5f707605ef0eee Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 17 Mar 2024 14:51:10 -0400 Subject: [PATCH 29/48] Add support for Windows `#![no_main]` (#62) --- .github/workflows/build.yml | 22 ++++++++++++++++++---- Cargo.toml | 1 - README.md | 2 +- no_main/{ => nix}/.gitignore | 0 no_main/{ => nix}/Cargo.lock | 0 no_main/{ => nix}/Cargo.toml | 1 - no_main/{ => nix}/src/main.rs | 0 no_main/win/.gitignore | 1 + no_main/win/Cargo.lock | 7 +++++++ no_main/win/Cargo.toml | 14 ++++++++++++++ no_main/win/src/main.rs | 24 ++++++++++++++++++++++++ no_std/Cargo.toml | 1 - 12 files changed, 65 insertions(+), 8 deletions(-) rename no_main/{ => nix}/.gitignore (100%) rename no_main/{ => nix}/Cargo.lock (100%) rename no_main/{ => nix}/Cargo.toml (81%) rename no_main/{ => nix}/src/main.rs (100%) create mode 100644 no_main/win/.gitignore create mode 100644 no_main/win/Cargo.lock create mode 100644 no_main/win/Cargo.toml create mode 100644 no_main/win/src/main.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0bb8ae4..467209b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: toolchain: [ stable, nightly ] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} @@ -25,21 +25,35 @@ jobs: toolchain: [ stable, nightly ] runs-on: ${{ matrix.platform }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.toolchain }} - name: Build working-directory: no_std run: cargo build --release --all-features + no_main_win: + name: no_main-win + strategy: + matrix: + toolchain: [ stable, nightly ] + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + - name: Build + working-directory: no_main/win + run: cargo build --release --all-features build_std: name: build-std strategy: matrix: - project_dir: [ build_std, no_main ] + project_dir: [ build_std, no_main/nix ] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: nightly diff --git a/Cargo.toml b/Cargo.toml index 25b75c9..cb87ee9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "min-sized-rust" version = "0.1.0" -authors = ["johnthagen "] edition = "2021" license-file = "LICENSE.txt" diff --git a/README.md b/README.md index 9fb2114..b7dbd28 100644 --- a/README.md +++ b/README.md @@ -233,7 +233,7 @@ On macOS, the final stripped binary size is reduced to 30KB. ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) -> Example project is located in the [`no_main`](no_main) folder. +> Example projects are located in the [`no_main`](no_main) folder. Up until this point, we haven't restricted what utilities we used from `libstd`. In this section we will restrict our usage of `libstd` in order to reduce binary size further. diff --git a/no_main/.gitignore b/no_main/nix/.gitignore similarity index 100% rename from no_main/.gitignore rename to no_main/nix/.gitignore diff --git a/no_main/Cargo.lock b/no_main/nix/Cargo.lock similarity index 100% rename from no_main/Cargo.lock rename to no_main/nix/Cargo.lock diff --git a/no_main/Cargo.toml b/no_main/nix/Cargo.toml similarity index 81% rename from no_main/Cargo.toml rename to no_main/nix/Cargo.toml index 20004a7..1eb6c8b 100644 --- a/no_main/Cargo.toml +++ b/no_main/nix/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "no_main" version = "0.1.0" -authors = ["johnthagen ", "Vitaly '_Vi' Shukela "] edition = "2021" license = "MIT" diff --git a/no_main/src/main.rs b/no_main/nix/src/main.rs similarity index 100% rename from no_main/src/main.rs rename to no_main/nix/src/main.rs diff --git a/no_main/win/.gitignore b/no_main/win/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/no_main/win/.gitignore @@ -0,0 +1 @@ +/target diff --git a/no_main/win/Cargo.lock b/no_main/win/Cargo.lock new file mode 100644 index 0000000..e1d1daa --- /dev/null +++ b/no_main/win/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "no_main" +version = "0.1.0" diff --git a/no_main/win/Cargo.toml b/no_main/win/Cargo.toml new file mode 100644 index 0000000..46a9e1c --- /dev/null +++ b/no_main/win/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "no_main" +version = "0.1.0" +edition = "2021" +license = "MIT" + +[dependencies] + +[profile.release] +opt-level = "z" +lto = true +codegen-units = 1 +panic = "abort" +strip = true diff --git a/no_main/win/src/main.rs b/no_main/win/src/main.rs new file mode 100644 index 0000000..018a9bf --- /dev/null +++ b/no_main/win/src/main.rs @@ -0,0 +1,24 @@ +#![no_main] + +use std::fs::File; +use std::io::Write as _; +use std::os::windows::{io::FromRawHandle as _, raw::HANDLE}; + +#[link(name = "kernel32")] +extern "system" { + pub fn GetStdHandle(nstdhandle: u32) -> HANDLE; +} + +pub const STD_OUTPUT_HANDLE: u32 = 4294967285; + +fn stdout() -> File { + unsafe { File::from_raw_handle(GetStdHandle(STD_OUTPUT_HANDLE)) } +} + +#[no_mangle] +pub fn main(_argc: i32, _argv: *const *const u8) -> u32 { + let mut stdout = stdout(); + stdout.write_all(b"Hello, world!\n").unwrap(); + + 0 +} diff --git a/no_std/Cargo.toml b/no_std/Cargo.toml index 108db3f..6c5d73f 100644 --- a/no_std/Cargo.toml +++ b/no_std/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "min-sized-no_std" version = "0.1.0" -authors = ["johnthagen "] edition = "2021" license = "MIT" From 17406df099eb1135d88d63f7445ed7c045553548 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 17 Mar 2024 15:03:54 -0400 Subject: [PATCH 30/48] Add Windows no_std project example (#63) --- .github/workflows/build.yml | 16 +++++++- README.md | 2 +- no_std/{ => nix}/.gitignore | 0 no_std/{ => nix}/Cargo.lock | 0 no_std/{ => nix}/Cargo.toml | 0 no_std/{ => nix}/src/main.rs | 0 no_std/win/.gitignore | 1 + no_std/win/Cargo.lock | 76 ++++++++++++++++++++++++++++++++++++ no_std/win/Cargo.toml | 21 ++++++++++ no_std/win/src/main.rs | 36 +++++++++++++++++ 10 files changed, 150 insertions(+), 2 deletions(-) rename no_std/{ => nix}/.gitignore (100%) rename no_std/{ => nix}/Cargo.lock (100%) rename no_std/{ => nix}/Cargo.toml (100%) rename no_std/{ => nix}/src/main.rs (100%) create mode 100644 no_std/win/.gitignore create mode 100644 no_std/win/Cargo.lock create mode 100644 no_std/win/Cargo.toml create mode 100644 no_std/win/src/main.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 467209b..ec85312 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,21 @@ jobs: with: toolchain: ${{ matrix.toolchain }} - name: Build - working-directory: no_std + working-directory: no_std/nix + run: cargo build --release --all-features + no_std_win: + name: no_std-win + strategy: + matrix: + toolchain: [ stable, nightly ] + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + - name: Build + working-directory: no_std/win run: cargo build --release --all-features no_main_win: name: no_main-win diff --git a/README.md b/README.md index b7dbd28..c310855 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,7 @@ On macOS, the final stripped binary is reduced to 8KB. ![Minimum Rust: 1.30](https://img.shields.io/badge/Minimum%20Rust%20Version-1.30-brightgreen.svg) -> Example project is located in the [`no_std`](no_std) folder. +> Example projects are located in the [`no_std`](no_std) folder. Up until this point, our application was using the Rust standard library, `libstd`. `libstd` provides many convenient, well tested cross-platform APIs and data types. But if a user wants diff --git a/no_std/.gitignore b/no_std/nix/.gitignore similarity index 100% rename from no_std/.gitignore rename to no_std/nix/.gitignore diff --git a/no_std/Cargo.lock b/no_std/nix/Cargo.lock similarity index 100% rename from no_std/Cargo.lock rename to no_std/nix/Cargo.lock diff --git a/no_std/Cargo.toml b/no_std/nix/Cargo.toml similarity index 100% rename from no_std/Cargo.toml rename to no_std/nix/Cargo.toml diff --git a/no_std/src/main.rs b/no_std/nix/src/main.rs similarity index 100% rename from no_std/src/main.rs rename to no_std/nix/src/main.rs diff --git a/no_std/win/.gitignore b/no_std/win/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/no_std/win/.gitignore @@ -0,0 +1 @@ +/target diff --git a/no_std/win/Cargo.lock b/no_std/win/Cargo.lock new file mode 100644 index 0000000..e69bffc --- /dev/null +++ b/no_std/win/Cargo.lock @@ -0,0 +1,76 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "no_std_win" +version = "0.1.0" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/no_std/win/Cargo.toml b/no_std/win/Cargo.toml new file mode 100644 index 0000000..d0aac8e --- /dev/null +++ b/no_std/win/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "no_std_win" +version = "0.1.0" +edition = "2021" + +[dependencies] +windows-sys = { version = "0.52.0", features = [ + "Win32_Foundation", + "Win32_System_Threading", # for `ExitProcess` + "Win32_System_Console", # for `WriteConsoleA` etc. +] } + +[profile.dev] +panic = "abort" + +[profile.release] +opt-level = "z" # Optimize for size. +lto = true # Enable Link Time Optimization +codegen-units = 1 # Reduce number of codegen units to increase optimizations. +panic = "abort" # Abort on panic +strip = true # Automatically strip symbols from the binary. diff --git a/no_std/win/src/main.rs b/no_std/win/src/main.rs new file mode 100644 index 0000000..0c15a52 --- /dev/null +++ b/no_std/win/src/main.rs @@ -0,0 +1,36 @@ +#![no_main] +#![no_std] +#![windows_subsystem = "console"] + +use core::ffi::c_void; +use core::panic::PanicInfo; + +use windows_sys::Win32::System::Console::GetStdHandle; +use windows_sys::Win32::System::Console::WriteConsoleA; +use windows_sys::Win32::System::Console::STD_OUTPUT_HANDLE; +use windows_sys::Win32::System::Threading::ExitProcess; + +#[panic_handler] +fn panic(_: &PanicInfo<'_>) -> ! { + unsafe { + ExitProcess(1); + } +} + +#[allow(non_snake_case)] +#[no_mangle] +fn mainCRTStartup() -> ! { + let message = "Hello, world!\n"; + unsafe { + let console = GetStdHandle(STD_OUTPUT_HANDLE); + WriteConsoleA( + console, + message.as_ptr().cast::(), + message.len() as u32, + core::ptr::null_mut(), + core::ptr::null(), + ); + + ExitProcess(0) + } +} From f3da56c6d1b6ca29cfa07cc95f01acb6f531280c Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 14 Jun 2024 09:09:04 -0400 Subject: [PATCH 31/48] Add reference to Tock Binary Size --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c310855..246c515 100644 --- a/README.md +++ b/README.md @@ -353,6 +353,7 @@ create minimum sized container images that run Rust binaries. - [A very small Rust binary indeed - 2022][a-very-small-rust-binary] - [The dark side of inlining and monomorphization - 2023][dark-side-of-inlining] - [Making Rust binaries smaller by default - 2024][making-rust-binaries-smaller-by-default] +- [Tock Binary Size - 2024][tock-binary-size] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size - [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] @@ -384,6 +385,8 @@ create minimum sized container images that run Rust binaries. [making-rust-binaries-smaller-by-default]: https://kobzol.github.io/rust/cargo/2024/01/23/making-rust-binaries-smaller-by-default.html +[tock-binary-size]: https://tweedegolf.nl/en/blog/126/tock-binary-size + [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html From c030adcb9d3d9052b5576c2bfcc1a3d031a1665a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 14 Jun 2024 15:11:41 +0200 Subject: [PATCH 32/48] Add information about the `optimize_for_size` libstd feature (#64) --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 246c515..9ecd214 100644 --- a/README.md +++ b/README.md @@ -204,11 +204,16 @@ host: x86_64-apple-darwin # Use that target triple when building with build-std. # Add the =std,panic_abort to the option to make panic = "abort" Cargo.toml option work. # See: https://github.com/rust-lang/wg-cargo-std-aware/issues/56 -$ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort --target x86_64-apple-darwin --release +$ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort \ + -Z build-std-features="std/optimize_for_size" \ + --target x86_64-apple-darwin --release ``` On macOS, the final stripped binary size is reduced to 51KB. +The `optimize_for_size` flag provides a hint to libstd that it should try to use algorithms optimized +for binary size. More information about it can be found [here](https://github.com/rust-lang/rust/issues/125612). + # Remove `panic` String Formatting with `panic_immediate_abort` ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) From ea5ab25d3844a26f3e118dc0a4e632d10a05ed18 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 14 Jun 2024 09:21:56 -0400 Subject: [PATCH 33/48] Run `std/optimize_for_size` in nightly CI (#65) --- .github/workflows/build.yml | 2 +- README.md | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec85312..410e11c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,5 +75,5 @@ jobs: working-directory: ${{ matrix.project_dir }} run: > rustup component add rust-src; - RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort --target x86_64-unknown-linux-gnu --release; + RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="std/optimize_for_size" --target x86_64-unknown-linux-gnu --release; cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu --release; diff --git a/README.md b/README.md index 9ecd214..6b37584 100644 --- a/README.md +++ b/README.md @@ -209,10 +209,11 @@ $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic --target x86_64-apple-darwin --release ``` -On macOS, the final stripped binary size is reduced to 51KB. +The `optimize_for_size` flag provides a hint to `libstd` that it should try to use algorithms +optimized for binary size. More information about it can be found in the +[tracking issue](https://github.com/rust-lang/rust/issues/125612). -The `optimize_for_size` flag provides a hint to libstd that it should try to use algorithms optimized -for binary size. More information about it can be found [here](https://github.com/rust-lang/rust/issues/125612). +On macOS, the final stripped binary size is reduced to 51KB. # Remove `panic` String Formatting with `panic_immediate_abort` From 63a7b92a22aeaf5cc369fe5a25b335dc43fbd520 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Fri, 14 Jun 2024 09:27:34 -0400 Subject: [PATCH 34/48] Add a reference to dive --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6b37584..8bd0931 100644 --- a/README.md +++ b/README.md @@ -341,6 +341,8 @@ create minimum sized container images that run Rust binaries. - [mini-docker-rust](https://github.com/kpcyrd/mini-docker-rust) - [muslrust](https://github.com/clux/muslrust) - [docker-slim](https://github.com/docker-slim/docker-slim) - Minify Docker images +- [dive](https://github.com/wagoodman/dive) - A tool for exploring a container image and + discovering ways to shrink the size of the image. # References From 2f7d9682acc22d09a653b9936badf035447c1eb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Mon, 17 Jun 2024 12:59:00 +0200 Subject: [PATCH 35/48] Improve std feature flag in README and CI (#66) --- .github/workflows/build.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 410e11c..6e83b34 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,5 +75,5 @@ jobs: working-directory: ${{ matrix.project_dir }} run: > rustup component add rust-src; - RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="std/optimize_for_size" --target x86_64-unknown-linux-gnu --release; + RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="optimize_for_size" --target x86_64-unknown-linux-gnu --release; cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu --release; diff --git a/README.md b/README.md index 8bd0931..2baa388 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,7 @@ host: x86_64-apple-darwin # Add the =std,panic_abort to the option to make panic = "abort" Cargo.toml option work. # See: https://github.com/rust-lang/wg-cargo-std-aware/issues/56 $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort \ - -Z build-std-features="std/optimize_for_size" \ + -Z build-std-features="optimize_for_size" \ --target x86_64-apple-darwin --release ``` From af259fc564fa7e68d0dffd3e95539ad497e6178a Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 25 Jun 2024 19:42:03 -0400 Subject: [PATCH 36/48] Use GitHub Markdown alerts in README (#67) --- README.md | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2baa388..b0859ee 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,10 @@ which optimizes the binary for **speed**. To instruct Cargo to optimize for mini opt-level = "z" # Optimize for size. ``` -Note that in some cases the `"s"` level may result in a smaller binary than `"z"`, as explained in -the -[`opt-level` documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level): - +> [!NOTE] +> In some cases the `"s"` level may result in a smaller binary than `"z"`, as explained in the +> [`opt-level` documentation](https://doc.rust-lang.org/cargo/reference/profiles.html#opt-level): +> > It is recommended to experiment with different levels to find the right balance for your project. > There may be surprising results, such as ... the `"s"` and `"z"` levels not being necessarily > smaller. @@ -129,7 +129,8 @@ codegen-units = 1 ![Minimum Rust: 1.10](https://img.shields.io/badge/Minimum%20Rust%20Version-1.10-brightgreen.svg) -> **Note**: Up to this point, the features discussed to reduce binary size did not have an +> [!IMPORTANT] +> Up to this point, the features discussed to reduce binary size did not have an > impact on the behaviour of the program (only its execution speed). This feature does > have an impact on behavior. @@ -165,9 +166,11 @@ $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build --release ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) -> **Note**: See also [Xargo](https://github.com/japaric/xargo), the predecessor to `build-std`. +> [!NOTE] +> See also [Xargo](https://github.com/japaric/xargo), the predecessor to `build-std`. [Xargo is currently in maintenance status](https://github.com/japaric/xargo/issues/193). +> [!NOTE] > Example project is located in the [`build_std`](build_std) folder. Rust ships pre-built copies of the standard library (`libstd`) with its toolchains. This means @@ -239,6 +242,7 @@ On macOS, the final stripped binary size is reduced to 30KB. ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) +> [!NOTE] > Example projects are located in the [`no_main`](no_main) folder. Up until this point, we haven't restricted what utilities we used from `libstd`. In this section @@ -271,6 +275,7 @@ On macOS, the final stripped binary is reduced to 8KB. ![Minimum Rust: 1.30](https://img.shields.io/badge/Minimum%20Rust%20Version-1.30-brightgreen.svg) +> [!NOTE] > Example projects are located in the [`no_std`](no_std) folder. Up until this point, our application was using the Rust standard library, `libstd`. `libstd` @@ -307,8 +312,9 @@ fn my_panic(_info: &core::panic::PanicInfo) -> ! { # Compress the binary -Up until this point, all size-reducing techniques were Rust-specific. This section describes -a language-agnostic binary packing tool that is an option to reduce binary size further. +> [!NOTE] +> Up until this point, all size-reducing techniques were Rust-specific. This section describes +> a language-agnostic binary packing tool that is an option to reduce binary size further. [UPX](https://github.com/upx/upx) is a powerful tool for creating a self-contained, compressed binary with no addition runtime requirements. It claims to typically reduce binary size by 50-70%, @@ -318,8 +324,9 @@ but the actual result depends on your executable. $ upx --best --lzma target/release/min-sized-rust ``` -It should be noted that there have been times that UPX-packed binaries have flagged -heuristic-based anti-virus software because malware often uses UPX. +> [!WARNING] +> There have been times that UPX-packed binaries have flagged heuristic-based antivirus software +> because malware often uses UPX. # Tools From 094d314f0c28f7e4bffeb0b0258f71cb303bd91a Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 16 Jul 2024 13:42:23 -0400 Subject: [PATCH 37/48] Add jemalloc section admonition --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b0859ee..f8a3f97 100644 --- a/README.md +++ b/README.md @@ -94,10 +94,11 @@ lto = true ![Minimum Rust: 1.28](https://img.shields.io/badge/Minimum%20Rust%20Version-1.28-brightgreen.svg) ![Maximum Rust: 1.31](https://img.shields.io/badge/Maximum%20Rust%20Version-1.31-brightgreen.svg) -As of Rust 1.32, -[`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html). -**If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this -feature**. +> [!IMPORTANT] +> As of Rust 1.32, +> [`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html). +> **If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this +> feature**. **Prior to Rust 1.32**, to improve performance on some platforms Rust bundled [jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often From 5d0b53b7aef30f87d1cc036338a9aebe050ca156 Mon Sep 17 00:00:00 2001 From: Kornel Date: Wed, 11 Sep 2024 11:59:10 +0100 Subject: [PATCH 38/48] Removing fmt::Debug impls (#71) --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index f8a3f97..1955d27 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,19 @@ flag: $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build --release ``` +# Remove `fmt::Debug` + +![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) + +With the [`-Zfmt-debug`](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/fmt-debug.html) flag you can turn `#[derive(Debug)]` +and [`{:?}`](https://doc.rust-lang.org/stable/std/fmt/trait.Debug.html) formatting into no-ops. +This will ruin output of `dbg!()`, `assert!()`, `unwrap()`, etc., and may break code that unwisely relies on +the debug formatting, but it will remove derived `fmt` functions and their strings. + +```bash +$ RUSTFLAGS="-Zfmt-debug=none" cargo +nightly build --release +``` + # Optimize `libstd` with `build-std` ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) From dc323be1301e79f809f24dd1a07183019c436cde Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 11 Sep 2024 06:59:52 -0400 Subject: [PATCH 39/48] Wrap README at 100 lines --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1955d27..447f9b9 100644 --- a/README.md +++ b/README.md @@ -167,10 +167,12 @@ $ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build --release ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) -With the [`-Zfmt-debug`](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/fmt-debug.html) flag you can turn `#[derive(Debug)]` -and [`{:?}`](https://doc.rust-lang.org/stable/std/fmt/trait.Debug.html) formatting into no-ops. -This will ruin output of `dbg!()`, `assert!()`, `unwrap()`, etc., and may break code that unwisely relies on -the debug formatting, but it will remove derived `fmt` functions and their strings. +With the +[`-Zfmt-debug`](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/fmt-debug.html) flag +you can turn `#[derive(Debug)]`and +[`{:?}`](https://doc.rust-lang.org/stable/std/fmt/trait.Debug.html) formatting into no-ops. This +will ruin output of `dbg!()`, `assert!()`, `unwrap()`, etc., and may break code that unwisely +relies on the debug formatting, but it will remove derived `fmt` functions and their strings. ```bash $ RUSTFLAGS="-Zfmt-debug=none" cargo +nightly build --release From cbab928e6074bd06d7c6bac6ea9f6393dd3599ca Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 11 Sep 2024 07:03:05 -0400 Subject: [PATCH 40/48] Move jemalloc to a legacy techniques section (#72) --- README.md | 55 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 447f9b9..c6bde5b 100644 --- a/README.md +++ b/README.md @@ -89,31 +89,6 @@ Enable LTO in `Cargo.toml`: lto = true ``` -# Remove Jemalloc - -![Minimum Rust: 1.28](https://img.shields.io/badge/Minimum%20Rust%20Version-1.28-brightgreen.svg) -![Maximum Rust: 1.31](https://img.shields.io/badge/Maximum%20Rust%20Version-1.31-brightgreen.svg) - -> [!IMPORTANT] -> As of Rust 1.32, -> [`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html). -> **If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this -> feature**. - -**Prior to Rust 1.32**, to improve performance on some platforms Rust bundled -[jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often -outperforms the default system allocator. Bundling jemalloc added around 200KB -to the resulting binary, however. - -To remove `jemalloc` on Rust 1.28 - Rust 1.31, add this code to the top of `main.rs`: - -```rust -use std::alloc::System; - -#[global_allocator] -static A: System = System; -``` - # Reduce Parallel Code Generation Units to Increase Optimization [By default][cargo-profile], Cargo specifies 16 parallel codegen units for release builds. @@ -427,3 +402,33 @@ create minimum sized container images that run Rust binaries. - [wg-binary-size]: Working group for improving the size of Rust programs and libraries. [wg-binary-size]: https://github.com/rust-lang/wg-binary-size + +# Legacy Techniques + +The following techniques are no longer relevant for modern Rust development, but may apply to older +versions of Rust and are maintained for historical purposes. + +## Remove Jemalloc + +![Minimum Rust: 1.28](https://img.shields.io/badge/Minimum%20Rust%20Version-1.28-brightgreen.svg) +![Maximum Rust: 1.31](https://img.shields.io/badge/Maximum%20Rust%20Version-1.31-brightgreen.svg) + +> [!IMPORTANT] +> As of Rust 1.32, +> [`jemalloc` is removed by default](https://blog.rust-lang.org/2019/01/17/Rust-1.32.0.html). +> **If using Rust 1.32 or newer, no action is needed to reduce binary size regarding this +> feature**. + +**Prior to Rust 1.32**, to improve performance on some platforms Rust bundled +[jemalloc](https://github.com/jemalloc/jemalloc), an allocator that often +outperforms the default system allocator. Bundling jemalloc added around 200KB +to the resulting binary, however. + +To remove `jemalloc` on Rust 1.28 - Rust 1.31, add this code to the top of `main.rs`: + +```rust +use std::alloc::System; + +#[global_allocator] +static A: System = System; +``` \ No newline at end of file From 8dcb3a0ebea3466735d0d8c32009f2e0b9c3a51d Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 11 Sep 2024 07:14:26 -0400 Subject: [PATCH 41/48] Add -Zfmt-debug=none to nightly CI (#73) * Add -Zfmt-debug=none to nightly CI * Update libstd example to include -Zfmt-debug --- .github/workflows/build.yml | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e83b34..e4da0df 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,5 +75,5 @@ jobs: working-directory: ${{ matrix.project_dir }} run: > rustup component add rust-src; - RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="optimize_for_size" --target x86_64-unknown-linux-gnu --release; + RUSTFLAGS="-Zlocation-detail=none -Zfmt-debug=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="optimize_for_size" --target x86_64-unknown-linux-gnu --release; cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu --release; diff --git a/README.md b/README.md index c6bde5b..d2b88ac 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,8 @@ host: x86_64-apple-darwin # Use that target triple when building with build-std. # Add the =std,panic_abort to the option to make panic = "abort" Cargo.toml option work. # See: https://github.com/rust-lang/wg-cargo-std-aware/issues/56 -$ RUSTFLAGS="-Zlocation-detail=none" cargo +nightly build -Z build-std=std,panic_abort \ +$ RUSTFLAGS="-Zlocation-detail=none -Zfmt-debug=none" cargo +nightly build \ + -Z build-std=std,panic_abort \ -Z build-std-features="optimize_for_size" \ --target x86_64-apple-darwin --release ``` From f71ee5d91d4f674db5f95304d13817f41611437c Mon Sep 17 00:00:00 2001 From: johnthagen Date: Sun, 27 Oct 2024 12:46:49 -0400 Subject: [PATCH 42/48] Add reference to Trimming down a rust binary in half --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index d2b88ac..1d20a82 100644 --- a/README.md +++ b/README.md @@ -361,6 +361,7 @@ create minimum sized container images that run Rust binaries. - [The dark side of inlining and monomorphization - 2023][dark-side-of-inlining] - [Making Rust binaries smaller by default - 2024][making-rust-binaries-smaller-by-default] - [Tock Binary Size - 2024][tock-binary-size] +- [Trimming down a rust binary in half - 2024][trimming-down-a-rust-binary-in-half] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size - [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] @@ -394,6 +395,8 @@ create minimum sized container images that run Rust binaries. [tock-binary-size]: https://tweedegolf.nl/en/blog/126/tock-binary-size +[trimming-down-a-rust-binary-in-half]: https://tech.dreamleaves.org/trimming-down-a-rust-binary-in-half/ + [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html From f1db29c8cf2be1eaba1ee813cfd147a263853614 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Thu, 26 Dec 2024 08:44:06 -0500 Subject: [PATCH 43/48] Add reference to "Reducing WASM binary size: lessons from building a web terminal" --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 1d20a82..0995488 100644 --- a/README.md +++ b/README.md @@ -362,6 +362,7 @@ create minimum sized container images that run Rust binaries. - [Making Rust binaries smaller by default - 2024][making-rust-binaries-smaller-by-default] - [Tock Binary Size - 2024][tock-binary-size] - [Trimming down a rust binary in half - 2024][trimming-down-a-rust-binary-in-half] +- [Reducing WASM binary size: lessons from building a web terminal - 2024][reducing-wasm-binary-size] - [`min-sized-rust-windows`][min-sized-rust-windows] - Windows-specific tricks to reduce binary size - [Shrinking `.wasm` Code Size][shrinking-wasm-code-size] @@ -397,6 +398,8 @@ create minimum sized container images that run Rust binaries. [trimming-down-a-rust-binary-in-half]: https://tech.dreamleaves.org/trimming-down-a-rust-binary-in-half/ +[reducing-wasm-binary-size]: https://www.warp.dev/blog/reducing-wasm-binary-size + [min-sized-rust-windows]: https://github.com/mcountryman/min-sized-rust-windows [shrinking-wasm-code-size]: https://rustwasm.github.io/docs/book/reference/code-size.html From d2a8cd9df000d96efbe67f337967017a14a6b30a Mon Sep 17 00:00:00 2001 From: Kivooeo <75776246+Kivooeo@users.noreply.github.com> Date: Wed, 11 Jun 2025 04:01:45 +0500 Subject: [PATCH 44/48] Dynamic linking (#80) --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0995488..362719c 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,16 @@ Enable LTO in `Cargo.toml`: lto = true ``` +# Dynamic Linking: Why It Doesn't Work + +![Minimum Rust: 1.0](https://img.shields.io/badge/Minimum%20Rust%20Version-1.0-brightgreen.svg) + +Some might suggest using [`prefer-dynamic`](https://doc.rust-lang.org/rustc/codegen-options/index.html#prefer-dynamic) for smaller binaries, but this approach has critical limitations: + +- **No stable ABI** - binaries break between Rust versions +- **Deployment complexity** - requires exact library matches +- **Community consensus** - static linking preferred for reliability + # Reduce Parallel Code Generation Units to Increase Optimization [By default][cargo-profile], Cargo specifies 16 parallel codegen units for release builds. @@ -438,4 +448,4 @@ use std::alloc::System; #[global_allocator] static A: System = System; -``` \ No newline at end of file +``` From de338632f863920881ef1fc834853386b17cd7c1 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Tue, 17 Jun 2025 15:34:24 -0400 Subject: [PATCH 45/48] Add tool reference to cargo-llvm-lines --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 362719c..4bdd023 100644 --- a/README.md +++ b/README.md @@ -334,6 +334,9 @@ $ upx --best --lzma target/release/min-sized-rust - [`cargo-bloat`](https://github.com/RazrFalcon/cargo-bloat) - Find out what takes most of the space in your executable. +- [`cargo-llvm-lines`](https://github.com/dtolnay/cargo-llvm-lines) - Measure the number and size + of instantiations of each generic function, indicating which parts of your code offer the highest + leverage in improving compilation metrics. - [`cargo-unused-features`](https://github.com/TimonPost/cargo-unused-features) - Find and prune enabled but potentially unused feature flags from your project. - [`momo`](https://github.com/llogiq/momo) - `proc_macro` crate to help keeping the code footprint From b0bc6dc0b8fa8a0c32b2c4ca9a97c80c971351d1 Mon Sep 17 00:00:00 2001 From: Xerxes-2 Date: Sat, 16 Aug 2025 00:58:57 +1000 Subject: [PATCH 46/48] Add `distroless` to README.md (#84) `distroless` provides an excellent base image to run Rust programs. For Rust programs linked with musl, use `distroless/static` which weighs ~2MB. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4bdd023..d92e7a5 100644 --- a/README.md +++ b/README.md @@ -355,6 +355,7 @@ create minimum sized container images that run Rust binaries. - [docker-slim](https://github.com/docker-slim/docker-slim) - Minify Docker images - [dive](https://github.com/wagoodman/dive) - A tool for exploring a container image and discovering ways to shrink the size of the image. +- [distroless](https://github.com/GoogleContainerTools/distroless) - 2MB base image to run statically linked Rust program # References From eae3cd5554eb0d7d52f4bdc44a35fa1dab1ce8f5 Mon Sep 17 00:00:00 2001 From: Sam Estep Date: Fri, 26 Sep 2025 15:39:01 -0400 Subject: [PATCH 47/48] Switch to new `panic=immediate-abort` flag (#86) --- .github/workflows/build.yml | 2 +- README.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e4da0df..dd6fe40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,4 +76,4 @@ jobs: run: > rustup component add rust-src; RUSTFLAGS="-Zlocation-detail=none -Zfmt-debug=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="optimize_for_size" --target x86_64-unknown-linux-gnu --release; - cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target x86_64-unknown-linux-gnu --release; + RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" cargo +nightly build -Z build-std=std,panic_abort --target x86_64-unknown-linux-gnu --release; diff --git a/README.md b/README.md index d92e7a5..b99afed 100644 --- a/README.md +++ b/README.md @@ -220,21 +220,21 @@ optimized for binary size. More information about it can be found in the On macOS, the final stripped binary size is reduced to 51KB. -# Remove `panic` String Formatting with `panic_immediate_abort` +# Remove `panic` String Formatting with `panic=immediate-abort` ![Minimum Rust: Nightly](https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-orange.svg) Even if `panic = "abort"` is specified in `Cargo.toml`, `rustc` will still include panic strings and formatting code in final binary by default. -[An unstable `panic_immediate_abort` feature](https://github.com/rust-lang/rust/pull/55011) +[An unstable `panic=immediate-abort` feature](https://github.com/rust-lang/rust/pull/146317) has been merged into the `nightly` `rustc` compiler to address this. -To use this, repeat the instructions above to use `build-std`, but also pass the following -[`-Z build-std-features=panic_immediate_abort`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std-features) -option. +To use this, repeat the instructions above to use `build-std`, but also pass +[`-Zunstable-options -Cpanic=immediate-abort`](https://doc.rust-lang.org/rustc/command-line-arguments.html#-z-set-unstable-options) +to `rustc`. ```bash -$ cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort \ +$ RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" cargo +nightly build -Z build-std=std,panic_abort \ --target x86_64-apple-darwin --release ``` @@ -252,7 +252,7 @@ we will restrict our usage of `libstd` in order to reduce binary size further. If you want an executable smaller than 20 kilobytes, Rust's string formatting code, [`core::fmt`](https://doc.rust-lang.org/core/fmt/index.html) must -be removed. `panic_immediate_abort` only removes some usages of this code. There is a lot of other +be removed. `panic=immediate-abort` only removes some usages of this code. There is a lot of other code that uses formatting in some cases. That includes Rust's "pre-main" code in `libstd`. By using a C entry point (by adding the `#![no_main]` attribute) , managing stdio manually, and From 24233f98d9a8a484302408ed6b5431ed8f720321 Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Fri, 3 Oct 2025 18:20:49 +0800 Subject: [PATCH 48/48] Fix regression of switching to new `panic=immediate-abort` flag (#87) --- .github/workflows/build.yml | 2 +- README.md | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd6fe40..cdcc0b7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,4 +76,4 @@ jobs: run: > rustup component add rust-src; RUSTFLAGS="-Zlocation-detail=none -Zfmt-debug=none" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features="optimize_for_size" --target x86_64-unknown-linux-gnu --release; - RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" cargo +nightly build -Z build-std=std,panic_abort --target x86_64-unknown-linux-gnu --release; + RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" cargo +nightly build -Z build-std=std,panic_abort -Z build-std-features= --target x86_64-unknown-linux-gnu --release; diff --git a/README.md b/README.md index b99afed..f939890 100644 --- a/README.md +++ b/README.md @@ -230,11 +230,14 @@ and formatting code in final binary by default. has been merged into the `nightly` `rustc` compiler to address this. To use this, repeat the instructions above to use `build-std`, but also pass -[`-Zunstable-options -Cpanic=immediate-abort`](https://doc.rust-lang.org/rustc/command-line-arguments.html#-z-set-unstable-options) +[`-Zunstable-options -Cpanic=immediate-abort`](https://doc.rust-lang.org/rustc/command-line-arguments.html#-z-set-unstable-options) and +[`-Z build-std-features=`](https://doc.rust-lang.org/cargo/reference/unstable.html#build-std-features) (which will disable the default `backtrace` and `panic-unwind` features) to `rustc`. ```bash -$ RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" cargo +nightly build -Z build-std=std,panic_abort \ +$ RUSTFLAGS="-Zunstable-options -Cpanic=immediate-abort" cargo +nightly build \ + -Z build-std=std,panic_abort \ + -Z build-std-features= \ --target x86_64-apple-darwin --release ```