Skip to content

Commit f0a26f2

Browse files
committed
Avoid multiple copies of proc macros ending up in the sysroot
1 parent 345e08b commit f0a26f2

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ impl Step for RustcLink {
15581558
run.never()
15591559
}
15601560

1561-
/// Same as `std_link`, only for librustc
1561+
/// Same as `StdLink`, only for librustc
15621562
fn run(self, builder: &Builder<'_>) {
15631563
let build_compiler = self.build_compiler;
15641564
let sysroot_compiler = self.sysroot_compiler;
@@ -2418,13 +2418,28 @@ pub fn add_to_sysroot(
24182418
t!(fs::create_dir_all(sysroot_dst));
24192419
t!(fs::create_dir_all(sysroot_host_dst));
24202420
t!(fs::create_dir_all(self_contained_dst));
2421+
2422+
let mut rustc_crates = HashSet::new();
24212423
for (path, dependency_type) in builder.read_stamp_file(stamp) {
2424+
let filename = path.file_name().unwrap().to_str().unwrap();
24222425
let dst = match dependency_type {
24232426
DependencyType::Host => sysroot_host_dst,
24242427
DependencyType::Target => sysroot_dst,
24252428
DependencyType::TargetSelfContained => self_contained_dst,
24262429
};
2427-
builder.copy_link(&path, &dst.join(path.file_name().unwrap()), FileType::Regular);
2430+
builder.copy_link(&path, &dst.join(filename), FileType::Regular);
2431+
2432+
// Check that none of the rustc_* crates have multiple versions. Otherwise using them from
2433+
// the sysroot would cause ambiguity errors. We do allow rustc_hash however as it is an
2434+
// external dependency that we build multiple copies of. It is re-exported by
2435+
// rustc_data_structures, so not being able to use extern crate rustc_hash; is not a big
2436+
// issue.
2437+
if !filename.contains("rustc_") || filename.contains("rustc_hash") {
2438+
continue;
2439+
}
2440+
if !rustc_crates.insert(filename.split_once('-').unwrap().0.to_owned()) {
2441+
panic!("duplicate rustc crate at {}", path.display());
2442+
}
24282443
}
24292444
}
24302445

@@ -2511,7 +2526,13 @@ pub fn run_cargo(
25112526
if filename.starts_with(&host_root_dir) {
25122527
// Unless it's a proc macro used in the compiler
25132528
if crate_types.iter().any(|t| t == "proc-macro") {
2514-
deps.push((filename.to_path_buf(), DependencyType::Host));
2529+
// Cargo will compile proc-macros that are part of the rustc workspace twice.
2530+
// Once as libmacro-hash.so as build dependency and once as libmacro.so as
2531+
// output artifact. Only keep the former to avoid ambiguity when trying to use
2532+
// the proc macro from the sysroot.
2533+
if filename.file_name().unwrap().to_str().unwrap().contains("-") {
2534+
deps.push((filename.to_path_buf(), DependencyType::Host));
2535+
}
25152536
}
25162537
continue;
25172538
}

0 commit comments

Comments
 (0)