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

Allow use with Cargo's "build-std" feature #62

Closed
drmikehenry opened this issue Sep 12, 2020 · 6 comments
Closed

Allow use with Cargo's "build-std" feature #62

drmikehenry opened this issue Sep 12, 2020 · 6 comments

Comments

@drmikehenry
Copy link

Cargo has a recent nightly-only feature for building the Rust standard library (std) as part of a normal build: https://github.com/rust-lang/wg-cargo-std-aware

Consider this example project:

cargo new bloattest
cd bloattest
cat <<'EOF' >> Cargo.toml

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
EOF
cargo build --release --target x86_64-unknown-linux-gnu

cargo-bloat works properly here:

cargo bloat --release --target x86_64-unknown-linux-gnu

It generates this output:

    Finished release [optimized] target(s) in 0.00s
    Analyzing target/x86_64-unknown-linux-gnu/release/bloattest

 File  .text     Size     Crate Name
 2.2%  16.7%  28.7KiB       std std::backtrace_rs::symbolize::gimli::elf::<impl std::backtrace_rs::symbolize::gimli::Mapping>::new
 0.8%   6.2%  10.7KiB       std addr2line::ResUnit<R>::parse_lines
 0.7%   5.3%   9.2KiB       std miniz_oxide::inflate::core::decompress
 0.6%   4.8%   8.3KiB       std std::sys_common::backtrace::_print_fmt::{{closure}}
 0.4%   2.8%   4.9KiB       std addr2line::ResUnit<R>::parse_functions
 0.4%   2.8%   4.8KiB       std gimli::read::unit::parse_attribute
 0.3%   2.4%   4.1KiB       std rustc_demangle::v0::Printer::print_type
 0.3%   2.3%   3.9KiB       std addr2line::Function<R>::parse_children
 0.3%   2.2%   3.7KiB       std <std::backtrace_rs::symbolize::SymbolName as core::fmt::Display>::fmt
 0.3%   2.1%   3.6KiB       std gimli::read::rnglists::RngListIter<R>::next
 0.3%   1.9%   3.2KiB       std core::slice::sort::recurse
 0.2%   1.8%   3.1KiB       std rustc_demangle::try_demangle
 0.2%   1.7%   2.9KiB [Unknown] main
 0.2%   1.3%   2.3KiB       std gimli::read::line::parse_attribute
 0.2%   1.3%   2.2KiB       std std::sys_common::backtrace::output_filename
 0.2%   1.2%   2.2KiB       std core::str::pattern::StrSearcher::new
 0.2%   1.2%   2.1KiB       std rustc_demangle::v0::Printer::print_path
 0.1%   1.1%   1.9KiB       std gimli::read::unit::Attribute<R>::value
 0.1%   1.0%   1.7KiB       std std::backtrace_rs::symbolize::gimli::callback
 0.1%   0.9%   1.6KiB       std std::backtrace_rs::print::BacktraceFrameFmt::print_raw
 5.0%  37.8%  65.0KiB           And 228 smaller methods. Use -n N to show more.
13.4% 100.0% 172.1KiB           .text section size, the file size is 1.3MiB

Cargo's new build-std feature can reduce the executable size:

rustup component add rust-src

cargo build --release \
    --target x86_64-unknown-linux-gnu \
    -Z build-std=panic_abort,std \
    -Z build-std-features=panic_immediate_abort

cargo-bloat doesn't work with this build method:

cargo bloat --release \
    --target x86_64-unknown-linux-gnu \
    -Z build-std=panic_abort,std \
    -Z build-std-features=panic_immediate_abort

The above results in this error:

Error: unused arguments left: -Z, build-std=panic_abort,std, -Z, build-std-features=panic_immediate_abort.

If cargo-bloat would pass along the various nightly-only -Z arguments to cargo build, it could be used successfully. As a proof-of-concept, here is a cargo shim to force the build-std arguments:

mkdir cargo-bin
cat <<'EOF' > cargo-bin/cargo
#!/bin/sh

if [ "$1" = "build" ]; then
    shift
    set -- build \
        -Z build-std=panic_abort,std \
        -Z build-std-features=panic_immediate_abort \
        "$@"
fi

exec ~/.rustup/toolchains/nightly-2020-08-20-x86_64-unknown-linux-gnu/bin/cargo "$@"
EOF
chmod +x cargo-bin/cargo

