|
7 | 7 | //! goes along from the output of the previous stage. |
8 | 8 |
|
9 | 9 | use std::borrow::Cow; |
10 | | -use std::collections::HashSet; |
| 10 | +use std::collections::{HashMap, HashSet}; |
11 | 11 | use std::ffi::OsStr; |
12 | 12 | use std::io::BufReader; |
13 | 13 | use std::io::prelude::*; |
@@ -1558,7 +1558,7 @@ impl Step for RustcLink { |
1558 | 1558 | run.never() |
1559 | 1559 | } |
1560 | 1560 |
|
1561 | | - /// Same as `std_link`, only for librustc |
| 1561 | + /// Same as `StdLink`, only for librustc |
1562 | 1562 | fn run(self, builder: &Builder<'_>) { |
1563 | 1563 | let build_compiler = self.build_compiler; |
1564 | 1564 | let sysroot_compiler = self.sysroot_compiler; |
@@ -2418,13 +2418,52 @@ pub fn add_to_sysroot( |
2418 | 2418 | t!(fs::create_dir_all(sysroot_dst)); |
2419 | 2419 | t!(fs::create_dir_all(sysroot_host_dst)); |
2420 | 2420 | t!(fs::create_dir_all(self_contained_dst)); |
| 2421 | + |
| 2422 | + let mut crates = HashMap::new(); |
2421 | 2423 | for (path, dependency_type) in builder.read_stamp_file(stamp) { |
| 2424 | + let filename = path.file_name().unwrap().to_str().unwrap(); |
2422 | 2425 | let dst = match dependency_type { |
2423 | | - DependencyType::Host => sysroot_host_dst, |
2424 | | - DependencyType::Target => sysroot_dst, |
| 2426 | + DependencyType::Host => { |
| 2427 | + if sysroot_dst == sysroot_host_dst { |
| 2428 | + // Only insert the part before the . to deduplicate different files for the same crate. |
| 2429 | + // For example foo-1234.dll and foo-1234.dll.lib. |
| 2430 | + crates.insert(filename.split_once('.').unwrap().0.to_owned(), path.clone()); |
| 2431 | + } |
| 2432 | + |
| 2433 | + sysroot_host_dst |
| 2434 | + } |
| 2435 | + DependencyType::Target => { |
| 2436 | + // Only insert the part before the . to deduplicate different files for the same crate. |
| 2437 | + // For example foo-1234.dll and foo-1234.dll.lib. |
| 2438 | + crates.insert(filename.split_once('.').unwrap().0.to_owned(), path.clone()); |
| 2439 | + |
| 2440 | + sysroot_dst |
| 2441 | + } |
2425 | 2442 | DependencyType::TargetSelfContained => self_contained_dst, |
2426 | 2443 | }; |
2427 | | - builder.copy_link(&path, &dst.join(path.file_name().unwrap()), FileType::Regular); |
| 2444 | + builder.copy_link(&path, &dst.join(filename), FileType::Regular); |
| 2445 | + } |
| 2446 | + |
| 2447 | + // Check that none of the rustc_* crates have multiple versions. Otherwise using them from |
| 2448 | + // the sysroot would cause ambiguity errors. We do allow rustc_hash however as it is an |
| 2449 | + // external dependency that we build multiple copies of. It is re-exported by |
| 2450 | + // rustc_data_structures, so not being able to use extern crate rustc_hash; is not a big |
| 2451 | + // issue. |
| 2452 | + let mut seen_crates = HashMap::new(); |
| 2453 | + for (filestem, path) in crates { |
| 2454 | + if !filestem.contains("rustc_") || filestem.contains("rustc_hash") { |
| 2455 | + continue; |
| 2456 | + } |
| 2457 | + if let Some(other_path) = |
| 2458 | + seen_crates.insert(filestem.split_once('-').unwrap().0.to_owned(), path.clone()) |
| 2459 | + { |
| 2460 | + panic!( |
| 2461 | + "duplicate rustc crate {}\n- first copy at {}\n- second copy at {}", |
| 2462 | + filestem.split_once('-').unwrap().0.to_owned(), |
| 2463 | + other_path.display(), |
| 2464 | + path.display(), |
| 2465 | + ); |
| 2466 | + } |
2428 | 2467 | } |
2429 | 2468 | } |
2430 | 2469 |
|
@@ -2511,7 +2550,13 @@ pub fn run_cargo( |
2511 | 2550 | if filename.starts_with(&host_root_dir) { |
2512 | 2551 | // Unless it's a proc macro used in the compiler |
2513 | 2552 | if crate_types.iter().any(|t| t == "proc-macro") { |
2514 | | - deps.push((filename.to_path_buf(), DependencyType::Host)); |
| 2553 | + // Cargo will compile proc-macros that are part of the rustc workspace twice. |
| 2554 | + // Once as libmacro-hash.so as build dependency and once as libmacro.so as |
| 2555 | + // output artifact. Only keep the former to avoid ambiguity when trying to use |
| 2556 | + // the proc macro from the sysroot. |
| 2557 | + if filename.file_name().unwrap().to_str().unwrap().contains("-") { |
| 2558 | + deps.push((filename.to_path_buf(), DependencyType::Host)); |
| 2559 | + } |
2515 | 2560 | } |
2516 | 2561 | continue; |
2517 | 2562 | } |
|
0 commit comments