Find out what takes most of the space in your executable.

Overview

cargo-bloat

Find out what takes most of the space in your executable.

Supports ELF (Linux, BSD), Mach-O (macOS) and PE (Windows) binaries.

WASM is not supported. Use twiggy instead.

Inspired by google/bloaty.

Install

cargo install cargo-bloat

or

cargo install cargo-bloat --no-default-features

if you don't need regex filtering using the --filter option.

Usage

Get a list of the biggest functions in the release build:

% cargo bloat --release -n 10
Compiling ...
Analyzing target/release/cargo-bloat

 File  .text     Size       Crate Name
 0.9%   7.1%  27.0KiB cargo_bloat cargo_bloat::main
 0.8%   5.7%  21.4KiB cargo_bloat cargo_bloat::process_crate
 0.3%   2.3%   8.6KiB   [Unknown] read_line_info
 0.3%   2.1%   7.9KiB         std std::sys::unix::process::process_common::Command::capture_env
 0.3%   2.1%   7.8KiB        json json::parser::Parser::parse
 0.2%   1.7%   6.5KiB   [Unknown] elf_add
 0.2%   1.7%   6.3KiB         std __rdos_backtrace_dwarf_add
 0.2%   1.3%   5.0KiB         std <rustc_demangle::legacy::Demangle as core::fmt::Display>::fmt
 0.2%   1.3%   4.9KiB         std std::sys_common::backtrace::_print
 0.2%   1.3%   4.8KiB         std core::num::flt2dec::strategy::dragon::format_shortest
 9.8%  73.5% 278.0KiB             And 932 smaller methods. Use -n N to show more.
13.3% 100.0% 378.0KiB             .text section size, the file size is 2.8MiB

Get a list of the biggest dependencies in the release build:

% cargo bloat --release --crates
Compiling ...
Analyzing target/release/cargo-bloat

 File  .text     Size Crate
 8.1%  61.2% 231.5KiB std
 2.5%  19.2%  72.4KiB cargo_bloat
 1.2%   9.4%  35.5KiB [Unknown]
 1.0%   7.2%  27.2KiB json
 0.3%   2.2%   8.5KiB pico_args
 0.1%   0.4%   1.7KiB multimap
 0.0%   0.3%   1.1KiB memmap
 0.0%   0.0%     175B term_size
 0.0%   0.0%      45B time
13.3% 100.0% 378.0KiB .text section size, the file size is 2.8MiB

Note: numbers above are a result of guesswork. They are not 100% correct and never will be.

Get a list of the biggest functions in the release build filtered by the regexp:

Note: you have to build cargo-bloat with a regex-filter feature enabled.

% cargo bloat --release --filter '^__' -n 10
Compiling ...
Analyzing target/release/cargo-bloat

File .text    Size Crate Name
0.2%  1.7%  6.3KiB   std __rdos_backtrace_dwarf_add
0.1%  0.5%  1.9KiB   std __rdos_backtrace_qsort
0.0%  0.2%    843B   std __udivmodti4
0.0%  0.1%    296B   std __floattidf
0.0%  0.1%    290B   std __floattisf
0.0%  0.1%    284B   std __rdos_backtrace_initialize
0.0%  0.1%    253B   std __floatuntisf
0.0%  0.1%    253B   std __floatuntidf
0.0%  0.1%    211B   std __rdos_backtrace_get_view
0.0%  0.0%    180B   std __rdos_backtrace_vector_grow
0.1%  0.7%  2.8KiB       And 37 smaller methods. Use -n N to show more.
0.5%  3.6% 13.5KiB       filtered data size, the file size is 2.8MiB

Get a list of crates that took longest to compile:

% cargo bloat --time -j 1
 Time Crate
1.42s pdb
1.37s regex_syntax
1.11s cargo_bloat
0.96s regex
0.58s binfarce
0.54s json
0.45s libc
0.22s uuid
0.20s fallible_iterator
0.19s pico_args
0.18s scroll
0.12s memmap2
0.09s multimap
0.06s term_size

Flags specific for cargo-bloat:

    --crates                   Per crate bloatedness
    --time                     Per crate build time. Will run `cargo clean` first
    --filter <CRATE|REGEXP>    Filter functions by crate
    --split-std                Split the 'std' crate to original crates like core, alloc, etc.
    --no-relative-size         Hide 'File' and '.text' columns
    --full-fn                  Print full function name with hash values
-n <NUM>                       Number of lines to show, 0 to show all [default: 20]
-w, --wide                     Do not trim long function names
    --message-format <FMT>     Output format [default: table] [possible values: table, json]

License

cargo-bloat is licensed under the MIT license.

Comments
  • Add basic support for PDB

    Add basic support for PDB

    See https://github.com/RazrFalcon/cargo-bloat/issues/17, I think this may be ready to merge as-is but it seems to be missing quite a few symbols. Not sure if merging initial support and possible improvements later is preferred, or waiting to see if we can get a better implementation.

    Example output on this crate:

    D:\dev\cargo-bloat [master ↑2]> cargo run ; cargo run --release -- --release
       Compiling cargo-bloat v0.10.1 (D:\dev\cargo-bloat)
        Finished dev [unoptimized + debuginfo] target(s) in 1.27s
         Running `target\debug\cargo-bloat.exe`
        Finished dev [unoptimized + debuginfo] target(s) in 0.02s
        Analyzing target\debug\cargo-bloat.exe
    
     File  .text    Size         Crate Name
     1.1%   1.4% 28.1KiB          json json::parser::Parser::parse
     0.5%   0.7% 13.2KiB          json json::util::print_dec::write
     0.5%   0.6% 11.8KiB  cargo_bloat? cargo_bloat::process_crate
     0.5%   0.6% 11.7KiB          json json::codegen::Generator::write_json
     0.5%   0.6% 11.6KiB          std? std::sys::windows::process::Command::spawn
     0.5%   0.6% 11.6KiB  cargo_bloat? cargo_bloat::parse_args
     0.4%   0.5% 10.6KiB  cargo_bloat? cargo_bloat::collect_pe_data
     0.3%   0.4%  8.0KiB           pdb <pdb::symbol::SymbolData as scroll::ctx::TryFromCtx>::try_from_ctx
     0.3%   0.4%  7.0KiB  regex_syntax <regex_syntax::hir::translate::TranslatorI as regex_syntax::ast::visitor::Visitor>::visit_class_set_item_post
     0.3%   0.3%  6.8KiB regex_syntax? regex_syntax::ast::parse::ParserI<ref_mut$<regex_syntax::ast::parse::Parser> >::parse_with_comments<ref_mut$<regex_syntax::ast::parse::Parser> >
     0.3%   0.3%  6.6KiB  regex_syntax <regex_syntax::hir::translate::TranslatorI as regex_syntax::ast::visitor::Visitor>::visit_post
     0.2%   0.3%  5.3KiB          std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,std::ffi::os_str::OsString>
     0.2%   0.3%  5.3KiB         regex regex::exec::ExecBuilder::build
     0.2%   0.3%  5.3KiB           std core::num::flt2dec::strategy::dragon::format_shortest
     0.2%   0.3%  5.3KiB          std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,enum$<core::option::Option<std::ffi::os_str::OsString>, 1, 1844674...
     0.2%   0.2%  4.7KiB  regex_syntax alloc::str::join_generic_copy
     0.2%   0.2%  4.5KiB      binfarce <binfarce::demangle::legacy::Demangle as core::fmt::Display>::fmt
     0.2%   0.2%  4.4KiB  cargo_bloat? cargo_bloat::main
     0.2%   0.2%  4.4KiB      binfarce binfarce::pe::Pe::symbols
     0.2%   0.2%  4.4KiB           std core::num::flt2dec::strategy::dragon::format_exact
    69.2%  86.9%  1.7MiB               And 10270 smaller methods. Use -n N to show more.
    79.6% 100.0%  1.9MiB               .text section size, the file size is 2.4MiB
       Compiling cargo-bloat v0.10.1 (D:\dev\cargo-bloat)
        Finished release [optimized] target(s) in 4.32s
         Running `target\release\cargo-bloat.exe --release`
        Finished release [optimized] target(s) in 0.02s
        Analyzing target\release\cargo-bloat.exe
    
     File  .text     Size Crate Name
     1.2%   1.6%  11.6KiB  std? std::sys::windows::process::Command::spawn
     0.6%   0.7%   5.3KiB  std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,std::ffi::os_str::OsString>
     0.6%   0.7%   5.3KiB   std core::num::flt2dec::strategy::dragon::format_shortest
     0.6%   0.7%   5.3KiB  std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,enum$<core::option::Option<std::ffi::os_str::OsString>, 1, 18446744073709...
     0.5%   0.6%   4.4KiB   std core::num::flt2dec::strategy::dragon::format_exact
     0.4%   0.5%   3.8KiB  std? rustc_demangle::v0::Printer::print_type
     0.3%   0.4%   3.3KiB   std rustc_demangle::demangle
     0.3%   0.4%   3.2KiB  std? std::sys::windows::process::Stdio::to_handle
     0.3%   0.4%   3.1KiB   std <rustc_demangle::legacy::Demangle as core::fmt::Display>::fmt
     0.3%   0.4%   3.0KiB   std std::process::Child::wait_with_output
     0.3%   0.4%   2.9KiB  std? rustc_demangle::v0::Printer::print_const
     0.3%   0.3%   2.6KiB  std? rustc_demangle::v0::Printer::print_path
     0.3%   0.3%   2.5KiB   std std::env::args_os
     0.2%   0.3%   2.3KiB   std core::num::flt2dec::strategy::grisu::format_shortest_opt
     0.2%   0.3%   2.1KiB  std? std::sys::windows::process::make_command_line::append_arg
     0.2%   0.2%   1.6KiB  std? std::backtrace_rs::print::BacktraceFrameFmt::print_raw_with_column
     0.2%   0.2%   1.6KiB  std? alloc::collections::btree::node::Handle::remove_leaf_kv<std::sys::windows::process::EnvKey,std::ffi::os_str::OsString,alloc::collections::btree::map::entry::...
     0.2%   0.2%   1.5KiB  std? std::panicking::default_hook
     0.2%   0.2%   1.5KiB   std <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
     0.2%   0.2%   1.5KiB  std? rustc_demangle::v0::impl$6::print_type::closure$0
    12.6%  16.2% 121.3KiB       And 518 smaller methods. Use -n N to show more.
    78.2% 100.0% 751.0KiB       .text section size, the file size is 960.5KiB
    
    opened by nico-abram 20
  • Crash when trying to check repository

    Crash when trying to check repository

    git clone https://github.com/qarmin/czkawka
    cd czkawka
    cargo bloat --release
    

    will print this panic

    rafal@rafalDesktop:~/Projekty/Rust/czkawka$ cargo bloat --release
        Finished release [optimized] target(s) in 0.08s
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: MalformedInput', /home/rafal/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-bloat-0.10.0/src/main.rs:806:59
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    
    opened by qarmin 17
  • cargo-bloat fails to find std libraries, it expects them to live in /usr/lib/rustlib

    cargo-bloat fails to find std libraries, it expects them to live in /usr/lib/rustlib

    how to reproduce, with the example of a fresh git checkout:

    cd tmp && git clone https://github.com/eqrion/cbindgen.git
    cd cbindgen
    cargo bloat 
    compiling...
    Error: failed to find a dir with std libraries. Expected location: /usr/lib/rustlib/x86_64-unknown-linux-gnu/lib.
    

    this is on a x86_64 machine, hence there's /usr/lib64/${RUSTVERSION}/ where rustlib resides. Not sure wether that is excentric behavior from my distro? :-)

    opened by stefson 14
  • Run on Library Crates

    Run on Library Crates

    Thanks for creating this tool! :smile:

    Is there a way to run cargo bloat on crates that are just libraries? If you need an executable to run on, I could pass --example foo to generate an executable for that particular example. I would like to use this on my crates to see if any functions/dependencies are taking up most of the binary generated by anyone using the crate.

    opened by sunjay 14
  • cargo-bloat 0.5.2 broken for cortex-m

    cargo-bloat 0.5.2 broken for cortex-m

    I just upgraded from 0.5.1 to 0.5.2 as result of a major upgrade frenzy and not cargo bloat spits out these messages when running for e.g. thumbv6m-none-eabi:

    Processing example blinky
       Compiling cortex-m-rt v0.5.3
       Compiling cortex-m v0.5.6
       Compiling stm32f042 v0.6.1
    LLVM ERROR: Global variable '__RESET_VECTOR' has an invalid section specifier '.vector_table.reset_vector': mach-o section specifier requires a segment whose length is between 1 and 16 characters.
    error: Could not compile `cortex-m-rt`.
    warning: build failed, waiting for other jobs to finish...
    error: build failed
    
    opened by therealprof 13
  • text section

    text section

    cargo-bloat only returns the size of the text-section of the binary. It would be more useful to try to figure out the size of a library in the whole binary (or to make it more explicit that it only deals with the text section somehow).

    Also, would it be possible to include per-library how big the debug symbols for a particular library are?

    opened by gnzlbg 11
  • Output useful information on macOS

    Output useful information on macOS

    Interesting crate! In contrast to what the Readme assumes, it doesn't work on macOS. Curiously, it doesn't really fail, but instead outputs this (for cargo-edit):

      NaN% 0B [10222 Others]
      NaN% 0B _je_tcache_boot
      NaN% 0B _je_tcache_cleanup
      NaN% 0B _je_tcache_create
      NaN% 0B _je_tcache_enabled_cleanup
      NaN% 0B _je_tcache_event_hard
      NaN% 0B _je_tcache_get_hard
      NaN% 0B _je_tcache_stats_merge
      NaN% 0B _je_tcaches_create
      NaN% 0B _je_tcaches_destroy
      NaN% 0B _je_tcaches_flush
      NaN% 0B _je_thread_allocated_cleanup
      NaN% 0B _je_thread_deallocated_cleanup
      NaN% 0B _je_tsd_cleanup
      NaN% 0B _je_tsd_init_check_recursion
      NaN% 0B _je_tsd_init_finish
      NaN% 0B _je_witness_fork_cleanup
      NaN% 0B _je_witnesses_cleanup
      NaN% 0B _main
      NaN% 0B _rust_begin_unwind
      NaN% 0B _rust_eh_personality
    100.0% 0B Total
    

    Looks like the object crate just reports 0 bytes all the time? Should it ever return 0?

    opened by killercup 11
  • Error: parsing failed cause 'section .symtab is missing'.

    Error: parsing failed cause 'section .symtab is missing'.

    I've been getting this error recently, and even rebuilding cargo-bloat doesn't fix it. I've also tried clearing target/release/, but the result is the same. Have you seen this before?

    Thank you kindly.

    opened by fosskers 9
  • cargo bloat --time can't execute cargo build

    cargo bloat --time can't execute cargo build

    Steps to reproduce

    1. clone solana repo.
    2. run cargo bloat --time

    Output

    image This repo can be builded with cargo build with no errors.

    Meanwhile bare cargo bloat works.

    opened by totikom 9
  • Offer prebuilt release binaries

    Offer prebuilt release binaries

    Thanks for this awesome tool! I'm building a github action to run cargo bloat on projects. Would you be willing to add support for distributing pre-built binaries via github releases, for environments where a cargo install would be too slow or expensive?

    This can be entirely automated with Github actions themselves.

    opened by orf 9
  • cargo bloat prints json-time on stderr

    cargo bloat prints json-time on stderr

    I installed cargo bloat on a Mac and the functionality is great and useful. However, after running cargo bloat --crates --time, I am seeing output like this every time I run any cargo command (build, clippy, etc.):

    json-time {"crate_name":"derive_builder_macro","time":1492788223,"build_script":false}
    json-time {"crate_name":"git2","time":6255647714,"build_script":false}
    json-time {"crate_name":"build_info_proc","time":4735568231,"build_script":false}
    json-time {"crate_name":"syntex_syntax","time":25882835499,"build_script":false}
    json-time {"crate_name":"tonic_build","time":2963543957,"build_script":false}
    json-time {"crate_name":"build_info_build","time":2070763756,"build_script":false}
    json-time {"crate_name":"derive_builder","time":536162450,"build_script":false}
    json-time {"crate_name":"rustfmt","time":9911235635,"build_script":false}
    

    This happens even after I uninstall cargo bloat, which is very weird, as I see that the output is indeed generated by this script: https://github.com/RazrFalcon/cargo-bloat/blob/master/src/main.rs#L423-L428. I verified that there is no binary named cargo-bloat inside ~/.cargo/bin.

    This is driving me a bit crazy, lol. Any cargo experts here can help me figure out why this is happening?

    opened by jvimal 8
  • Replace unmaintained dependency term_size with terminal_size

    Replace unmaintained dependency term_size with terminal_size

    term_size is officially unmaintained and the authors recommend switching to terminal_size [1].

    [1] https://github.com/clap-rs/term_size-rs/blob/5889fdc589d267182cc946faa24e0e3166a70000/README.md

    opened by LingMan 4
  • Incorrect target resolving

    Incorrect target resolving

    cargo +nightly bloat -Z build-std --target x86_64-apple-darwin
    Error: failed to find a dir with std libraries. Expected location: /Users/user/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib.
    
    opened by RazrFalcon 0
  • don't suggest -n if all data is shown

    don't suggest -n if all data is shown

    Just a minor nit: if all data is shown, cargo-bloat outputs something like 0.0% 0.0% 0B And 0 smaller methods. Use -n N to show more. which could probably be skipped altogether :)

    opened by matthiaskrgr 1
  • Discrepancy in reported `.text` size: `cargo bloat` vs GNU Binuils `size`

    Discrepancy in reported `.text` size: `cargo bloat` vs GNU Binuils `size`

    I noticed cargo bloat report a smaller .text size than GNU binutils size for the same binary (by only a couple KB, but happens to be 10% or so in this case).

    Steps to replicate issue documented here, the discrepancy is:

    | | cargo bloat | cargo size | | --- | --- | --- | | min_size_no_std | 14.7KB | 17.0KB | | min_size_std | 16.4KB | 17.8KB |

    Note cargo size's output is consistent with using the distro-installed size binary from GNU binutils (e.g. size ./target/x86_64-unknown-linux-musl/release/min_size_no_std).

    Not sure which tool's output is ground truth, but wanted to bring it to your attention! Thank you for your work on this tool.

    opened by tnballo 3
  • Analyze .rodata too

    Analyze .rodata too

    I have troubles finding where this insane amount of .rodata is coming from ...

    ...
    .text                 66898   131072
    .rodata               33136   197976
    ...
    

    Would be great, if cargo bloat also could support eg rodata :)

    help wanted 
    opened by shufps 6
Owner
Yevhenii Reizner
RIIR
Yevhenii Reizner
A quick and dirty Space Invaders type game in Bevy, with attached tutorial.

This article is in-development and will be released in full form soon. It'll appear on Medium (my publisher likes that), with this as a the accompanyi

Herbert 17 Oct 18, 2022
Helper functions and structs for working with 2D space in Bevy.

About Baffled by quaternions? Want to accelerate an object in 2D? Wish that there was a simple way to work with grids? Just want to know if two axis-a

Leafwing Studios 11 May 9, 2022
A simple space shooter game. Runs in the terminal using characters-based UI. Fully written in Rust, using the "ruscii" library.

Thrust - a terminal shooter game Originally created as a project for the "Missing Semester" course at JKU Linz (338.006). The game is entirely written

Mathias Wöß 3 Jan 16, 2023
Rust implementation of Another World (aka Out of this world) game engine

RustyWorld Rust implementation of Another World (aka Out of this world) game engine. I wanted a fun project to challenge myself while learning Rust, a

Francesco Degrassi 3 Jul 1, 2021
Provides a mechanism to lay out data into GPU buffers according to WGSL's memory layout rules

Provides a mechanism to lay out data into GPU buffers ensuring WGSL's memory layout requirements are met. Features supports all WGSL host-shareable ty

Teodor Tanasoaia 69 Dec 30, 2022
a rust library to find near-duplicate video files

Video Duplicate Finder vid_dup_finder finds near-duplicate video files on disk. It detects videos whose frames look similar, and where the videos are

null 12 Oct 28, 2022
A CLI tool to manage your godot-rust projects

ftw A CLI tool to manage your godot-rust project! Table of contents General Information Setup Usage Contact General Information This is a tool to help

Michael Angelo Calimlim 77 Dec 13, 2022
rpg-cli —your filesystem as a dungeon!

rpg-cli is a bare-bones JRPG-inspired terminal game written in Rust. It can work as an alternative to cd where you randomly encounter enemies as you change directories.

Facundo Olano 1.2k Jan 4, 2023
A puzzle game where you eat your own tail to win!

taileater taileater is a puzzle game available for free here: https://szunami.itch.io/taileater This project is built using Rust and Bevy. Assets were

null 25 Dec 20, 2022
Synchronize games from other platforms into your Steam library

BoilR Description This little tool will synchronize games from other platforms into your Steam library, using the Steam Shortcuts feature. The goal is

Philip Kristoffersen 823 Jan 9, 2023
The Big Cheese a webapp wherein you can share recipes with your friends.

The Big Cheese The Big Cheese a webapp wherein you can share recipes with your friends. Contributing Contributions are what make the open source commu

null 3 May 5, 2022
💤 Put your Minecraft server to rest when idle.

?? Put your Minecraft server to rest when idle.

Tim Visée 285 Jan 4, 2023
This is an online game in which you program your character and he fights with other players

Game for programmers The goal of this project is to create a simple game for programmers. The essence of the game Each player has his own character th

Danila 1 Dec 10, 2021
Easily update your minecraft mods with 1 file (guess I'm back to rust again)

Mod Updater This program updates all your mods to a newer/later version. To use: Create a file named config.toml Create a folder named mods; Add the f

sussyimpostor 2 Sep 18, 2022
State of the art "build your own engine" kit powered by gfx-hal

A rendering engine based on gfx-hal, which mimics the Vulkan API. Building This library requires standard build tools for the target platforms, except

Amethyst Foundation 801 Dec 28, 2022
This is starter for your own game-specific tools

Bevy Toolbar Usage: This is starter for your own game-specific tools, clone source and manually add it to [workspace] section in Cargo.toml. Now add i

null 15 Sep 11, 2022
NeosPeeps is tool that allows for listing your NeosVR friends quickly, without having to actually open the whole game

Neos Peeps NeosPeeps is tool that allows for listing your NeosVR friends quickly, without having to actually open the whole game. It also has a bunch

LJ 6 Sep 12, 2022
"putzen" is German and means cleaning. It helps keeping your disk clean of build and dependency artifacts safely.

Putzen "putzen" is German and means cleaning. It helps keeping your disk clean of build and dependency artifacts safely. About In short, putzen solves

Sven Assmann 2 Jul 4, 2022
A canvas on which you can draw anything with ease before drawing the pixels on your small hardware display.

embedded-canvas    canvas - a piece of cloth backed or framed as a surface for a painting NOTE: This crate is still in development and may have breaki

Lechev.space 13 Aug 31, 2022