The shim assumes the toolchain "nightly-2020-08-20" for convenience. Now cargo-bloat works properly:

PATH="$PWD/cargo-bin:$PATH" cargo bloat --release \
  --target x86_64-unknown-linux-gnu

It generates this output:

    Finished release [optimized] target(s) in 0.06s
    Analyzing target/x86_64-unknown-linux-gnu/release/bloattest

 File  .text    Size     Crate Name
 3.1%   9.6%  1.4KiB [Unknown] main
 2.5%   7.9%  1.1KiB      core <str as core::fmt::Debug>::fmt
 1.4%   4.3%    631B      std? <std::io::Write::write_fmt::Adaptor<T> as core::fmt::Write>::write_str
 1.4%   4.3%    624B       std std::thread::Thread::new
 1.3%   4.2%    609B       std std::io::stdio::stdout
 1.3%   3.9%    567B bloattest bloattest::main
 1.2%   3.8%    554B      core core::fmt::Formatter::pad_integral
 1.1%   3.3%    478B       std std::sync::once::Once::call_once::{{closure}}
 1.0%   3.1%    454B      core core::fmt::write
 0.7%   2.2%    319B       std std::sys::unix::thread_local_dtor::register_dtor
 0.7%   2.2%    315B       std std::io::buffered::BufWriter<W>::flush_buf
 0.6%   2.0%    290B       std std::sys::unix::stack_overflow::imp::signal_handler
 0.6%   1.9%    282B      core core::fmt::Formatter::pad
 0.5%   1.5%    216B      core core::unicode::printable::check
 0.4%   1.4%    199B      std? <std::io::Write::write_fmt::Adaptor<T> as core::fmt::Write>::write_str
 0.4%   1.3%    196B       std <std::io::buffered::BufWriter<W> as std::io::Write>::write
 0.4%   1.3%    192B      core core::fmt::num::imp::fmt_u64
 0.4%   1.2%    182B      core core::str::slice_error_fail
 0.4%   1.2%    178B       std std::sys_common::thread_info::THREAD_INFO::__getit
 0.4%   1.2%    173B       std <std::io::stdio::Stdout as std::io::Write>::write_fmt
11.7%  36.4%  5.2KiB           And 113 smaller methods. Use -n N to show more.
32.3% 100.0% 14.2KiB           .text section size, the file size is 44.1KiB

Would it be possible to add support for Cargo's build-std feature to cargo-bloat?

@RazrFalcon
Copy link
Owner

cargo-bloat simply doesn't support -Z options. Not sure how hard it would be to implement them.

As a workaround, you can simply use RUSTFLAGS env.

@drmikehenry
Copy link
Author

Yes, I was hoping cargo-bloat could be extended to support passing along nightly cargo options directly. That would fix this case, as well as any future cases of nightly options.

I don't see how to use RUSTFLAGS as a work-around. The -Z build-std flags are for Cargo; they cause Cargo to compile the Rust standard library from source. Isn't RUSTFLAGS for rustc options? I'd looked for a similar environment variable for Cargo, but couldn't find it. I could see a hypothetical CARGOFLAGS being a work-around, though. Am I missing something?

@RazrFalcon
Copy link
Owner

RazrFalcon commented Sep 12, 2020

I'll see what I can do.

No idea. I haven't used build-std yet.

@drmikehenry
Copy link
Author

Thanks :-) Yeah, build-std is pretty new, but it's already very usable. I do have the cargo shim work-around mentioned earlier, so with some awkwardness I can still use cargo-bloat with build-std (which is good, since cargo-bloat has been a very helpful tool in the pursuit of smaller executables).

@tnballo
Copy link

tnballo commented Nov 18, 2021

Ran into the same issue, wanted to share my workaround in case it helps. You can add some variation of the following to your .cargo/config.toml (can be project-specific or a global setting):

[unstable]
build-std=["core","std","alloc","proc_macro","panic_abort"]
build-std-features=["panic_immediate_abort"]

Then you can run cargo bloat as normal, and std will be built from source.

More generally, maybe a blurb on using cargo's config.toml should be added to this project's README.md? There's potentially several usecases for which this would be easier to support than additional command line flags.

@RazrFalcon
Copy link
Owner

I just have to support -Z flags. That's it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants