Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strip buildpack binaries when packaging #445

Merged
merged 1 commit into from
Jul 5, 2022
Merged

Conversation

edmorley
Copy link
Member

@edmorley edmorley commented Jul 4, 2022

As of Rust 1.59, Cargo now supports a strip option, which when enabled, causes the generated binaries to be stripped of all symbol information:
https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html#creating-stripped-binaries
https://doc.rust-lang.org/beta/cargo/reference/profiles.html#strip

Doing this significantly reduces the size of the binaries, which:

  • Results in smaller overall production builder image sizes, which reduces push/pull times.
  • Helps speed up workflows where the otherwise large dev/debug builds were being used (such as integration tests or local buildpack development), since Docker/pack build's transfer of files into the ephemeral builder image is very slow.
  • Helps reduce any end-user perception of libcnb.rs powered CNBs being bloated compared to say bash-based CNBs (and also keeps us competitive with any Go-based CNB frameworks).

Before/after comparison:

  • examples/basics:
    • dev build: 22.01 MiB -> 3.26 MiB
    • release build: 5.04 MiB -> 1.29 MiB
  • examples/exec.d:
    • dev build: 37.40 MiB -> 4.10 MiB
    • release build: 9.02 MiB -> 1.78 MiB
    • cargo test -- --ignored: 5.5s -> 2.6s (performed on an M1, so with slow QEMU emulation)
  • heroku/procfile:
    • dev build: 43.40 MiB -> 5.16 MiB
    • release build: 6.27 MiB -> 2.17 MiB
    • cargo test -- --ignored: 9.1s -> 5.2s (performed on an M1, so with slow QEMU emulation)
  • heroku/jvm:
    • dev build: 116.55 MiB -> 15.52 MiB
    • release build: 24.40 MiB -> 7.38 MiB
    • cargo test --test integration_tests: 97s -> 82s (performed on an M1, so with slow QEMU emulation)

Stripping the binaries does not result in any loss of useful backtraces, since with the cross-compilation and/or usage of MUSL, these did not work even in debug buildpack builds anyway. Both before and after this change, any panics still show the originating file/line number, which is all that's generally required when debugging. Lastly, even if backtraces had previously worked, they are a pain to enable given that the env has to be set outside of the buildpack invocation, so can't be used when clear_env = true is set etc.

Since Cargo only supports the strip option as of Rust 1.59, the minimum Rust version has been bumped to match. This bump is the reason for the breaking change label, rather than the enabling stripping itself.

Fixes #319.
GUS-W-11324847.

As of Rust 1.59, Cargo now supports a `strip` option, which when enabled,
causes the binaries output to stripped of all symbol information:
https://blog.rust-lang.org/2022/02/24/Rust-1.59.0.html#creating-stripped-binaries
https://doc.rust-lang.org/beta/cargo/reference/profiles.html#strip

Doing this significantly reduces the size of the binaries, which:
- Results in smaller overall production builder image sizes, which
  reduces push/pull times.
- Helps speed up workflows where the otherwise large dev/debug builds
  were being used (such as integration tests or local buildpack development),
  since Docker/`pack build`'s transfer of files into the ephemeral builder image
  is very slow.
- Helps reduce any end-user perception of `libcnb.rs` powered CNBs being
  bloated compared to say bash-based CNBs (and also keeps us competitive
  with any Go-based CNB frameworks).

Before/after comparison:
- `examples/basics`:
  - dev build: 22.01 MiB -> 3.26 MiB
  - release build: 5.04 MiB -> 1.29 MiB
- `examples/exec.d`:
  - dev build: 37.40 MiB -> 4.10 MiB
  - release build: 9.02 MiB -> 1.78 MiB
  - `cargo test -- --ignored`: 5.5s -> 2.6s
- `heroku/procfile`:
  - dev build: 43.40 MiB -> 5.16 MiB
  - release build: 6.27 MiB -> 2.17 MiB
  - `cargo test -- --ignored`: 9.1s -> 5.2s
- `heroku/jvm`:
  - dev build: 116.55 MiB -> 15.52 MiB
  - release build: 24.40 MiB -> 7.38 MiB
  - `cargo test --test integration_tests`: 97s -> 82s

Stripping the binaries does not result in any loss of useful backtraces, since
with the cross-compilation and/or usage of MUSL, these did not work even
in debug buildpack builds anyway. Both before and after this change, any
panics still show the originating file/line number, which is all that's generally
required when debugging. Lastly, even if backtraces had previously worked,
they are a pain to enable given that the env has to be set outside of the
buildpack invocation, so can't be used when `clear_env = true` is set etc.

Since Cargo only supports the `strip` option as of Rust 1.59, the minimum
Rust version has been bumped to match.

Fixes #319.
GUS-W-11324847.
@edmorley edmorley added libcnb-cargo libcnb-data examples libcnb libcnb-test breaking change libcnb-proc-macros slim buildpacks Things that affect the size of the compiled binaries or packaged buildpacks faster tests Things that improve the runtime of tests libcnb-package labels Jul 4, 2022
@edmorley edmorley self-assigned this Jul 4, 2022
@edmorley edmorley marked this pull request as ready for review July 4, 2022 13:27
@edmorley edmorley requested a review from a team as a code owner July 4, 2022 13:27
libcnb-package/src/build.rs Show resolved Hide resolved
@edmorley edmorley merged commit fdb0ae6 into main Jul 5, 2022
@edmorley edmorley deleted the edmorley/strip-binaries branch July 5, 2022 09:17
edmorley added a commit that referenced this pull request Jul 7, 2022
* Adds READMEs for the `libcnb-data` and `libcnb-proc-macros` crates,
  since previously they were bundling the repo root README, which was
  confusing when looking at their crates.io listing (#274).
* Corrects the MSRV listed in the READMEs so it matches that defined in
  each crate's `Cargo.toml` after #445.
* Adds badges to READMEs that didn't have them, to improve discoverability
  of the docs (eg towards #402) and awareness of latest version of each crate.
  Note: `libcnb-cargo` does not have a docs link since it's a binary not a library.
* Syncs the `libcnb-cargo` usage example output with the latest output
  used in the repo root README.
* Switches the docs.rs URLs style from `/*/` to `/latest/` since the former
  resolves to an exact version, which if bookmarked (or search engine indexed)
  will get out of date.
* Various other small tweaks.

Fixes #274.
Addresses part of #402.
edmorley added a commit that referenced this pull request Jul 7, 2022
* Adds READMEs for the `libcnb-data` and `libcnb-proc-macros` crates,
  since previously they were bundling the repo root README, which was
  confusing when looking at their crates.io listing (#274).
* Corrects the MSRV listed in the READMEs so it matches that defined in
  each crate's `Cargo.toml` after #445.
* Adds badges to READMEs that didn't have them, to improve discoverability
  of the docs (eg towards #402) and awareness of latest version of each crate.
  Note: `libcnb-cargo` does not have a docs link since it's a binary not a library.
* Syncs the `libcnb-cargo` usage example output with the latest output
  used in the repo root README.
* Switches the docs.rs URLs style from `/*/` to `/latest/` since the former
  resolves to an exact version, which if bookmarked (or search engine indexed)
  will get out of date.
* Various other small tweaks.

Fixes #274.
Addresses part of #402.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change examples faster tests Things that improve the runtime of tests libcnb libcnb-cargo libcnb-data libcnb-package libcnb-proc-macros libcnb-test slim buildpacks Things that affect the size of the compiled binaries or packaged buildpacks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Strip packaged binaries to reduce buildpack size
2 participants