-
Notifications
You must be signed in to change notification settings - Fork 0
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
HTTP (127KB) and HTTPS (766KB) #16
Comments
Dynamic linked gnu target (for glibc + openssl) for 112KB (HTTPS) / 84.6KB (HTTP)For base images which need glibc + openssl for other binaries, a dynamically linked This would require adding another feature to # Additional build flags from `neonmoe/minreq/issues/111` used, only provides a 10KB additional reduction:
# NOTE: Unlike the original issue message, these results are from a slightly modified `httpget`,
# but it should be roughly equivalent.
RUSTFLAGS='-Z location-detail=none -Z fmt-debug=none -C link-arg=-fuse-ld=lld -C relocation-model=static' \
cargo build --release --target x86_64-unknown-linux-gnu --features tls \
-Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort,optimize_for_size # NOTE: ldd is not exactly accurate for knowing which externally linked dependencies are required,
# `libz` is actually from `libcrypto` (part of OpenSSL 3)
$ ldd target/x86_64-unknown-linux-gnu/release/httpget
linux-vdso.so.1 (0x00007fff311dc000)
libssl.so.3 => /lib64/libssl.so.3 (0x00007f3cfb0f5000)
libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007f3cfac44000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3cfaa52000)
libz.so.1 => /lib64/libz.so.1 (0x00007f3cfaa31000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3cfb1d2000)
$ dnf install -y patchelf
# Direct libraries (linked by the binary only)
$ patchelf --print-needed target/x86_64-unknown-linux-gnu/release/httpget
libssl.so.3
libcrypto.so.3
libc.so.6
# `libz` isn't available on Google Distroless,
# but since this isn't actually a directly linked library for `httpget`, this is not a concern:
$ patchelf --print-needed /lib64/libcrypto.so.3
libz.so.1
libc.so.6 If you did consider glibc dynamic linking, you should consider the build host will set the minimum glibc version to whatever it has. One way around that is via UPX compression (HTTPS => 53KB, HTTP => 43KB)With a compressed executable via UPX: $ upx --lzma target/x86_64-unknown-linux-gnu/release/httpget
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2024
UPX 4.2.4 Markus Oberhumer, Laszlo Molnar & John Reiser May 9th 2024
File size Ratio Format Name
-------------------- ------ ----------- -----------
112024 -> 53088 47.39% linux/amd64 httpget
# For reference, dynamically linked HTTP only build with UPX is 43KB:
upx --lzma target/x86_64-unknown-linux-gnu/release/httpget
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2024
UPX 4.2.4 Markus Oberhumer, Laszlo Molnar & John Reiser May 9th 2024
File size Ratio Format Name
-------------------- ------ ----------- -----------
84600 -> 43256 51.13% linux/amd64 httpget NOTE: UPX will prevent inspection of linked libraries, appearing as a static one:
Upstream reductions for
|
Thank you for the comprehensive breakdown! I'll investigate this on my end and see what the implication of those nightly features are. I think I'm more partial to the idea of publishing a compressed and an uncompressed binary side-by-side so folks can choose their own threat model. I'm not super familiar with UPX or with binary compression in that way so I don't want to force that on folks. I've already opened #17 to start updating the cargo file, I will see if I can do an update to the docs with the updated binary sizes and publish a new version to start with |
A bit verbose, but this information might assist you with that:
When using
For size impacts of these tweaks, I did make some notes about their individual impact here. AFAIK, these optimizations are all fine for
Oh that's perfectly ok, it was just added for reference, note that the issue title doesn't reference the UPX size reductions. I share some insights here as to caveats to keep in mind when deciding if UPX is appropriate. In this case for static builds I think it's fine, but it's quite easy to use a separate stage in a At the current size without UPX involved, I think most do not have a need push it down further with compression, it'll already be compressed with the image over the network pulls, and in constrained environments it'd use more CPU and memory which would be more valuable than disk. If you decide to publish with such it should be clear that UPX was used, especially in other projects where chasing disk size improvements can unintentionally negatively impact runtime costs. |
Thank you so much for this detailed follow-up! I'll be trying to schedule the work sometime in the next couple of months between my work-work and class work |
You can build
httpget
with nightly for some improvements in size reduction: neonmoe/minreq#111Reproduction
I've adapted the referenced example to
httpget
build. I've omitted some extra optimizations from the linked issue which would be approx 20KB smaller (or 50%+ with UPX for further reduction via compression).HTTP only (127.5KB)
HTTPS (766KB)
Size improvement
cargo update
+ UPXFor the
--features tls
results, if you updateCargo.lock
withcargo update
the sizes are1,268,056
vs766,320
, which is a nice improvement in savings.rustls
, that was true with theCargo.lock
before update dependencies #15Use UPX to bring the HTTPS build down to just 432KB 😎 (for an HTTP-only build, this reduces down to about 70KB)
The text was updated successfully, but these errors were encountered: