Skip to content

Commit 4aee12c

Browse files
committed
Auto merge of #12625 - weihanglo:rfc3127, r=epage
feat: implement RFC 3127 `-Ztrim-paths`
2 parents b988daa + 63cef2c commit 4aee12c

File tree

10 files changed

+939
-4
lines changed

10 files changed

+939
-4
lines changed

src/cargo/core/compiler/mod.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ use crate::util::errors::{CargoResult, VerboseError};
9494
use crate::util::interning::InternedString;
9595
use crate::util::machine_message::{self, Message};
9696
use crate::util::toml::TomlDebugInfo;
97+
use crate::util::toml::TomlTrimPaths;
9798
use crate::util::{add_path_args, internal, iter_join_onto, profile};
9899
use cargo_util::{paths, ProcessBuilder, ProcessError};
99100
use rustfix::diagnostics::Applicability;
@@ -950,6 +951,7 @@ fn build_base_args(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder, unit: &Unit)
950951
incremental,
951952
strip,
952953
rustflags: profile_rustflags,
954+
trim_paths,
953955
..
954956
} = unit.profile.clone();
955957
let test = unit.mode.is_any_test();
@@ -1028,6 +1030,10 @@ fn build_base_args(cx: &Context<'_, '_>, cmd: &mut ProcessBuilder, unit: &Unit)
10281030
}
10291031
}
10301032

1033+
if let Some(trim_paths) = trim_paths {
1034+
trim_paths_args(cmd, cx, unit, &trim_paths)?;
1035+
}
1036+
10311037
cmd.args(unit.pkg.manifest().lint_rustflags());
10321038
cmd.args(&profile_rustflags);
10331039
if let Some(args) = cx.bcx.extra_args_for(unit) {
@@ -1162,6 +1168,74 @@ fn features_args(unit: &Unit) -> Vec<OsString> {
11621168
args
11631169
}
11641170

1171+
/// Generates the `--remap-path-scope` and `--remap-path-prefix` for [RFC 3127].
1172+
/// See also unstable feature [`-Ztrim-paths`].
1173+
///
1174+
/// [RFC 3127]: https://rust-lang.github.io/rfcs/3127-trim-paths.html
1175+
/// [`-Ztrim-paths`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-trim-paths-option
1176+
fn trim_paths_args(
1177+
cmd: &mut ProcessBuilder,
1178+
cx: &Context<'_, '_>,
1179+
unit: &Unit,
1180+
trim_paths: &TomlTrimPaths,
1181+
) -> CargoResult<()> {
1182+
if trim_paths.is_none() {
1183+
return Ok(());
1184+
}
1185+
1186+
// feature gate was checked during mainfest/config parsing.
1187+
cmd.arg("-Zunstable-options");
1188+
cmd.arg(format!("-Zremap-path-scope={trim_paths}"));
1189+
1190+
let sysroot_remap = {
1191+
let sysroot = &cx.bcx.target_data.info(unit.kind).sysroot;
1192+
let mut remap = OsString::from("--remap-path-prefix=");
1193+
remap.push(sysroot);
1194+
remap.push("/lib/rustlib/src/rust"); // See also `detect_sysroot_src_path()`.
1195+
remap.push("=");
1196+
remap.push("/rustc/");
1197+
// This remap logic aligns with rustc:
1198+
// <https://github.com/rust-lang/rust/blob/c2ef3516/src/bootstrap/src/lib.rs#L1113-L1116>
1199+
if let Some(commit_hash) = cx.bcx.rustc().commit_hash.as_ref() {
1200+
remap.push(commit_hash);
1201+
} else {
1202+
remap.push(cx.bcx.rustc().version.to_string());
1203+
}
1204+
remap
1205+
};
1206+
cmd.arg(sysroot_remap);
1207+
1208+
let package_remap = {
1209+
let pkg_root = unit.pkg.root();
1210+
let ws_root = cx.bcx.ws.root();
1211+
let is_local = unit.pkg.package_id().source_id().is_path();
1212+
let mut remap = OsString::from("--remap-path-prefix=");
1213+
// Remapped to path relative to workspace root:
1214+
//
1215+
// * path dependencies under workspace root directory
1216+
//
1217+
// Remapped to `<pkg>-<version>`
1218+
//
1219+
// * registry dependencies
1220+
// * git dependencies
1221+
// * path dependencies outside workspace root directory
1222+
if is_local && pkg_root.strip_prefix(ws_root).is_ok() {
1223+
remap.push(ws_root);
1224+
remap.push("="); // empty to remap to relative paths.
1225+
} else {
1226+
remap.push(pkg_root);
1227+
remap.push("=");
1228+
remap.push(unit.pkg.name());
1229+
remap.push("-");
1230+
remap.push(unit.pkg.version().to_string());
1231+
}
1232+
remap
1233+
};
1234+
cmd.arg(package_remap);
1235+
1236+
Ok(())
1237+
}
1238+
11651239
/// Generates the `--check-cfg` arguments for the `unit`.
11661240
/// See unstable feature [`check-cfg`].
11671241
///

src/cargo/core/features.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ features! {
496496

497497
// Support for 2024 edition.
498498
(unstable, edition2024, "", "reference/unstable.html#edition-2024"),
499+
500+
// Allow setting trim-paths in a profile to control the sanitisation of file paths in build outputs.
501+
(unstable, trim_paths, "", "reference/unstable.html#profile-trim-paths-option"),
499502
}
500503

501504
pub struct Feature {
@@ -755,6 +758,7 @@ unstable_cli_options!(
755758
separate_nightlies: bool = (HIDDEN),
756759
skip_rustdoc_fingerprint: bool = (HIDDEN),
757760
target_applies_to_host: bool = ("Enable the `target-applies-to-host` key in the .cargo/config.toml file"),
761+
trim_paths: bool = ("Enable the `trim-paths` option in profiles"),
758762
unstable_options: bool = ("Allow the usage of unstable options"),
759763
);
760764

@@ -1089,6 +1093,7 @@ impl CliUnstable {
10891093
"no-index-update" => self.no_index_update = parse_empty(k, v)?,
10901094
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
10911095
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
1096+
"trim-paths" => self.trim_paths = parse_empty(k, v)?,
10921097
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
10931098
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
10941099
"rustdoc-scrape-examples" => self.rustdoc_scrape_examples = parse_empty(k, v)?,

src/cargo/core/profiles.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424
use crate::core::compiler::{CompileKind, CompileTarget, Unit};
2525
use crate::core::dependency::Artifact;
2626
use crate::core::resolver::features::FeaturesFor;
27+
use crate::core::Feature;
2728
use crate::core::{PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace};
2829
use crate::util::interning::InternedString;
30+
use crate::util::toml::TomlTrimPaths;
31+
use crate::util::toml::TomlTrimPathsValue;
2932
use crate::util::toml::{
3033
ProfilePackageSpec, StringOrBool, TomlDebugInfo, TomlProfile, TomlProfiles,
3134
};
@@ -80,7 +83,9 @@ impl Profiles {
8083
rustc_host,
8184
};
8285

83-
Self::add_root_profiles(&mut profile_makers, &profiles);
86+
let trim_paths_enabled = ws.unstable_features().is_enabled(Feature::trim_paths())
87+
|| config.cli_unstable().trim_paths;
88+
Self::add_root_profiles(&mut profile_makers, &profiles, trim_paths_enabled);
8489

8590
// Merge with predefined profiles.
8691
use std::collections::btree_map::Entry;
@@ -123,6 +128,7 @@ impl Profiles {
123128
fn add_root_profiles(
124129
profile_makers: &mut Profiles,
125130
profiles: &BTreeMap<InternedString, TomlProfile>,
131+
trim_paths_enabled: bool,
126132
) {
127133
profile_makers.by_name.insert(
128134
InternedString::new("dev"),
@@ -131,7 +137,10 @@ impl Profiles {
131137

132138
profile_makers.by_name.insert(
133139
InternedString::new("release"),
134-
ProfileMaker::new(Profile::default_release(), profiles.get("release").cloned()),
140+
ProfileMaker::new(
141+
Profile::default_release(trim_paths_enabled),
142+
profiles.get("release").cloned(),
143+
),
135144
);
136145
}
137146

@@ -556,6 +565,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
556565
if let Some(flags) = &toml.rustflags {
557566
profile.rustflags = flags.iter().map(InternedString::from).collect();
558567
}
568+
if let Some(trim_paths) = &toml.trim_paths {
569+
profile.trim_paths = Some(trim_paths.clone());
570+
}
559571
profile.strip = match toml.strip {
560572
Some(StringOrBool::Bool(true)) => Strip::Named(InternedString::new("symbols")),
561573
None | Some(StringOrBool::Bool(false)) => Strip::None,
@@ -599,6 +611,9 @@ pub struct Profile {
599611
#[serde(skip_serializing_if = "Vec::is_empty")] // remove when `rustflags` is stablized
600612
// Note that `rustflags` is used for the cargo-feature `profile_rustflags`
601613
pub rustflags: Vec<InternedString>,
614+
// remove when `-Ztrim-paths` is stablized
615+
#[serde(skip_serializing_if = "Option::is_none")]
616+
pub trim_paths: Option<TomlTrimPaths>,
602617
}
603618

604619
impl Default for Profile {
@@ -619,6 +634,7 @@ impl Default for Profile {
619634
panic: PanicStrategy::Unwind,
620635
strip: Strip::None,
621636
rustflags: vec![],
637+
trim_paths: None,
622638
}
623639
}
624640
}
@@ -628,7 +644,7 @@ compact_debug! {
628644
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
629645
let (default, default_name) = match self.name.as_str() {
630646
"dev" => (Profile::default_dev(), "default_dev()"),
631-
"release" => (Profile::default_release(), "default_release()"),
647+
"release" => (Profile::default_release(false), "default_release()"),
632648
_ => (Profile::default(), "default()"),
633649
};
634650
[debug_the_fields(
@@ -647,6 +663,7 @@ compact_debug! {
647663
panic
648664
strip
649665
rustflags
666+
trim_paths
650667
)]
651668
}
652669
}
@@ -688,11 +705,13 @@ impl Profile {
688705
}
689706

690707
/// Returns a built-in `release` profile.
691-
fn default_release() -> Profile {
708+
fn default_release(trim_paths_enabled: bool) -> Profile {
709+
let trim_paths = trim_paths_enabled.then(|| TomlTrimPathsValue::Object.into());
692710
Profile {
693711
name: InternedString::new("release"),
694712
root: ProfileRoot::Release,
695713
opt_level: InternedString::new("3"),
714+
trim_paths,
696715
..Profile::default()
697716
}
698717
}
@@ -713,6 +732,7 @@ impl Profile {
713732
self.rpath,
714733
(self.incremental, self.panic, self.strip),
715734
&self.rustflags,
735+
&self.trim_paths,
716736
)
717737
}
718738
}

src/cargo/util/rustc.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ pub struct Rustc {
2828
pub version: semver::Version,
2929
/// The host triple (arch-platform-OS), this comes from verbose_version.
3030
pub host: InternedString,
31+
/// The rustc full commit hash, this comes from `verbose_version`.
32+
pub commit_hash: Option<String>,
3133
cache: Mutex<Cache>,
3234
}
3335

@@ -80,6 +82,17 @@ impl Rustc {
8082
verbose_version
8183
)
8284
})?;
85+
let commit_hash = extract("commit-hash: ").ok().map(|hash| {
86+
debug_assert!(
87+
hash.chars().all(|ch| ch.is_ascii_hexdigit()),
88+
"commit hash must be a hex string"
89+
);
90+
debug_assert!(
91+
hash.len() == 40 || hash.len() == 64,
92+
"hex string must be generated from sha1 or sha256"
93+
);
94+
hash.to_string()
95+
});
8396

8497
Ok(Rustc {
8598
path,
@@ -88,6 +101,7 @@ impl Rustc {
88101
verbose_version,
89102
version,
90103
host,
104+
commit_hash,
91105
cache: Mutex::new(cache),
92106
})
93107
}

0 commit comments

Comments
 (0)