feat(unstable): add -Zbuild-analysis unstable feature (#15845)

### What does this PR try to resolve?

Part of #15844

Set up `-Zbuild-analysis` flag and `build.analysis` configuration table
to lay the ground work.
when `build.analysis.enabled = true`, enables HTML timing output to
pretend we are persisting timing data for now. This will change when the
storage part is implemented.

### How to test and review this PR?
This commit is contained in:
Ed Page 2025-08-16 14:18:21 +00:00 committed by GitHub
commit e04e0b65c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 130 additions and 42 deletions

View File

@ -115,6 +115,18 @@ impl BuildConfig {
(None, _) => false,
};
let timing_outputs = match (cfg.analysis.as_ref(), gctx.cli_unstable().build_analysis) {
// Enable HTML output to pretend we are persisting timing data for now.
(Some(analysis), true) if analysis.enabled => vec![TimingOutput::Html],
(Some(_), false) => {
gctx.shell().warn(
"ignoring 'build.analysis' config, pass `-Zbuild-analysis` to enable it",
)?;
Vec::new()
}
_ => Vec::new(),
};
Ok(BuildConfig {
requested_kinds,
jobs,
@ -130,7 +142,7 @@ impl BuildConfig {
rustfix_diagnostic_server: Rc::new(RefCell::new(None)),
export_dir: None,
future_incompat_report: false,
timing_outputs: Vec::new(),
timing_outputs,
sbom,
compile_time_deps_only: false,
})

View File

@ -844,6 +844,7 @@ unstable_cli_options!(
avoid_dev_deps: bool = ("Avoid installing dev-dependencies if possible"),
binary_dep_depinfo: bool = ("Track changes to dependency artifacts"),
bindeps: bool = ("Allow Cargo packages to depend on bin, cdylib, and staticlib crates, and use the artifacts built by those crates"),
build_analysis: bool = ("Record and persist build metrics across runs, with commands to query past builds."),
#[serde(deserialize_with = "deserialize_comma_separated_list")]
build_std: Option<Vec<String>> = ("Enable Cargo to compile the standard library itself as part of a crate graph compilation"),
#[serde(deserialize_with = "deserialize_comma_separated_list")]
@ -1363,6 +1364,7 @@ impl CliUnstable {
"avoid-dev-deps" => self.avoid_dev_deps = parse_empty(k, v)?,
"binary-dep-depinfo" => self.binary_dep_depinfo = parse_empty(k, v)?,
"bindeps" => self.bindeps = parse_empty(k, v)?,
"build-analysis" => self.build_analysis = parse_empty(k, v)?,
"build-std" => self.build_std = Some(parse_list(v)),
"build-std-features" => self.build_std_features = Some(parse_list(v)),
"cargo-lints" => self.cargo_lints = parse_empty(k, v)?,

View File

@ -2768,6 +2768,15 @@ pub struct CargoBuildConfig {
pub warnings: Option<WarningHandling>,
/// Unstable feature `-Zsbom`.
pub sbom: Option<bool>,
/// Unstable feature `-Zbuild-analysis`.
pub analysis: Option<CargoBuildAnalysis>,
}
/// Metrics collection for build analysis.
#[derive(Debug, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct CargoBuildAnalysis {
pub enabled: bool,
}
/// Whether warnings should warn, be allowed, or cause an error.

View File

@ -113,6 +113,7 @@ Each new feature described below should explain how to use it.
* [Build-plan](#build-plan) --- Emits JSON information on which commands will be run.
* [unit-graph](#unit-graph) --- Emits JSON for Cargo's internal graph structure.
* [`cargo rustc --print`](#rustc---print) --- Calls rustc with `--print` to display information from rustc.
* [Build analysis](#build-analysis) --- Record and persist detailed build metrics across runs, with new commands to query past builds.
* Configuration
* [config-include](#config-include) --- Adds the ability for config files to include other files.
* [`cargo config`](#cargo-config) --- Adds a new subcommand for viewing config files.
@ -1922,6 +1923,22 @@ HTML/JSON output.
cargo +nightly -Zsection-timings build --timings
```
## Build analysis
* Original Issue: [rust-lang/rust-project-goals#332](https://github.com/rust-lang/rust-project-goals/pull/332)
* Tracking Issue: [#15844](https://github.com/rust-lang/cargo/issues/15844)
The `-Zbuild-analysis` feature records and persists detailed build metrics
(timings, rebuild reasons, etc.) across runs, with new commands to query past builds.
```toml
# Example config.toml file.
# Enable the build metric collection
[build.analysis]
enabled = true
```
# Stabilized and removed features
## Compile progress

View File

@ -0,0 +1,45 @@
//! Tests for `-Zbuild-analysis`.
use crate::prelude::*;
use cargo_test_support::basic_manifest;
use cargo_test_support::project;
use cargo_test_support::str;
#[cargo_test]
fn gated() {
let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
.file("src/lib.rs", "")
.build();
p.cargo("check")
.env("CARGO_BUILD_ANALYSIS_ENABLED", "true")
.masquerade_as_nightly_cargo(&["build-analysis"])
.with_stderr_data(str![[r#"
[WARNING] ignoring 'build.analysis' config, pass `-Zbuild-analysis` to enable it
[CHECKING] foo v0.0.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}
#[cargo_test]
fn simple() {
let p = project()
.file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
.file("src/lib.rs", "")
.build();
p.cargo("check -Zbuild-analysis")
.env("CARGO_BUILD_ANALYSIS_ENABLED", "true")
.masquerade_as_nightly_cargo(&["build-analysis"])
.with_stderr_data(str![[r#"
[CHECKING] foo v0.0.0 ([ROOT]/foo)
Timing report saved to [ROOT]/foo/target/cargo-timings/cargo-timing-[..].html
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
"#]])
.run();
}

View File

@ -1,4 +1,4 @@
<svg width="1255px" height="866px" xmlns="http://www.w3.org/2000/svg">
<svg width="1255px" height="884px" xmlns="http://www.w3.org/2000/svg">
<style>
.fg { fill: #AAAAAA }
.bg { background: #000000 }
@ -30,85 +30,87 @@
</tspan>
<tspan x="10px" y="136px"><tspan> -Z bindeps Allow Cargo packages to depend on bin, cdylib, and staticlib crates, and use the artifacts built by those crates</tspan>
</tspan>
<tspan x="10px" y="154px"><tspan> -Z build-std Enable Cargo to compile the standard library itself as part of a crate graph compilation</tspan>
<tspan x="10px" y="154px"><tspan> -Z build-analysis Record and persist build metrics across runs, with commands to query past builds.</tspan>
</tspan>
<tspan x="10px" y="172px"><tspan> -Z build-std-features Configure features enabled for the standard library itself when building the standard library</tspan>
<tspan x="10px" y="172px"><tspan> -Z build-std Enable Cargo to compile the standard library itself as part of a crate graph compilation</tspan>
</tspan>
<tspan x="10px" y="190px"><tspan> -Z cargo-lints Enable the `[lints.cargo]` table</tspan>
<tspan x="10px" y="190px"><tspan> -Z build-std-features Configure features enabled for the standard library itself when building the standard library</tspan>
</tspan>
<tspan x="10px" y="208px"><tspan> -Z checksum-freshness Use a checksum to determine if output is fresh rather than filesystem mtime</tspan>
<tspan x="10px" y="208px"><tspan> -Z cargo-lints Enable the `[lints.cargo]` table</tspan>
</tspan>
<tspan x="10px" y="226px"><tspan> -Z codegen-backend Enable the `codegen-backend` option in profiles in .cargo/config.toml file</tspan>
<tspan x="10px" y="226px"><tspan> -Z checksum-freshness Use a checksum to determine if output is fresh rather than filesystem mtime</tspan>
</tspan>
<tspan x="10px" y="244px"><tspan> -Z config-include Enable the `include` key in config files</tspan>
<tspan x="10px" y="244px"><tspan> -Z codegen-backend Enable the `codegen-backend` option in profiles in .cargo/config.toml file</tspan>
</tspan>
<tspan x="10px" y="262px"><tspan> -Z direct-minimal-versions Resolve minimal dependency versions instead of maximum (direct dependencies only)</tspan>
<tspan x="10px" y="262px"><tspan> -Z config-include Enable the `include` key in config files</tspan>
</tspan>
<tspan x="10px" y="280px"><tspan> -Z dual-proc-macros Build proc-macros for both the host and the target</tspan>
<tspan x="10px" y="280px"><tspan> -Z direct-minimal-versions Resolve minimal dependency versions instead of maximum (direct dependencies only)</tspan>
</tspan>
<tspan x="10px" y="298px"><tspan> -Z feature-unification Enable new feature unification modes in workspaces</tspan>
<tspan x="10px" y="298px"><tspan> -Z dual-proc-macros Build proc-macros for both the host and the target</tspan>
</tspan>
<tspan x="10px" y="316px"><tspan> -Z fix-edition Permanently unstable edition migration helper</tspan>
<tspan x="10px" y="316px"><tspan> -Z feature-unification Enable new feature unification modes in workspaces</tspan>
</tspan>
<tspan x="10px" y="334px"><tspan> -Z gc Track cache usage and "garbage collect" unused files</tspan>
<tspan x="10px" y="334px"><tspan> -Z fix-edition Permanently unstable edition migration helper</tspan>
</tspan>
<tspan x="10px" y="352px"><tspan> -Z git Enable support for shallow git fetch operations</tspan>
<tspan x="10px" y="352px"><tspan> -Z gc Track cache usage and "garbage collect" unused files</tspan>
</tspan>
<tspan x="10px" y="370px"><tspan> -Z gitoxide Use gitoxide for the given git interactions, or all of them if no argument is given</tspan>
<tspan x="10px" y="370px"><tspan> -Z git Enable support for shallow git fetch operations</tspan>
</tspan>
<tspan x="10px" y="388px"><tspan> -Z host-config Enable the `[host]` section in the .cargo/config.toml file</tspan>
<tspan x="10px" y="388px"><tspan> -Z gitoxide Use gitoxide for the given git interactions, or all of them if no argument is given</tspan>
</tspan>
<tspan x="10px" y="406px"><tspan> -Z minimal-versions Resolve minimal dependency versions instead of maximum</tspan>
<tspan x="10px" y="406px"><tspan> -Z host-config Enable the `[host]` section in the .cargo/config.toml file</tspan>
</tspan>
<tspan x="10px" y="424px"><tspan> -Z msrv-policy Enable rust-version aware policy within cargo</tspan>
<tspan x="10px" y="424px"><tspan> -Z minimal-versions Resolve minimal dependency versions instead of maximum</tspan>
</tspan>
<tspan x="10px" y="442px"><tspan> -Z mtime-on-use Configure Cargo to update the mtime of used files</tspan>
<tspan x="10px" y="442px"><tspan> -Z msrv-policy Enable rust-version aware policy within cargo</tspan>
</tspan>
<tspan x="10px" y="460px"><tspan> -Z no-embed-metadata Avoid embedding metadata in library artifacts</tspan>
<tspan x="10px" y="460px"><tspan> -Z mtime-on-use Configure Cargo to update the mtime of used files</tspan>
</tspan>
<tspan x="10px" y="478px"><tspan> -Z no-index-update Do not update the registry index even if the cache is outdated</tspan>
<tspan x="10px" y="478px"><tspan> -Z no-embed-metadata Avoid embedding metadata in library artifacts</tspan>
</tspan>
<tspan x="10px" y="496px"><tspan> -Z panic-abort-tests Enable support to run tests with -Cpanic=abort</tspan>
<tspan x="10px" y="496px"><tspan> -Z no-index-update Do not update the registry index even if the cache is outdated</tspan>
</tspan>
<tspan x="10px" y="514px"><tspan> -Z profile-hint-mostly-unused Enable the `hint-mostly-unused` setting in profiles to mark a crate as mostly unused.</tspan>
<tspan x="10px" y="514px"><tspan> -Z panic-abort-tests Enable support to run tests with -Cpanic=abort</tspan>
</tspan>
<tspan x="10px" y="532px"><tspan> -Z profile-rustflags Enable the `rustflags` option in profiles in .cargo/config.toml file</tspan>
<tspan x="10px" y="532px"><tspan> -Z profile-hint-mostly-unused Enable the `hint-mostly-unused` setting in profiles to mark a crate as mostly unused.</tspan>
</tspan>
<tspan x="10px" y="550px"><tspan> -Z public-dependency Respect a dependency's `public` field in Cargo.toml to control public/private dependencies</tspan>
<tspan x="10px" y="550px"><tspan> -Z profile-rustflags Enable the `rustflags` option in profiles in .cargo/config.toml file</tspan>
</tspan>
<tspan x="10px" y="568px"><tspan> -Z publish-timeout Enable the `publish.timeout` key in .cargo/config.toml file</tspan>
<tspan x="10px" y="568px"><tspan> -Z public-dependency Respect a dependency's `public` field in Cargo.toml to control public/private dependencies</tspan>
</tspan>
<tspan x="10px" y="586px"><tspan> -Z root-dir Set the root directory relative to which paths are printed (defaults to workspace root)</tspan>
<tspan x="10px" y="586px"><tspan> -Z publish-timeout Enable the `publish.timeout` key in .cargo/config.toml file</tspan>
</tspan>
<tspan x="10px" y="604px"><tspan> -Z rustdoc-depinfo Use dep-info files in rustdoc rebuild detection</tspan>
<tspan x="10px" y="604px"><tspan> -Z root-dir Set the root directory relative to which paths are printed (defaults to workspace root)</tspan>
</tspan>
<tspan x="10px" y="622px"><tspan> -Z rustdoc-map Allow passing external documentation mappings to rustdoc</tspan>
<tspan x="10px" y="622px"><tspan> -Z rustdoc-depinfo Use dep-info files in rustdoc rebuild detection</tspan>
</tspan>
<tspan x="10px" y="640px"><tspan> -Z rustdoc-scrape-examples Allows Rustdoc to scrape code examples from reverse-dependencies</tspan>
<tspan x="10px" y="640px"><tspan> -Z rustdoc-map Allow passing external documentation mappings to rustdoc</tspan>
</tspan>
<tspan x="10px" y="658px"><tspan> -Z sbom Enable the `sbom` option in build config in .cargo/config.toml file</tspan>
<tspan x="10px" y="658px"><tspan> -Z rustdoc-scrape-examples Allows Rustdoc to scrape code examples from reverse-dependencies</tspan>
</tspan>
<tspan x="10px" y="676px"><tspan> -Z script Enable support for single-file, `.rs` packages</tspan>
<tspan x="10px" y="676px"><tspan> -Z sbom Enable the `sbom` option in build config in .cargo/config.toml file</tspan>
</tspan>
<tspan x="10px" y="694px"><tspan> -Z section-timings Enable support for extended compilation sections in --timings output</tspan>
<tspan x="10px" y="694px"><tspan> -Z script Enable support for single-file, `.rs` packages</tspan>
</tspan>
<tspan x="10px" y="712px"><tspan> -Z target-applies-to-host Enable the `target-applies-to-host` key in the .cargo/config.toml file</tspan>
<tspan x="10px" y="712px"><tspan> -Z section-timings Enable support for extended compilation sections in --timings output</tspan>
</tspan>
<tspan x="10px" y="730px"><tspan> -Z trim-paths Enable the `trim-paths` option in profiles</tspan>
<tspan x="10px" y="730px"><tspan> -Z target-applies-to-host Enable the `target-applies-to-host` key in the .cargo/config.toml file</tspan>
</tspan>
<tspan x="10px" y="748px"><tspan> -Z unstable-options Allow the usage of unstable options</tspan>
<tspan x="10px" y="748px"><tspan> -Z trim-paths Enable the `trim-paths` option in profiles</tspan>
</tspan>
<tspan x="10px" y="766px"><tspan> -Z warnings Allow use of the build.warnings config key</tspan>
<tspan x="10px" y="766px"><tspan> -Z unstable-options Allow the usage of unstable options</tspan>
</tspan>
<tspan x="10px" y="784px">
<tspan x="10px" y="784px"><tspan> -Z warnings Allow use of the build.warnings config key</tspan>
</tspan>
<tspan x="10px" y="802px"><tspan>Run with `cargo -Z [FLAG] [COMMAND]`</tspan>
<tspan x="10px" y="802px">
</tspan>
<tspan x="10px" y="820px">
<tspan x="10px" y="820px"><tspan>Run with `cargo -Z [FLAG] [COMMAND]`</tspan>
</tspan>
<tspan x="10px" y="838px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
<tspan x="10px" y="838px">
</tspan>
<tspan x="10px" y="856px">
<tspan x="10px" y="856px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
</tspan>
<tspan x="10px" y="874px">
</tspan>
</text>

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -11,6 +11,7 @@ mod bad_manifest_path;
mod bench;
mod binary_name;
mod build;
mod build_analysis;
mod build_dir;
mod build_plan;
mod build_script;