Remove unwind routines from a musl-linked build

Hi!

I would like to make a small Rust binary, and because of that I am linking against musl and would like to remove unwind calls. This works for glibc, however for the former the calls and code are still there. Can you tell me how to fix it?
Below is a bloat listing from musl and glibc build for comparison.


~/w/h/rusb (master|✚2) $ env  RUST_BACKTRACE=1 TARGET=linux PKG_CONFIG=(which pkg-config) cargo +nightly bloat  -Z build-std=std,core,panic_abort -Z build-std-features=panic_immediate_abort --target=x86_64-unknown
-linux-musl --release  --example read_device
   Compiling compiler_builtins v0.1.87
 ......
warning: `rusb` (lib) generated 1 warning
   Compiling regex v1.7.2
    Finished release [optimized] target(s) in 15.50s
    Analyzing /tmp/cargo/x86_64-unknown-linux-musl/release/examples/read_device

 File  .text     Size       Crate Name
 7.6%  18.5%  19.6KiB   [Unknown] _ZN9libunwind10CFI_ParserINS_17LocalAddressSpaceEE20parseFDEInstructionsERS1_RKNS2_8FDE_InfoERKNS2_8CIE_InfoEmiPNS2_10PrologInfoE
 1.7%   4.1%   4.3KiB   [Unknown] _ZN9libunwind17DwarfInstructionsINS_17LocalAddressSpaceENS_16Registers_x86_64EE13stepWithDwarfERS1_mmRS2_Rb
 1.5%   3.7%   3.9KiB   [Unknown] _ZN9libunwind17DwarfInstructionsINS_17LocalAddressSpaceENS_16Registers_x86_64EE18evaluateExpressionEmRS1_RKS2_m
 1.4%   3.3%   3.5KiB read_device read_device::main
 1.1%   2.7%   2.9KiB   [Unknown] _ZN9libunwind10CFI_ParserINS_17LocalAddressSpaceEE9decodeFDEERS1_mPNS2_8FDE_InfoEPNS2_8CIE_InfoEb
 1.1%   2.7%   2.9KiB   [Unknown] fmt_fp
 1.1%   2.7%   2.8KiB   [Unknown] _ZN9libunwind10CFI_ParserINS_17LocalAddressSpaceEE8parseCIEERS1_mPNS2_8CIE_InfoE
 1.1%   2.7%   2.8KiB   [Unknown] _ZN9libunwind14EHHeaderParserINS_17LocalAddressSpaceEE7findFDEERS1_mmjPNS_10CFI_ParserIS1_E8FDE_InfoEPNS5_8CIE_InfoE
 1.0%   2.4%   2.6KiB   [Unknown] __unw_add_dynamic_fde
 1.0%   2.4%   2.5KiB   [Unknown] _ZN9libunwind10CFI_ParserINS_17LocalAddressSpaceEE7findFDEERS1_mmmmPNS2_8FDE_InfoEPNS2_8CIE_InfoE
 1.0%   2.4%   2.5KiB   [Unknown] main
 0.9%   2.2%   2.3KiB   [Unknown] printf_core
 0.7%   1.7%   1.8KiB   [Unknown] _ZN9libunwind14EHHeaderParserINS_17LocalAddressSpaceEE11decodeEHHdrERS1_mmRNS2_12EHHeaderInfoE
 0.6%   1.4%   1.5KiB   [Unknown] malloc
 0.5%   1.2%   1.3KiB         std <&T as core::fmt::Debug>::fmt
 0.5%   1.1%   1.2KiB   [Unknown] __bin_chunk
 0.4%   0.9%     988B   [Unknown] _ZN9libunwind17LocalAddressSpace11getEncodedPERmmhm
 0.3%   0.8%     873B   [Unknown] unwind_phase2
 0.3%   0.8%     853B read_device read_device::read_endpoint
 0.3%   0.7%     797B   [Unknown] unwind_phase2_forced
