diff options
| author | bors <bors@rust-lang.org> | 2022-07-31 13:26:27 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-07-31 13:26:27 +0000 |
| commit | e5a7d8f945f4259fb6b8c4953a65248243c054d1 (patch) | |
| tree | 00c56cd7266df82399b9982b57ac9f5485618692 /compiler/rustc_codegen_ssa/src/back/link.rs | |
| parent | 76822a28780a9a93be04409e52c5df21663aab97 (diff) | |
| parent | 990bce4da0a02a15a11abb22b00aacc5d329ce42 (diff) | |
| download | rust-e5a7d8f945f4259fb6b8c4953a65248243c054d1.tar.gz rust-e5a7d8f945f4259fb6b8c4953a65248243c054d1.zip | |
Auto merge of #99979 - Dylan-DPC:rollup-ikkejgy, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #99186 (Use LocalDefId for closures more) - #99741 (Use `impl`'s generics when suggesting fix on bad `impl Copy`) - #99844 (Introduce an ArchiveBuilderBuilder) - #99921 (triagebot.yml: CC Enselic when rustdoc-json-types changes) - #99974 (Suggest removing a semicolon and boxing the expressions for if-else) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back/link.rs')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 181 |
1 files changed, 111 insertions, 70 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c26e8d99bbb..13a7b6be947 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -24,7 +24,7 @@ use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; -use super::archive::{find_library, ArchiveBuilder}; +use super::archive::{find_library, ArchiveBuilder, ArchiveBuilderBuilder}; use super::command::Command; use super::linker::{self, Linker}; use super::metadata::{create_rmeta_file, MetadataPosition}; @@ -56,8 +56,9 @@ pub fn ensure_removed(diag_handler: &Handler, path: &Path) { /// Performs the linkage portion of the compilation phase. This will generate all /// of the requested outputs for this compilation session. -pub fn link_binary<'a, B: ArchiveBuilder<'a>>( +pub fn link_binary<'a>( sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, codegen_results: &CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorGuaranteed> { @@ -101,21 +102,29 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( match crate_type { CrateType::Rlib => { let _timer = sess.timer("link_rlib"); - link_rlib::<B>( + info!("preparing rlib to {:?}", out_filename); + link_rlib( sess, + archive_builder_builder, codegen_results, RlibFlavor::Normal, - &out_filename, &path, )? - .build(); + .build(&out_filename); } CrateType::Staticlib => { - link_staticlib::<B>(sess, codegen_results, &out_filename, &path)?; + link_staticlib( + sess, + archive_builder_builder, + codegen_results, + &out_filename, + &path, + )?; } _ => { - link_natively::<B>( + link_natively( sess, + archive_builder_builder, crate_type, &out_filename, codegen_results, @@ -245,18 +254,16 @@ pub fn each_linked_rlib( /// the object file of the crate, but it also contains all of the object files from native /// libraries. This is done by unzipping native libraries and inserting all of the contents into /// this archive. -fn link_rlib<'a, B: ArchiveBuilder<'a>>( +fn link_rlib<'a>( sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, codegen_results: &CodegenResults, flavor: RlibFlavor, - out_filename: &Path, tmpdir: &MaybeTempDir, -) -> Result<B, ErrorGuaranteed> { - info!("preparing rlib to {:?}", out_filename); - +) -> Result<Box<dyn ArchiveBuilder<'a> + 'a>, ErrorGuaranteed> { let lib_search_paths = archive_search_paths(sess); - let mut ab = <B as ArchiveBuilder>::new(sess, out_filename); + let mut ab = archive_builder_builder.new_archive_builder(sess); let trailing_metadata = match flavor { RlibFlavor::Normal => { @@ -342,7 +349,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( if let Some(name) = lib.name { let location = find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess); - ab.add_archive(&location, |_| false).unwrap_or_else(|e| { + ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| { sess.fatal(&format!( "failed to add native library {}: {}", location.to_string_lossy(), @@ -355,7 +362,16 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>( for (raw_dylib_name, raw_dylib_imports) in collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)? { - ab.inject_dll_import_lib(&raw_dylib_name, &raw_dylib_imports, tmpdir); + let output_path = archive_builder_builder.create_dll_import_lib( + sess, + &raw_dylib_name, + &raw_dylib_imports, + tmpdir.as_ref(), + ); + + ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| { + sess.fatal(&format!("failed to add native library {}: {}", output_path.display(), e)); + }); } if let Some(trailing_metadata) = trailing_metadata { @@ -446,14 +462,21 @@ fn collate_raw_dylibs( /// /// There's no need to include metadata in a static archive, so ensure to not link in the metadata /// object file (and also don't prepare the archive with a metadata file). -fn link_staticlib<'a, B: ArchiveBuilder<'a>>( +fn link_staticlib<'a>( sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, codegen_results: &CodegenResults, out_filename: &Path, tempdir: &MaybeTempDir, ) -> Result<(), ErrorGuaranteed> { - let mut ab = - link_rlib::<B>(sess, codegen_results, RlibFlavor::StaticlibBase, out_filename, tempdir)?; + info!("preparing staticlib to {:?}", out_filename); + let mut ab = link_rlib( + sess, + archive_builder_builder, + codegen_results, + RlibFlavor::StaticlibBase, + tempdir, + )?; let mut all_native_libs = vec![]; let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| { @@ -487,26 +510,29 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>( // might be also an extra name suffix let obj_start = name.as_str().to_owned(); - ab.add_archive(path, move |fname: &str| { - // Ignore metadata files, no matter the name. - if fname == METADATA_FILENAME { - return true; - } + ab.add_archive( + path, + Box::new(move |fname: &str| { + // Ignore metadata files, no matter the name. + if fname == METADATA_FILENAME { + return true; + } - // Don't include Rust objects if LTO is enabled - if lto && looks_like_rust_object_file(fname) { - return true; - } + // Don't include Rust objects if LTO is enabled + if lto && looks_like_rust_object_file(fname) { + return true; + } - // Otherwise if this is *not* a rust object and we're skipping - // objects then skip this file - if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { - return true; - } + // Otherwise if this is *not* a rust object and we're skipping + // objects then skip this file + if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { + return true; + } - // ok, don't skip this - false - }) + // ok, don't skip this + false + }), + ) .unwrap(); all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); @@ -515,7 +541,7 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>( sess.fatal(&e); } - ab.build(); + ab.build(out_filename); if !all_native_libs.is_empty() { if sess.opts.prints.contains(&PrintRequest::NativeStaticLibs) { @@ -645,8 +671,9 @@ fn link_dwarf_object<'a>( /// /// This will invoke the system linker/cc to create the resulting file. This links to all upstream /// files as well. -fn link_natively<'a, B: ArchiveBuilder<'a>>( +fn link_natively<'a>( sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, crate_type: CrateType, out_filename: &Path, codegen_results: &CodegenResults, @@ -654,10 +681,11 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( ) -> Result<(), ErrorGuaranteed> { info!("preparing {:?} to {:?}", crate_type, out_filename); let (linker_path, flavor) = linker_and_flavor(sess); - let mut cmd = linker_with_args::<B>( + let mut cmd = linker_with_args( &linker_path, flavor, sess, + archive_builder_builder, crate_type, tmpdir, out_filename, @@ -1844,10 +1872,11 @@ fn add_rpath_args( /// to the linking process as a whole. /// Order-independent options may still override each other in order-dependent fashion, /// e.g `--foo=yes --foo=no` may be equivalent to `--foo=no`. -fn linker_with_args<'a, B: ArchiveBuilder<'a>>( +fn linker_with_args<'a>( path: &Path, flavor: LinkerFlavor, sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, crate_type: CrateType, tmpdir: &Path, out_filename: &Path, @@ -1948,7 +1977,14 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( } // Upstream rust libraries and their non-bundled static libraries - add_upstream_rust_crates::<B>(cmd, sess, codegen_results, crate_type, tmpdir); + add_upstream_rust_crates( + cmd, + sess, + archive_builder_builder, + codegen_results, + crate_type, + tmpdir, + ); // Upstream dynamic native libraries linked with `#[link]` attributes at and `-l` // command line options. @@ -1963,7 +1999,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( for (raw_dylib_name, raw_dylib_imports) in collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)? { - cmd.add_object(&B::create_dll_import_lib( + cmd.add_object(&archive_builder_builder.create_dll_import_lib( sess, &raw_dylib_name, &raw_dylib_imports, @@ -2256,9 +2292,10 @@ fn add_local_native_libraries( /// /// Rust crates are not considered at all when creating an rlib output. All dependencies will be /// linked when producing the final output (instead of the intermediate rlib version). -fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( +fn add_upstream_rust_crates<'a>( cmd: &mut dyn Linker, sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, codegen_results: &CodegenResults, crate_type: CrateType, tmpdir: &Path, @@ -2347,7 +2384,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( let src = &codegen_results.crate_info.used_crate_source[&cnum]; match data[cnum.as_usize() - 1] { _ if codegen_results.crate_info.profiler_runtime == Some(cnum) => { - add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum); + add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum); } // compiler-builtins are always placed last to ensure that they're // linked correctly. @@ -2357,7 +2394,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( } Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { - add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum); + add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum); // Link static native libs with "-bundle" modifier only if the crate they originate from // is being linked statically to the current crate. If it's linked dynamically @@ -2431,7 +2468,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic` // is used) if let Some(cnum) = compiler_builtins { - add_static_crate::<B>(cmd, sess, codegen_results, tmpdir, cnum); + add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum); } // Converts a library file-stem into a cc -l argument @@ -2457,9 +2494,10 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( // Note, however, that if we're not doing LTO we can just pass the rlib // blindly to the linker (fast) because it's fine if it's not actually // included as we're at the end of the dependency chain. - fn add_static_crate<'a, B: ArchiveBuilder<'a>>( + fn add_static_crate<'a>( cmd: &mut dyn Linker, sess: &'a Session, + archive_builder_builder: &dyn ArchiveBuilderBuilder, codegen_results: &CodegenResults, tmpdir: &Path, cnum: CrateNum, @@ -2499,38 +2537,41 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>( let is_builtins = sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum); - let mut archive = <B as ArchiveBuilder>::new(sess, &dst); - if let Err(e) = archive.add_archive(cratepath, move |f| { - if f == METADATA_FILENAME { - return true; - } + let mut archive = archive_builder_builder.new_archive_builder(sess); + if let Err(e) = archive.add_archive( + cratepath, + Box::new(move |f| { + if f == METADATA_FILENAME { + return true; + } - let canonical = f.replace('-', "_"); + let canonical = f.replace('-', "_"); - let is_rust_object = - canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f); + let is_rust_object = + canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f); - // If we've been requested to skip all native object files - // (those not generated by the rust compiler) then we can skip - // this file. See above for why we may want to do this. - let skip_because_cfg_say_so = skip_native && !is_rust_object; + // If we've been requested to skip all native object files + // (those not generated by the rust compiler) then we can skip + // this file. See above for why we may want to do this. + let skip_because_cfg_say_so = skip_native && !is_rust_object; - // If we're performing LTO and this is a rust-generated object - // file, then we don't need the object file as it's part of the - // LTO module. Note that `#![no_builtins]` is excluded from LTO, - // though, so we let that object file slide. - let skip_because_lto = - upstream_rust_objects_already_included && is_rust_object && is_builtins; + // If we're performing LTO and this is a rust-generated object + // file, then we don't need the object file as it's part of the + // LTO module. Note that `#![no_builtins]` is excluded from LTO, + // though, so we let that object file slide. + let skip_because_lto = + upstream_rust_objects_already_included && is_rust_object && is_builtins; - if skip_because_cfg_say_so || skip_because_lto { - return true; - } + if skip_because_cfg_say_so || skip_because_lto { + return true; + } - false - }) { + false + }), + ) { sess.fatal(&format!("failed to build archive from rlib: {}", e)); } - if archive.build() { + if archive.build(&dst) { link_upstream(&dst); } }); |
