ArchLinux下Cargo编译的Release二进制为何比Fedora 36大很多?
ArchLinux与Fedora下Rust编译Release二进制体积差异原因分析
问题现象
ArchLinux下编译Rust项目的Release二进制文件体积远大于Fedora 36(toolbox容器)中的产物:
ArchLinux编译结果
$ cargo clean $ cargo build --release $ du -h target/release/ks_trace 3,7M target/release/ks_trace
Fedora 36编译结果
$ cargo clean $ toolbox run cargo build --release # 在Fedora 36容器中执行 $ du -h target/release/ks_trace 420K target/release/ks_trace
补充说明:在
Cargo.toml中手动添加优化规则后,两个系统编译出的二进制体积均可降至约200KB。
cargo bloat分析结果
执行cargo bloat --release对比两个系统的二进制内容,发现核心代码段(.text)大小几乎完全一致,差异仅在于整体文件占比:
ArchLinux输出
$ cargo bloat --release File .text Size Crate Name 0.5% 8.6% 19.8KiB std addr2line::ResDwarf<R>::parse 0.5% 7.9% 18.2KiB std std::backtrace_rs::symbolize::gimli::resolve::{{closure}} 0.3% 4.2% 9.6KiB std addr2line::ResUnit<R>::parse_lines 0.2% 3.7% 8.5KiB std miniz_oxide::inflate::core::decompress 0.2% 2.6% 5.9KiB std gimli::read::abbrev::Abbreviations::insert 0.1% 1.9% 4.5KiB std gimli::read::unit::parse_attribute 0.1% 1.7% 4.0KiB std addr2line::function::Function<R>::parse_children 0.1% 1.7% 3.9KiB std std::backtrace_rs::symbolize::gimli::Context::new 0.1% 1.6% 3.7KiB std core::slice::sort::recurse 0.1% 1.6% 3.7KiB std gimli::read::rnglists::RngListIter<R>::next 0.1% 1.4% 3.3KiB xentrace_parser xentrace_parser::xentrace_parse 0.1% 1.4% 3.2KiB std std::backtrace_rs::symbolize::gimli::elf::<impl std::backtrace_rs::symbolize::gimli::... 0.1% 1.3% 3.1KiB std rustc_demangle::demangle 0.1% 1.3% 2.9KiB xentrace_parser alloc::slice::merge_sort 0.1% 1.2% 2.8KiB std <rustc_demangle::legacy::Demangle as core::fmt::Display>::fmt 0.1% 1.0% 2.3KiB std gimli::read::line::parse_attribute 0.1% 0.9% 2.1KiB std core::str::count::do_count_chars 0.0% 0.8% 1.8KiB std rustc_demangle::v0::Printer::print_const 0.0% 0.8% 1.8KiB std hashbrown::raw::RawTable<T,A>::reserve_rehash 0.0% 0.8% 1.8KiB std rustc_demangle::v0::Printer::print_path 3.1% 51.5% 118.6KiB And 566 smaller methods. Use -n N to show more. 6.1% 100.0% 230.3KiB .text section size, the file size is 3.7MiB
Fedora输出
$ toolbox run cargo bloat --release File .text Size Crate Name 4.7% 8.6% 19.8KiB std addr2line::ResDwarf<R>::parse 4.3% 7.9% 18.2KiB std std::backtrace_rs::symbolize::gimli::resolve::{{closure}} 2.3% 4.2% 9.6KiB std addr2line::ResUnit<R>::parse_lines 2.0% 3.7% 8.5KiB std miniz_oxide::inflate::core::decompress 1.4% 2.6% 5.9KiB std gimli::read::abbrev::Abbreviations::insert 1.1% 1.9% 4.5KiB std gimli::read::unit::parse_attribute 0.9% 1.7% 4.0KiB std addr2line::function::Function<R>::parse_children 0.9% 1.7% 3.9KiB std std::backtrace_rs::symbolize::gimli::Context::new 0.9% 1.6% 3.7KiB std core::slice::sort::recurse 0.9% 1.6% 3.7KiB std gimli::read::rnglists::RngListIter<R>::next 0.8% 1.4% 3.3KiB xentrace_parser xentrace_parser::xentrace_parse 0.8% 1.4% 3.2KiB std std::backtrace_rs::symbolize::gimli::elf::<impl std::backtrace_rs::symbolize::gimli:... 0.7% 1.3% 3.1KiB std rustc_demangle::demangle 0.7% 1.3% 2.9KiB xentrace_parser alloc::slice::merge_sort 0.7% 1.2% 2.8KiB std <rustc_demangle::legacy::Demangle as core::fmt::Display>::fmt 0.5% 1.0% 2.3KiB std gimli::read::line::parse_attribute 0.5% 0.9% 2.1KiB std core::str::count::do_count_chars 0.4% 0.8% 1.8KiB std rustc_demangle::v0::Printer::print_const 0.4% 0.8% 1.8KiB std hashbrown::raw::RawTable<T,A>::reserve_rehash 0.4% 0.8% 1.8KiB std rustc_demangle::v0::Printer::print_path 28.3% 51.5% 118.7KiB And 568 smaller methods. Use -n N to show more. 55.0% 100.0% 230.5KiB .text section size, the file size is 418.9KiB
差异原因分析
从cargo bloat结果可以看到,两个二进制的核心执行代码(.text段)大小几乎完全一致,差异出现在非核心代码段的内容上,主要原因包括:
- 调试符号与信息保留差异:ArchLinux的
rustc默认可能保留了完整的调试信息(如debuginfo=2),这些信息会大幅增加文件体积;而Fedora的rustc默认配置可能降低了调试信息级别,或者自动剥离了部分符号。可通过readelf -S target/release/ks_trace查看是否存在.debug_*段验证。 - 链接器默认参数不同:Fedora的链接器(ld)默认可能启用了
--gc-sections(自动移除未使用的代码段)、--strip-debug(剥离调试符号)等优化参数;而ArchLinux的链接器默认未启用这些选项,导致无用段和符号被保留。 - Rust工具链默认配置差异:不同发行版打包的Rust工具链可能带有不同的默认编译配置。比如Arch通常使用最新稳定版rustc,而Fedora使用经过适配的特定版本,默认优化策略、符号处理逻辑有区别。
- 二进制后处理步骤:Fedora可能在编译完成后自动对二进制文件做了剥离符号、压缩等后处理操作,而ArchLinux没有这一步。
当手动在Cargo.toml中添加优化规则后,这些默认配置被覆盖,两个系统的编译结果体积趋于一致,也验证了上述原因。
内容的提问来源于stack exchange,提问作者Giuseppe
相关产品推荐
相关产品推荐

