Print the crates not available as static

This commit is contained in:
John Kåre Alsaker 2024-03-11 17:02:12 +01:00
parent a6d93acf5f
commit 38518c44b0
3 changed files with 32 additions and 8 deletions

View File

@ -38,6 +38,9 @@ metadata_crate_dep_multiple =
cannot satisfy dependencies so `{$crate_name}` only shows up once cannot satisfy dependencies so `{$crate_name}` only shows up once
.help = having upstream crates all available in one format will likely make this go away .help = having upstream crates all available in one format will likely make this go away
metadata_crate_dep_not_static =
`{$crate_name}` was unavailable as a static crate, preventing fully static linking
metadata_crate_location_unknown_type = metadata_crate_location_unknown_type =
extern location for {$crate_name} is of an unknown type: {$path} extern location for {$crate_name} is of an unknown type: {$path}

View File

@ -54,7 +54,7 @@
use crate::creader::CStore; use crate::creader::CStore;
use crate::errors::{ use crate::errors::{
BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired, BadPanicStrategy, CrateDepMultiple, IncompatiblePanicInDropStrategy, LibRequired,
RequiredPanicStrategy, RlibRequired, RustcLibRequired, TwoPanicRuntimes, NonStaticCrateDep, RequiredPanicStrategy, RlibRequired, RustcLibRequired, TwoPanicRuntimes,
}; };
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
@ -123,13 +123,15 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
CrateType::Rlib => Linkage::NotLinked, CrateType::Rlib => Linkage::NotLinked,
}; };
let mut unavailable_as_static = Vec::new();
match preferred_linkage { match preferred_linkage {
// If the crate is not linked, there are no link-time dependencies. // If the crate is not linked, there are no link-time dependencies.
Linkage::NotLinked => return Vec::new(), Linkage::NotLinked => return Vec::new(),
Linkage::Static => { Linkage::Static => {
// Attempt static linkage first. For dylibs and executables, we may be // Attempt static linkage first. For dylibs and executables, we may be
// able to retry below with dynamic linkage. // able to retry below with dynamic linkage.
if let Some(v) = attempt_static(tcx) { if let Some(v) = attempt_static(tcx, &mut unavailable_as_static) {
return v; return v;
} }
@ -169,11 +171,11 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
let src = tcx.used_crate_source(cnum); let src = tcx.used_crate_source(cnum);
if src.dylib.is_some() { if src.dylib.is_some() {
info!("adding dylib: {}", name); info!("adding dylib: {}", name);
add_library(tcx, cnum, RequireDynamic, &mut formats); add_library(tcx, cnum, RequireDynamic, &mut formats, &mut unavailable_as_static);
let deps = tcx.dylib_dependency_formats(cnum); let deps = tcx.dylib_dependency_formats(cnum);
for &(depnum, style) in deps.iter() { for &(depnum, style) in deps.iter() {
info!("adding {:?}: {}", style, tcx.crate_name(depnum)); info!("adding {:?}: {}", style, tcx.crate_name(depnum));
add_library(tcx, depnum, style, &mut formats); add_library(tcx, depnum, style, &mut formats, &mut unavailable_as_static);
} }
} }
} }
@ -201,7 +203,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
{ {
assert!(src.rlib.is_some() || src.rmeta.is_some()); assert!(src.rlib.is_some() || src.rmeta.is_some());
info!("adding staticlib: {}", tcx.crate_name(cnum)); info!("adding staticlib: {}", tcx.crate_name(cnum));
add_library(tcx, cnum, RequireStatic, &mut formats); add_library(tcx, cnum, RequireStatic, &mut formats, &mut unavailable_as_static);
ret[cnum.as_usize() - 1] = Linkage::Static; ret[cnum.as_usize() - 1] = Linkage::Static;
} }
} }
@ -252,6 +254,7 @@ fn add_library(
cnum: CrateNum, cnum: CrateNum,
link: LinkagePreference, link: LinkagePreference,
m: &mut FxHashMap<CrateNum, LinkagePreference>, m: &mut FxHashMap<CrateNum, LinkagePreference>,
unavailable_as_static: &mut Vec<CrateNum>,
) { ) {
match m.get(&cnum) { match m.get(&cnum) {
Some(&link2) => { Some(&link2) => {
@ -263,7 +266,13 @@ fn add_library(
// This error is probably a little obscure, but I imagine that it // This error is probably a little obscure, but I imagine that it
// can be refined over time. // can be refined over time.
if link2 != link || link == RequireStatic { if link2 != link || link == RequireStatic {
tcx.dcx().emit_err(CrateDepMultiple { crate_name: tcx.crate_name(cnum) }); tcx.dcx().emit_err(CrateDepMultiple {
crate_name: tcx.crate_name(cnum),
non_static_deps: unavailable_as_static
.drain(..)
.map(|cnum| NonStaticCrateDep { crate_name: tcx.crate_name(cnum) })
.collect(),
});
} }
} }
None => { None => {
@ -272,7 +281,7 @@ fn add_library(
} }
} }
fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> { fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<DependencyList> {
let all_crates_available_as_rlib = tcx let all_crates_available_as_rlib = tcx
.crates(()) .crates(())
.iter() .iter()
@ -281,7 +290,11 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
if tcx.dep_kind(cnum).macros_only() { if tcx.dep_kind(cnum).macros_only() {
return None; return None;
} }
Some(tcx.used_crate_source(cnum).rlib.is_some()) let is_rlib = tcx.used_crate_source(cnum).rlib.is_some();
if !is_rlib {
unavailable.push(cnum);
}
Some(is_rlib)
}) })
.all(|is_rlib| is_rlib); .all(|is_rlib| is_rlib);
if !all_crates_available_as_rlib { if !all_crates_available_as_rlib {

View File

@ -38,6 +38,14 @@ pub struct RustcLibRequired<'a> {
#[help] #[help]
pub struct CrateDepMultiple { pub struct CrateDepMultiple {
pub crate_name: Symbol, pub crate_name: Symbol,
#[subdiagnostic]
pub non_static_deps: Vec<NonStaticCrateDep>,
}
#[derive(Subdiagnostic)]
#[note(metadata_crate_dep_not_static)]
pub struct NonStaticCrateDep {
pub crate_name: Symbol,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]