1
Fork 0

Auto merge of #106224 - bjorn3:staticlib_fixes, r=wesleywiser

Small fixes for --crate-type staticlib

The first commit doesn't have an effect until we start translating error messages. The second commit fixes potential linker errors when combining `--crate-type staticlib` with another crate type and I think `-Cprefer-dynamic`.
This commit is contained in:
bors 2023-01-04 21:35:15 +00:00
commit d9e317a176
4 changed files with 80 additions and 84 deletions

View file

@ -11,7 +11,7 @@ use rustc_metadata::find_native_static_library;
use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME}; use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME};
use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip}; use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind}; use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
use rustc_session::cstore::DllImport; use rustc_session::cstore::DllImport;
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
@ -208,16 +208,16 @@ pub fn link_binary<'a>(
Ok(()) Ok(())
} }
// Crate type is not passed when calculating the dylibs to include for LTO. In that case all
// crate types must use the same dependency formats.
pub fn each_linked_rlib( pub fn each_linked_rlib(
sess: &Session,
info: &CrateInfo, info: &CrateInfo,
crate_type: Option<CrateType>,
f: &mut dyn FnMut(CrateNum, &Path), f: &mut dyn FnMut(CrateNum, &Path),
) -> Result<(), errors::LinkRlibError> { ) -> Result<(), errors::LinkRlibError> {
let crates = info.used_crates.iter(); let crates = info.used_crates.iter();
let mut fmts = None;
let lto_active = matches!(sess.lto(), Lto::Fat | Lto::Thin); let fmts = if crate_type.is_none() {
if lto_active {
for combination in info.dependency_formats.iter().combinations(2) { for combination in info.dependency_formats.iter().combinations(2) {
let (ty1, list1) = &combination[0]; let (ty1, list1) = &combination[0];
let (ty2, list2) = &combination[1]; let (ty2, list2) = &combination[1];
@ -230,27 +230,23 @@ pub fn each_linked_rlib(
}); });
} }
} }
if info.dependency_formats.is_empty() {
return Err(errors::LinkRlibError::MissingFormat);
} }
&info.dependency_formats[0].1
} else {
let fmts = info
.dependency_formats
.iter()
.find_map(|&(ty, ref list)| if Some(ty) == crate_type { Some(list) } else { None });
for (ty, list) in info.dependency_formats.iter() {
match ty {
CrateType::Executable
| CrateType::Staticlib
| CrateType::Cdylib
| CrateType::ProcMacro => {
fmts = Some(list);
break;
}
CrateType::Dylib if lto_active => {
fmts = Some(list);
break;
}
_ => {}
}
}
let Some(fmts) = fmts else { let Some(fmts) = fmts else {
return Err(errors::LinkRlibError::MissingFormat); return Err(errors::LinkRlibError::MissingFormat);
}; };
fmts
};
for &cnum in crates { for &cnum in crates {
match fmts.get(cnum.as_usize() - 1) { match fmts.get(cnum.as_usize() - 1) {
Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue, Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
@ -516,7 +512,10 @@ fn link_staticlib<'a>(
)?; )?;
let mut all_native_libs = vec![]; let mut all_native_libs = vec![];
let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| { let res = each_linked_rlib(
&codegen_results.crate_info,
Some(CrateType::Staticlib),
&mut |cnum, path| {
let name = codegen_results.crate_info.crate_name[&cnum]; let name = codegen_results.crate_info.crate_name[&cnum];
let native_libs = &codegen_results.crate_info.native_libraries[&cnum]; let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
@ -562,7 +561,9 @@ fn link_staticlib<'a>(
// Otherwise if this is *not* a rust object and we're skipping // Otherwise if this is *not* a rust object and we're skipping
// objects then skip this file // objects then skip this file
if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) { if skip_object_files
&& (!fname.starts_with(&obj_start) || !fname.ends_with(".o"))
{
return true; return true;
} }
@ -572,8 +573,10 @@ fn link_staticlib<'a>(
) )
.unwrap(); .unwrap();
all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); all_native_libs
}); .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
},
);
if let Err(e) = res { if let Err(e) = res {
sess.emit_fatal(e); sess.emit_fatal(e);
} }
@ -1354,7 +1357,8 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
if !lib_args.is_empty() { if !lib_args.is_empty() {
sess.emit_note(errors::StaticLibraryNativeArtifacts); sess.emit_note(errors::StaticLibraryNativeArtifacts);
// Prefix for greppability // Prefix for greppability
sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") }); // Note: This must not be translated as tools are allowed to depend on this exact string.
sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" ")));
} }
} }

View file

@ -1002,7 +1002,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
let sess = tcx.sess; let sess = tcx.sess;
let mut each_linked_rlib_for_lto = Vec::new(); let mut each_linked_rlib_for_lto = Vec::new();
drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| { drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
if link::ignored_for_lto(sess, crate_info, cnum) { if link::ignored_for_lto(sess, crate_info, cnum) {
return; return;
} }

View file

@ -444,12 +444,6 @@ pub struct LinkerFileStem;
#[diag(codegen_ssa_static_library_native_artifacts)] #[diag(codegen_ssa_static_library_native_artifacts)]
pub struct StaticLibraryNativeArtifacts; pub struct StaticLibraryNativeArtifacts;
#[derive(Diagnostic)]
#[diag(codegen_ssa_native_static_libs)]
pub struct NativeStaticLibs {
pub arguments: String,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(codegen_ssa_link_script_unavailable)] #[diag(codegen_ssa_link_script_unavailable)]
pub struct LinkScriptUnavailable; pub struct LinkScriptUnavailable;

View file

@ -157,8 +157,6 @@ codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
codegen_ssa_native_static_libs = native-static-libs: {$arguments}
codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker
codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error} codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error}