16.5%  40.4%  42.7KiB             And 381 smaller methods. Use -n N to show more.
40.8% 100.0% 105.6KiB             .text section size, the file size is 258.9KiB
~/w/h/rusb (master|✚2) $ env  RUST_BACKTRACE=1 TARGET=linux PKG_CONFIG=(which pkg-config) cargo +nightly bloat  -Z build-std=std,core,panic_abort -Z build-std-features=panic_immediate_abort --target=x86_64-unknown
-linux-gnu --release  --example read_device
....
    Finished release [optimized] target(s) in 14.85s
    Analyzing /tmp/cargo/x86_64-unknown-linux-gnu/release/examples/read_device

 File  .text    Size             Crate Name
 4.9%  12.9%  3.5KiB       read_device read_device::main
 3.8%   9.9%  2.7KiB         [Unknown] main
 1.8%   4.6%  1.3KiB               std <&T as core::fmt::Debug>::fmt
 1.2%   3.1%    853B       read_device read_device::read_endpoint
 1.0%   2.7%    753B              core <core::fmt::builders::PadAdapter as core::fmt::Write>::write_str
 0.9%   2.4%    659B       read_device read_device::convert_argument
 0.9%   2.3%    652B              rusb rusb::device_handle::DeviceHandle<T>::read_string_descriptor
 0.8%   2.1%    573B               std std::io::stdio::_print
 0.7%   1.8%    501B              core core::fmt::Formatter::pad_integral
 0.6%   1.6%    448B               std std::sys::unix::stack_overflow::imp::signal_handler
 0.6%   1.6%    448B              core <core::str::iter::Chars as core::iter::traits::iterator::Iterator>::count
 0.6%   1.6%    444B               std <std::env::Args as core::iter::traits::iterator::Iterator>::next
 0.6%   1.6%    438B              core core::fmt::write
 0.5%   1.4%    399B              core core::fmt::builders::DebugStruct::field
 0.4%   1.1%    311B              core core::fmt::builders::DebugTuple::field
 0.4%   1.1%    298B              core core::fmt::Formatter::pad
 0.4%   1.0%    289B               std std::io::error::Error::kind
 0.4%   1.0%    283B compiler_builtins compiler_builtins::float::trunc::__truncdfsf2
 0.4%   1.0%    272B       read_device read_device::find_readable_endpoint
 0.4%   1.0%    269B               std <std::io::Write::write_fmt::Adapter<T> as core::fmt::Write>::write_str
16.5%  43.4% 11.8KiB                   And 185 smaller methods. Use -n N to show more.
38.0% 100.0% 27.2KiB                   .text section size, the file size is 71.4KiB
~/w/h/rusb (master|✚2) $

I have found a suggestion to use older Rust version, and so I tried with nightly 1.65 (2022-08-11), however I must have missed something during setup, since it does not build for me:

$ rustup install nightly-2022-08-11
$ rustup component add rust-src --toolchain nightly-2022-08-11-x86_64-unknown-linux
$ rustup toolchain install nightly-2022-08-11-x86_64-unknown-linux-musl
$ rustup target install x86_64-unknown-linux-musl --toolchain nightly-2022-08-11-x86_64-unknown-linux-musl

$ env  RUST_BACKTRACE=1 TARGET=linux PKG_CONFIG=(which pkg-config) cargo +nightl
y-2022-08-11  bloat  -Z build-std=std,core,panic_abort -Z build-std-features=panic_immediate_abort --targe
t=x86_64-unknown-linux-musl --release  --example read_device
.....
  Compiling rusb v0.9.1 (/home/sz/work/heads/rusb)
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "/usr/lib64/rcrt1.o" "/usr/lib64/crti.o" "crtbeginS.o" "/tmp/rustcm7jlGy/symbols.o"
"/tmp/cargo/x86_64-unknown-linux-musl/release/examples/read_device-df267475feeb7920.read_device.006cdd6e-c
gu.0.rcgu.o" "-Wl,--as-needed" "-L" "/tmp/cargo/x86_64-unknown-linux-musl/release/deps" "-L" "/tmp/cargo/r
elease/deps" "-L" "/usr/lib64" "-L" "/home/sz/.rustup/toolchains/nightly-2022-08-11-x86_64-unknown-linux-g
nu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,--start-group" "-Wl,-Bstatic" "-lunwind" "-lc" "-Wl,--e
nd-group" "/tmp/cargo/x86_64-unknown-linux-musl/release/deps/libcompiler_builtins-86aac3ebc3530099.rlib" "
-Wl,-Bdynamic" "-lusb-1.0" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-nostartfiles" "-L" "/home/sz/.rustup
/toolchains/nightly-2022-08-11-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" "-L" "/
home/sz/.rustup/toolchains/nightly-2022-08-11-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-mu
sl/lib/self-contained" "-o" "/tmp/cargo/x86_64-unknown-linux-musl/release/examples/read_device-df267475fee
b7920" "-Wl,--gc-sections" "-static-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs" "crtendS.o" "/usr/lib64/crtn
.o"
  = note: /usr/bin/ld: cannot find crtbeginS.o: No such file or directory
          /usr/bin/ld: cannot find -lunwind: No such file or directory
          /usr/bin/ld: cannot find -lc: No such file or directory
          collect2: error: ld returned 1 exit status


error: could not compile `rusb` due to previous error
Error: failed to execute 'cargo build'. Probably a build error.

Try CARGO_PROFILE_RELEASE_PANIC="abort" (or equivalent setting panic = "abort" for the release profile in Cargo.toml) This is required for panic_immediate_abort to work as intended and with recent nightlies you get a compile error like the following if you don't do this:

error[E0080]: evaluation of constant value failed
  --> /home/bjorn/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic.rs:57:9
   |
57 |         $crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'panic_immediate_abort requires -C panic=abort', /home/bjorn/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panicking.rs:33:15
   |
  ::: /home/bjorn/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panicking.rs:33:15
   |
33 | const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C panic=abort");
   |               ------------------------------------------------------------------------------- in this macro invocation
   |
   = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0080`.
error: could not compile `core` (lib) due to previous error
Error: failed to execute 'cargo build'. Probably a build error.

With rustc 1.70.0-nightly (2036fdd24 2023-03-27) and CARGO_PROFILE_RELEASE_PANIC="abort" I get

    Analyzing target/x86_64-unknown-linux-musl/release/foo

 File  .text    Size     Crate Name
 1.7%   6.3%  2.9KiB [Unknown] fmt_fp
 1.4%   5.1%  2.3KiB [Unknown] printf_core
 0.9%   3.3%  1.5KiB [Unknown] malloc
 0.9%   3.3%  1.5KiB      core core::str::count::do_count_chars
 0.7%   2.6%  1.2KiB [Unknown] __bin_chunk
 0.5%   2.0%    933B      core core::fmt::Formatter::pad_integral
 0.5%   1.9%    878B       std std::sys::unix::stack_overflow::imp::signal_handler
 0.5%   1.8%    855B      core core::fmt::Formatter::pad
 0.4%   1.5%    715B [Unknown] __vdsosym
 0.4%   1.5%    678B [Unknown] alloc_rev
 0.4%   1.5%    678B [Unknown] alloc_fwd
 0.4%   1.4%    654B       std std::sys::unix::init
 0.4%   1.4%    645B      core <core::fmt::builders::PadAdapter as core::fmt::Write>::write_str
 0.4%   1.3%    614B       std std::sys_common::once::futex::Once::call
 0.3%   1.3%    605B       std std::io::stdio::print_to_buffer_if_capture_used
 0.3%   1.2%    578B [Unknown] realloc
 0.3%   1.1%    526B       std std::rt::init
 0.3%   1.1%    524B      core core::fmt::write
 0.3%   1.1%    505B     alloc <&[u8] as alloc::ffi::c_str::CString::new::SpecNewImpl>::spec_new_impl
 0.3%   1.0%    465B       std <std::io::buffered::linewritershim::LineWriterShim<W> as std::io::Write>::write_all
14.6%  54.7% 24.8KiB           And 228 smaller methods. Use -n N to show more.
26.7% 100.0% 45.3KiB           .text section size, the file size is 169.9KiB

on "Hello World!". It is bigger than the glibc version, but that is to be expected as the musl target by default statically links libc, while the glibc defaults to dynamic linking.

4 Likes

Hey! Thank you for the reply! I am terribly sorry for the delay. For the sake of completeness:

  1. It turned out I was using wrong command for installing the dependency, and it helped to run the following:
$ rustup install nightly-2022-08-11
$ rustup +nightly-2022-08-11 component add rust-src
$ rustup +nightly-2022-08-11 target install x86_64-unknown-linux-musl

With this the linking was successful.

  1. The suggestion I was mentioning before about 1.66 breaking linking is stated here:

Although now I am not sure it is relevant in this case, especially while it works for you. I have not tested your version yet.

  1. My Cargo.toml was:
[profile.release]
#strip = "symbols"
opt-level = "z"  # Optimize for size.
lto = true
codegen-units = 1
panic = "abort"
debug = false
debug-assertions = false
overflow-checks = false
  1. If you are curious where I needed that:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.