1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Command-line surface. `cargo-treemap` is dispatched by cargo as `cargo treemap`,
//! which injects `treemap` as argv[1]; the wrapper enum consumes that token.
use clap::Parser;
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "cargo", bin_name = "cargo")]
#[command(styles = clap_cargo::style::CLAP_STYLING)]
pub enum CargoCli {
/// Interactive treemap of Rust binary size & dependency usage.
Treemap(TreemapArgs),
}
#[derive(clap::Args)]
#[command(version, about = "Interactive treemap of Rust binary size & dependency usage")]
pub struct TreemapArgs {
// cargo-inherited flag groups (do not hand-roll these).
#[command(flatten)]
pub manifest: clap_cargo::Manifest,
#[command(flatten)]
pub workspace: clap_cargo::Workspace,
#[command(flatten)]
pub features: clap_cargo::Features,
/// Analyze a pre-built binary/library directly instead of running a build. Repeatable.
/// Crate names are derived from the binary's own symbols (no rlib map, so attribution is
/// heuristic). Skips --api-usage.
#[arg(long)]
pub artifact: Vec<PathBuf>,
/// Build for the given target triple (e.g. x86_64-unknown-linux-gnu, wasm32-unknown-unknown).
#[arg(long)]
pub target: Option<String>,
/// Analyze the release profile.
#[arg(long)]
pub release: bool,
/// Analyze a named profile (overrides --release).
#[arg(long)]
pub profile: Option<String>,
/// Only analyze the given binary target(s).
#[arg(long)]
pub bin: Vec<String>,
/// Analyze the library target (cdylib/staticlib artifacts).
#[arg(long)]
pub lib: bool,
/// Output format.
#[arg(long, value_enum, default_value_t = Format::Html)]
pub format: Format,
/// Output path (HTML report / JSON). Defaults to ./cargo-treemap.html for HTML.
#[arg(long, short)]
pub output: Option<PathBuf>,
/// Open the generated HTML report in the default browser.
#[arg(long)]
pub open: bool,
/// Which metric the treemap is initially weighted by.
#[arg(long, value_enum, default_value_t = Metric::Text)]
pub metric: Metric,
/// Break the standard library into its component crates instead of one `std` bucket.
#[arg(long)]
pub split_std: bool,
/// Attribute symbols by DWARF debug info (address to source file to crate) instead of by
/// symbol name. More accurate, reclaims anonymous rodata from the `[runtime]` bucket, and
/// forces a debug build.
#[arg(long)]
pub dwarf: bool,
/// Measure per-crate compile time via `cargo build --timings`. Does a full from-scratch
/// build in a separate target dir, so it's slow every run.
#[arg(long)]
pub compile_time: bool,
/// Compare the current build against a baseline saved earlier with `--format json`, and
/// report the per-crate/per-symbol size delta.
#[arg(long, value_name = "BASE.json")]
pub compare: Option<PathBuf>,
/// Compare the current build against a git ref (branch, tag, or commit). Builds the ref in
/// a temporary worktree, so the working tree is untouched. Overrides --compare.
#[arg(long, value_name = "REF")]
pub compare_ref: Option<String>,
/// Attribute binary size to each of the package's Cargo features by building with each one
/// toggled on against a no-default-features baseline. One build per feature, so it's slow.
#[arg(long)]
pub attribute_features: bool,
/// Compute the API-usage "how dependent are you" metric for each direct dependency.
/// Generates rustdoc JSON per dependency, so it's slower.
#[arg(long)]
pub api_usage: bool,
/// With --api-usage, do an extra opt-level-0 (`v0`-mangled) build so cross-crate calls
/// aren't inlined away, giving a truer "used" count. Doubles build time.
#[arg(long, requires = "api_usage")]
pub accurate: bool,
}
#[derive(clap::ValueEnum, Clone, Copy, PartialEq, Eq)]
pub enum Format {
Html,
Json,
Table,
}
#[derive(clap::ValueEnum, Clone, Copy, PartialEq, Eq)]
pub enum Metric {
/// Bytes in executable-code sections (`.text`), the reference "parsed size".
Text,
/// Bytes in data/read-only-data sections.
Data,
/// Gzipped size of each symbol's bytes.
Gzip,
/// Number of symbols/monomorphizations aggregated.
Mono,
/// Source size per crate (the webpack "stat" analog).
Stat,
}
impl Metric {
/// The JSON field name the treemap reads for this metric.
pub fn field(self) -> &'static str {
match self {
Metric::Text => "text",
Metric::Data => "data",
Metric::Gzip => "gzip",
Metric::Mono => "count",
Metric::Stat => "stat",
}
}
}