From 8656e1b3709391a54257631d688cfff0a0b5e0a1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:49:58 +0000 Subject: [PATCH 1/5] Simplify find_commandline_library --- compiler/rustc_metadata/src/locator.rs | 44 ++++++++++---------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index b9ebf17af248f..688120390f86d 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -728,37 +728,25 @@ impl<'a> CrateLocator<'a> { let Some(file) = loc_orig.file_name().and_then(|s| s.to_str()) else { return Err(CrateError::ExternLocationNotFile(self.crate_name, loc_orig.clone())); }; - // FnMut cannot return reference to captured value, so references - // must be taken outside the closure. - let rlibs = &mut rlibs; - let rmetas = &mut rmetas; - let dylibs = &mut dylibs; - let type_via_filename = (|| { - if file.starts_with("lib") { - if file.ends_with(".rlib") { - return Some(rlibs); - } - if file.ends_with(".rmeta") { - return Some(rmetas); - } - } - let dll_prefix = self.target.dll_prefix.as_ref(); - let dll_suffix = self.target.dll_suffix.as_ref(); - if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) { - return Some(dylibs); - } - None - })(); - match type_via_filename { - Some(type_via_filename) => { - type_via_filename.insert(loc_canon.clone(), PathKind::ExternFlag); + if file.starts_with("lib") { + if file.ends_with(".rlib") { + rlibs.insert(loc_canon.clone(), PathKind::ExternFlag); + continue; } - None => { - self.crate_rejections - .via_filename - .push(CrateMismatch { path: loc_orig.clone(), got: String::new() }); + if file.ends_with(".rmeta") { + rmetas.insert(loc_canon.clone(), PathKind::ExternFlag); + continue; } } + let dll_prefix = self.target.dll_prefix.as_ref(); + let dll_suffix = self.target.dll_suffix.as_ref(); + if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) { + dylibs.insert(loc_canon.clone(), PathKind::ExternFlag); + continue; + } + self.crate_rejections + .via_filename + .push(CrateMismatch { path: loc_orig.clone(), got: String::new() }); } // Extract the dylib/rlib/rmeta triple. From 017cca2755bcf23516bf6dbe0c27c19d7add443b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Feb 2022 18:50:13 +0100 Subject: [PATCH 2/5] Introduce -Zsplit-metadata option This will split the crate metadata out of library files. Instead only the svh is preserved to allow for loading the right rmeta file. This significicantly reduces library size. In addition it allows for cheaper checks if different library files are the same crate. --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- .../rustc_codegen_ssa/src/back/metadata.rs | 4 +- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_metadata/src/fs.rs | 25 +++-- compiler/rustc_metadata/src/locator.rs | 5 + compiler/rustc_metadata/src/rmeta/encoder.rs | 92 +++++++++++++++---- compiler/rustc_metadata/src/rmeta/mod.rs | 4 + compiler/rustc_session/src/options.rs | 2 + 8 files changed, 107 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index df35b5e8426f1..bb0d3c8a41eb2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -298,7 +298,7 @@ fn link_rlib<'a>( let (metadata, metadata_position) = create_wrapper_file( sess, ".rmeta".to_string(), - codegen_results.metadata.raw_data(), + codegen_results.metadata.maybe_reference(), ); let metadata = emit_wrapper_file(sess, &metadata, tmpdir, METADATA_FILENAME); match metadata_position { diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index ba7b53321a83d..6f6552d240f7b 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -578,8 +578,8 @@ pub fn create_compressed_metadata_file( symbol_name: &str, ) -> Vec { let mut packed_metadata = rustc_metadata::METADATA_HEADER.to_vec(); - packed_metadata.write_all(&(metadata.raw_data().len() as u64).to_le_bytes()).unwrap(); - packed_metadata.extend(metadata.raw_data()); + packed_metadata.write_all(&(metadata.maybe_reference().len() as u64).to_le_bytes()).unwrap(); + packed_metadata.extend(metadata.maybe_reference()); let Some(mut file) = create_object_file(sess) else { if sess.target.is_like_wasm { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 07c4b8987216c..dac3f661486c9 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -854,6 +854,7 @@ fn test_unstable_options_tracking_hash() { tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc"))); tracked!(small_data_threshold, Some(16)); tracked!(split_lto_unit, Some(true)); + tracked!(split_metadata, true); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); tracked!(stack_protector, StackProtector::All); tracked!(teach, true); diff --git a/compiler/rustc_metadata/src/fs.rs b/compiler/rustc_metadata/src/fs.rs index 4450d050c8e1f..105f87d840971 100644 --- a/compiler/rustc_metadata/src/fs.rs +++ b/compiler/rustc_metadata/src/fs.rs @@ -3,7 +3,7 @@ use std::{fs, io}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_middle::ty::TyCtxt; -use rustc_session::config::{OutFileName, OutputType}; +use rustc_session::config::{CrateType, OutFileName, OutputType}; use rustc_session::output::filename_for_metadata; use rustc_session::{MetadataKind, Session}; use tempfile::Builder as TempFileBuilder; @@ -50,7 +50,14 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) { .tempdir_in(out_filename.parent().unwrap_or_else(|| Path::new(""))) .unwrap_or_else(|err| tcx.dcx().emit_fatal(FailedCreateTempdir { err })); let metadata_tmpdir = MaybeTempDir::new(metadata_tmpdir, tcx.sess.opts.cg.save_temps); - let metadata_filename = metadata_tmpdir.as_ref().join(METADATA_FILENAME); + let metadata_filename = metadata_tmpdir.as_ref().join("full.rmeta"); + let metadata_reference_filename = if tcx.sess.opts.unstable_opts.split_metadata + && !tcx.crate_types().contains(&CrateType::ProcMacro) + { + Some(metadata_tmpdir.as_ref().join("ref.rmeta")) + } else { + None + }; // Always create a file at `metadata_filename`, even if we have nothing to write to it. // This simplifies the creation of the output `out_filename` when requested. @@ -60,9 +67,14 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) { std::fs::File::create(&metadata_filename).unwrap_or_else(|err| { tcx.dcx().emit_fatal(FailedCreateFile { filename: &metadata_filename, err }); }); + if let Some(metadata_reference_filename) = &metadata_reference_filename { + std::fs::File::create(metadata_reference_filename).unwrap_or_else(|err| { + tcx.dcx().emit_fatal(FailedCreateFile { filename: &metadata_filename, err }); + }); + } } MetadataKind::Uncompressed | MetadataKind::Compressed => { - encode_metadata(tcx, &metadata_filename); + encode_metadata(tcx, &metadata_filename, metadata_reference_filename.as_deref()) } }; @@ -100,9 +112,10 @@ pub fn encode_and_write_metadata(tcx: TyCtxt<'_>) -> (EncodedMetadata, bool) { // Load metadata back to memory: codegen may need to include it in object files. let metadata = - EncodedMetadata::from_path(metadata_filename, metadata_tmpdir).unwrap_or_else(|err| { - tcx.dcx().emit_fatal(FailedCreateEncodedMetadata { err }); - }); + EncodedMetadata::from_path(metadata_filename, metadata_reference_filename, metadata_tmpdir) + .unwrap_or_else(|err| { + tcx.dcx().emit_fatal(FailedCreateEncodedMetadata { err }); + }); let need_metadata_module = metadata_kind == MetadataKind::Compressed; diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 688120390f86d..f7b650f6702ce 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -580,6 +580,11 @@ impl<'a> CrateLocator<'a> { ) { Ok(blob) => { if let Some(h) = self.crate_matches(&blob, &lib) { + if blob.get_header().is_reference { + if slot.is_none() { + todo!("return error"); + } + } (h, blob) } else { info!("metadata mismatch"); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index c538ab99fb54b..95ac727ebdb22 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -701,6 +701,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { triple: tcx.sess.opts.target_triple.clone(), hash: tcx.crate_hash(LOCAL_CRATE), is_proc_macro_crate: proc_macro_data.is_some(), + is_reference: false, }, extra_filename: tcx.sess.opts.cg.extra_filename.clone(), stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(), @@ -2226,8 +2227,10 @@ fn prefetch_mir(tcx: TyCtxt<'_>) { // generated regardless of trailing bytes that end up in it. pub struct EncodedMetadata { - // The declaration order matters because `mmap` should be dropped before `_temp_dir`. - mmap: Option, + // The declaration order matters because `full_mmap` should be dropped + // before `_temp_dir`. + full_mmap: Option, + reference: Option>, // We need to carry MaybeTempDir to avoid deleting the temporary // directory while accessing the Mmap. _temp_dir: Option, @@ -2235,33 +2238,53 @@ pub struct EncodedMetadata { impl EncodedMetadata { #[inline] - pub fn from_path(path: PathBuf, temp_dir: Option) -> std::io::Result { + pub fn from_path( + path: PathBuf, + reference_path: Option, + temp_dir: Option, + ) -> std::io::Result { let file = std::fs::File::open(&path)?; let file_metadata = file.metadata()?; if file_metadata.len() == 0 { - return Ok(Self { mmap: None, _temp_dir: None }); + return Ok(Self { full_mmap: None, reference: None, _temp_dir: None }); } - let mmap = unsafe { Some(Mmap::map(file)?) }; - Ok(Self { mmap, _temp_dir: temp_dir }) + let full_mmap = unsafe { Some(Mmap::map(file)?) }; + + let reference = if let Some(reference_path) = reference_path { + Some(std::fs::read(reference_path)?) + } else { + None + }; + + Ok(Self { full_mmap, reference, _temp_dir: temp_dir }) } #[inline] - pub fn raw_data(&self) -> &[u8] { - self.mmap.as_deref().unwrap_or_default() + pub fn full(&self) -> &[u8] { + &self.full_mmap.as_deref().unwrap_or_default() + } + + #[inline] + pub fn maybe_reference(&self) -> &[u8] { + self.reference.as_deref().unwrap_or(self.full()) } } impl Encodable for EncodedMetadata { fn encode(&self, s: &mut S) { - let slice = self.raw_data(); + self.reference.encode(s); + + let slice = self.full(); slice.encode(s) } } impl Decodable for EncodedMetadata { fn decode(d: &mut D) -> Self { + let reference = >>::decode(d); + let len = d.read_usize(); - let mmap = if len > 0 { + let full_mmap = if len > 0 { let mut mmap = MmapMut::map_anon(len).unwrap(); for _ in 0..len { (&mut mmap[..]).write_all(&[d.read_u8()]).unwrap(); @@ -2272,11 +2295,11 @@ impl Decodable for EncodedMetadata { None }; - Self { mmap, _temp_dir: None } + Self { full_mmap, reference, _temp_dir: None } } } -pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) { +pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata"); // Since encoding metadata is not in a query, and nothing is cached, @@ -2290,6 +2313,42 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) { join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE)); } + with_encode_metadata_header(tcx, path, |ecx| { + // Encode all the entries and extra information in the crate, + // culminating in the `CrateRoot` which points to all of it. + let root = ecx.encode_crate_root(); + + // Flush buffer to ensure backing file has the correct size. + ecx.opaque.flush(); + // Record metadata size for self-profiling + tcx.prof.artifact_size( + "crate_metadata", + "crate_metadata", + ecx.opaque.file().metadata().unwrap().len(), + ); + + root.position.get() + }); + + if let Some(ref_path) = ref_path { + with_encode_metadata_header(tcx, ref_path, |ecx| { + let header: LazyValue = ecx.lazy(CrateHeader { + name: tcx.crate_name(LOCAL_CRATE), + triple: tcx.sess.opts.target_triple.clone(), + hash: tcx.crate_hash(LOCAL_CRATE), + is_proc_macro_crate: false, + is_reference: true, + }); + header.position.get() + }); + } +} + +fn with_encode_metadata_header( + tcx: TyCtxt<'_>, + path: &Path, + f: impl FnOnce(&mut EncodeContext<'_, '_>) -> usize, +) { let mut encoder = opaque::FileEncoder::new(path) .unwrap_or_else(|err| tcx.dcx().emit_fatal(FailCreateFileEncoder { err })); encoder.emit_raw_bytes(METADATA_HEADER); @@ -2324,9 +2383,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) { // Encode the rustc version string in a predictable location. rustc_version(tcx.sess.cfg_version).encode(&mut ecx); - // Encode all the entries and extra information in the crate, - // culminating in the `CrateRoot` which points to all of it. - let root = ecx.encode_crate_root(); + let root_position = f(&mut ecx); // Make sure we report any errors from writing to the file. // If we forget this, compilation can succeed with an incomplete rmeta file, @@ -2336,12 +2393,9 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path) { } let file = ecx.opaque.file(); - if let Err(err) = encode_root_position(file, root.position.get()) { + if let Err(err) = encode_root_position(file, root_position) { tcx.dcx().emit_fatal(FailWriteFile { path: ecx.opaque.path(), err }); } - - // Record metadata size for self-profiling - tcx.prof.artifact_size("crate_metadata", "crate_metadata", file.metadata().unwrap().len()); } fn encode_root_position(mut file: &File, pos: usize) -> Result<(), std::io::Error> { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 4f9cdc9a474bd..b9ebbd135859f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -220,6 +220,10 @@ pub(crate) struct CrateHeader { /// This is separate from [`ProcMacroData`] to avoid having to update [`METADATA_VERSION`] every /// time ProcMacroData changes. pub(crate) is_proc_macro_crate: bool, + /// Whether this header is a reference to a separate rmeta file. + /// + /// This is used inside rlibs and dylibs when using `-Zsplit-metadata`. + pub(crate) is_reference: bool, } /// Serialized `.rmeta` data for a crate. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 3af6df6301774..59305280f8b88 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2128,6 +2128,8 @@ written to standard error output)"), by the linker"), split_lto_unit: Option = (None, parse_opt_bool, [TRACKED], "enable LTO unit splitting (default: no)"), + split_metadata: bool = (false, parse_bool, [TRACKED], + "split metadata out of libraries into .rmeta files"), src_hash_algorithm: Option = (None, parse_src_file_hash, [TRACKED], "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] From 50c1208dc19203c1d5200e88ba3b110574f4754f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:16:28 +0000 Subject: [PATCH 3/5] Fix stdlib building --- compiler/rustc_metadata/src/locator.rs | 27 ++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index f7b650f6702ce..67f535186fbc0 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -580,11 +580,6 @@ impl<'a> CrateLocator<'a> { ) { Ok(blob) => { if let Some(h) = self.crate_matches(&blob, &lib) { - if blob.get_header().is_reference { - if slot.is_none() { - todo!("return error"); - } - } (h, blob) } else { info!("metadata mismatch"); @@ -659,7 +654,12 @@ impl<'a> CrateLocator<'a> { continue; } } - *slot = Some((hash, metadata, lib.clone())); + + if !metadata.get_header().is_reference { + // FIXME nicer error when only an rlib or dylib with is_reference is found + // and no .rmeta? + *slot = Some((hash, metadata, lib.clone())); + } ret = Some((lib, kind)); } @@ -735,6 +735,14 @@ impl<'a> CrateLocator<'a> { }; if file.starts_with("lib") { if file.ends_with(".rlib") { + if let Ok(rmeta_path) = try_canonicalize( + loc_orig + .parent() + .unwrap() + .join(file.strip_suffix(".rlib").unwrap().to_owned() + ".rmeta"), + ) { + rmetas.insert(rmeta_path, PathKind::ExternFlag); + } rlibs.insert(loc_canon.clone(), PathKind::ExternFlag); continue; } @@ -746,6 +754,13 @@ impl<'a> CrateLocator<'a> { let dll_prefix = self.target.dll_prefix.as_ref(); let dll_suffix = self.target.dll_suffix.as_ref(); if file.starts_with(dll_prefix) && file.ends_with(dll_suffix) { + if let Ok(rmeta_path) = try_canonicalize(loc_orig.parent().unwrap().join( + "lib".to_owned() + + file.strip_prefix(dll_prefix).unwrap().strip_suffix(dll_suffix).unwrap() + + ".rmeta", + )) { + rmetas.insert(rmeta_path, PathKind::ExternFlag); + } dylibs.insert(loc_canon.clone(), PathKind::ExternFlag); continue; } From bedeb199b23813d83f6bcd22ad038948c6144203 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 1 Jul 2024 19:16:37 +0000 Subject: [PATCH 4/5] Rustbuild: enable -Zsplit-metadata for stage != 0 --- src/bootstrap/src/bin/rustc.rs | 6 ++++++ src/bootstrap/src/core/build_steps/compile.rs | 19 +++++++++++-------- src/bootstrap/src/core/builder/cargo.rs | 12 ++++++++++++ tests/ui/duplicate_entry_error.rs | 4 ++-- tests/ui/duplicate_entry_error.stderr | 2 +- tests/ui/error-codes/E0152.rs | 5 ++--- tests/ui/error-codes/E0152.stderr | 2 +- tests/ui/lang-items/duplicate.rs | 2 +- tests/ui/lang-items/duplicate.stderr | 2 +- tests/ui/panic-handler/panic-handler-std.rs | 2 +- .../ui/panic-handler/panic-handler-std.stderr | 2 +- 11 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 6104506759282..cc7e77122e1ad 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -130,6 +130,12 @@ fn main() { } } + if orig_args.iter().any(|arg| arg == "-Zsplit-metadata") + && orig_args.windows(2).any(|args| args[0] == "--crate-type" && args[1] == "dylib") + { + cmd.arg("--emit").arg("metadata"); + } + // Print backtrace in case of ICE if env::var("RUSTC_BACKTRACE_ON_ICE").is_ok() && env::var("RUST_BACKTRACE").is_err() { cmd.env("RUST_BACKTRACE", "1"); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4c4df922b3799..10a4c29156453 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2050,14 +2050,12 @@ pub fn run_cargo( || filename.ends_with(".a") || is_debug_info(&filename) || is_dylib(Path::new(&*filename)) + || filename.ends_with(".rmeta") { - // Always keep native libraries, rust dylibs and debuginfo + // Always keep native libraries, rust dylibs, debuginfo and crate metadata keep = true; } - if is_check && filename.ends_with(".rmeta") { - // During check builds we need to keep crate metadata - keep = true; - } else if rlib_only_metadata { + if !is_check && rlib_only_metadata { if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") || filename.contains("stable_mir") @@ -2069,7 +2067,6 @@ pub fn run_cargo( // Distribute the rest of the rustc crates as rmeta files only to reduce // the tarball sizes by about 50%. The object files are linked into // librustc_driver.so, so it is still possible to link against them. - keep |= filename.ends_with(".rmeta"); } } else { // In all other cases keep all rlibs @@ -2115,7 +2112,12 @@ pub fn run_cargo( let file_stem = parts.next().unwrap().to_owned(); let extension = parts.next().unwrap().to_owned(); - toplevel.push((file_stem, extension, expected_len)); + if extension == "so" || extension == "dylib" { + // FIXME workaround for the fact that cargo doesn't understand `-Zsplit-metadata` + toplevel.push((file_stem.clone(), "rmeta".to_owned(), None)); + } + + toplevel.push((file_stem, extension, Some(expected_len))); } }); @@ -2136,7 +2138,7 @@ pub fn run_cargo( .collect::>(); for (prefix, extension, expected_len) in toplevel { let candidates = contents.iter().filter(|&(_, filename, meta)| { - meta.len() == expected_len + expected_len.is_none_or(|expected_len| meta.len() == expected_len) && filename .strip_prefix(&prefix[..]) .map(|s| s.starts_with('-') && s.ends_with(&extension[..])) @@ -2147,6 +2149,7 @@ pub fn run_cargo( }); let path_to_add = match max { Some(triple) => triple.0.to_str().unwrap(), + None if extension == "rmeta" => continue, // cfg(not(bootstrap)) remove this once -Zsplit-metadata is passed for all stages None => panic!("no output generated for {prefix:?} {extension:?}"), }; if is_dylib(Path::new(path_to_add)) { diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 2692a129ef3b9..3a1fc3b715a2a 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -626,6 +626,18 @@ impl Builder<'_> { hostflags.arg("-Zunstable-options"); hostflags.arg("--check-cfg=cfg(bootstrap)"); + match mode { + Mode::Std | Mode::Rustc | Mode::Codegen => { + // cfg(bootstrap) unconditionally pass this once the bootstrap compiler understands it + if stage != 0 { + // FIXME remove once cargo enables this by default + rustflags.arg("-Zsplit-metadata"); + } + } + // Tools may not expect to be compiled with -Zsplit-metadata + Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {} + } + // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`, // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See // #71458. diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs index 5a25802c6e789..69892379d6c88 100644 --- a/tests/ui/duplicate_entry_error.rs +++ b/tests/ui/duplicate_entry_error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" // note-pattern: first defined in crate `std`. // Test for issue #31788 and E0152 @@ -11,7 +11,7 @@ use core::panic::PanicInfo; #[lang = "panic_impl"] fn panic_impl(info: &PanicInfo) -> ! { -//~^ ERROR: found duplicate lang item `panic_impl` + //~^ ERROR: found duplicate lang item `panic_impl` loop {} } diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr index 958e9c7527d8c..73436153e6677 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/duplicate_entry_error.stderr @@ -8,7 +8,7 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta = note: second definition in the local crate (`duplicate_entry_error`) error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs index 565e92baf02ea..6c339b253c55b 100644 --- a/tests/ui/error-codes/E0152.rs +++ b/tests/ui/error-codes/E0152.rs @@ -1,8 +1,7 @@ -//@ normalize-stderr: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +//@ normalize-stderr: "loaded from .*liballoc-.*.rmeta" -> "loaded from SYSROOT/liballoc-*.rmeta" #![feature(lang_items)] #[lang = "owned_box"] struct Foo(T); //~ ERROR E0152 -fn main() { -} +fn main() {} diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr index dbea7e6d27fbe..73df5803e839a 100644 --- a/tests/ui/error-codes/E0152.stderr +++ b/tests/ui/error-codes/E0152.stderr @@ -5,7 +5,7 @@ LL | struct Foo(T); | ^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) - = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib + = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rmeta = note: second definition in the local crate (`E0152`) error: aborting due to 1 previous error diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs index 4594e9456a4ce..bab952fc9ad1c 100644 --- a/tests/ui/lang-items/duplicate.rs +++ b/tests/ui/lang-items/duplicate.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" +//@ normalize-stderr: "loaded from .*libcore-.*.rmeta" -> "loaded from SYSROOT/libcore-*.rmeta" #![feature(lang_items)] #[lang = "sized"] diff --git a/tests/ui/lang-items/duplicate.stderr b/tests/ui/lang-items/duplicate.stderr index aaa8f5e605afa..5639bcc838d81 100644 --- a/tests/ui/lang-items/duplicate.stderr +++ b/tests/ui/lang-items/duplicate.stderr @@ -5,7 +5,7 @@ LL | trait Sized {} | ^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) - = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib + = note: first definition in `core` loaded from SYSROOT/libcore-*.rmeta = note: second definition in the local crate (`duplicate`) error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 4eb05b5365feb..e6e5b8008c545 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" //@ error-pattern: found duplicate lang item `panic_impl` extern crate core; diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index caae16118ef7f..de71b675211e9 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta = note: second definition in the local crate (`panic_handler_std`) error: aborting due to 1 previous error From 6720404d38e0a9bd80d41a35bfec855e9608bb7c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:48:30 +0000 Subject: [PATCH 5/5] Fix cg_clif tests --- compiler/rustc_codegen_cranelift/build_system/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index 8de419a0c4eb2..1952af2ff37ed 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -428,6 +428,7 @@ impl<'a> TestRunner<'a> { cmd.arg(&self.target_compiler.triple); cmd.arg("-Cpanic=abort"); cmd.arg("--check-cfg=cfg(jit)"); + cmd.arg("--emit=metadata,link"); cmd.args(args); cmd }