Auto merge of #44279 - smaeul:crt_static-deps, r=alexcrichton
Require rlibs for dependent crates when linking static executables This handles the case for `CrateTypeExecutable` and `+crt_static`. I reworked the match block to avoid duplicating the `attempt_static` and error checking code again (this case would have been a copy of the `CrateTypeCdylib`/`CrateTypeStaticlib` case). On `linux-musl` targets where `std` was built with `crt_static = false` in `config.toml`, this change brings the test suite from entirely failing to mostly passing. This change should not affect behavior for other crate types, or for targets which do not respect `+crt_static`.
This commit is contained in:
commit
6c476ce462
@ -112,52 +112,61 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
match ty {
|
||||
// If the global prefer_dynamic switch is turned off, first attempt
|
||||
// static linkage (this can fail).
|
||||
config::CrateTypeExecutable if !sess.opts.cg.prefer_dynamic => {
|
||||
if let Some(v) = attempt_static(tcx) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// No linkage happens with rlibs, we just needed the metadata (which we
|
||||
// got long ago), so don't bother with anything.
|
||||
config::CrateTypeRlib => return Vec::new(),
|
||||
|
||||
// Staticlibs and cdylibs must have all static dependencies. If any fail
|
||||
// to be found, we generate some nice pretty errors.
|
||||
config::CrateTypeStaticlib |
|
||||
config::CrateTypeCdylib => {
|
||||
if let Some(v) = attempt_static(tcx) {
|
||||
return v;
|
||||
}
|
||||
for &cnum in tcx.crates().iter() {
|
||||
if tcx.dep_kind(cnum).macros_only() { continue }
|
||||
let src = tcx.used_crate_source(cnum);
|
||||
if src.rlib.is_some() { continue }
|
||||
sess.err(&format!("dependency `{}` not found in rlib format",
|
||||
tcx.crate_name(cnum)));
|
||||
}
|
||||
return Vec::new();
|
||||
}
|
||||
let preferred_linkage = match ty {
|
||||
// cdylibs must have all static dependencies.
|
||||
config::CrateTypeCdylib => Linkage::Static,
|
||||
|
||||
// Generating a dylib without `-C prefer-dynamic` means that we're going
|
||||
// to try to eagerly statically link all dependencies. This is normally
|
||||
// done for end-product dylibs, not intermediate products.
|
||||
config::CrateTypeDylib if !sess.opts.cg.prefer_dynamic => {
|
||||
config::CrateTypeDylib if !sess.opts.cg.prefer_dynamic => Linkage::Static,
|
||||
config::CrateTypeDylib => Linkage::Dynamic,
|
||||
|
||||
// If the global prefer_dynamic switch is turned off, or the final
|
||||
// executable will be statically linked, prefer static crate linkage.
|
||||
config::CrateTypeExecutable if !sess.opts.cg.prefer_dynamic ||
|
||||
sess.crt_static() => Linkage::Static,
|
||||
config::CrateTypeExecutable => Linkage::Dynamic,
|
||||
|
||||
// proc-macro crates are required to be dylibs, and they're currently
|
||||
// required to link to libsyntax as well.
|
||||
config::CrateTypeProcMacro => Linkage::Dynamic,
|
||||
|
||||
// No linkage happens with rlibs, we just needed the metadata (which we
|
||||
// got long ago), so don't bother with anything.
|
||||
config::CrateTypeRlib => Linkage::NotLinked,
|
||||
|
||||
// staticlibs must have all static dependencies.
|
||||
config::CrateTypeStaticlib => Linkage::Static,
|
||||
};
|
||||
|
||||
if preferred_linkage == Linkage::NotLinked {
|
||||
// If the crate is not linked, there are no link-time dependencies.
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
if preferred_linkage == Linkage::Static {
|
||||
// Attempt static linkage first. For dylibs and executables, we may be
|
||||
// able to retry below with dynamic linkage.
|
||||
if let Some(v) = attempt_static(tcx) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// Everything else falls through below. This will happen either with the
|
||||
// `-C prefer-dynamic` or because we're a proc-macro crate. Note that
|
||||
// proc-macro crates are required to be dylibs, and they're currently
|
||||
// required to link to libsyntax as well.
|
||||
config::CrateTypeExecutable |
|
||||
config::CrateTypeDylib |
|
||||
config::CrateTypeProcMacro => {},
|
||||
// Staticlibs, cdylibs, and static executables must have all static
|
||||
// dependencies. If any are not found, generate some nice pretty errors.
|
||||
if ty == config::CrateTypeCdylib || ty == config::CrateTypeStaticlib ||
|
||||
(ty == config::CrateTypeExecutable && sess.crt_static() &&
|
||||
!sess.target.target.options.crt_static_allows_dylibs) {
|
||||
for &cnum in tcx.crates().iter() {
|
||||
if tcx.dep_kind(cnum).macros_only() { continue }
|
||||
let src = tcx.used_crate_source(cnum);
|
||||
if src.rlib.is_some() { continue }
|
||||
sess.err(&format!("crate `{}` required to be available in rlib format, \
|
||||
but was not found in this form",
|
||||
tcx.crate_name(cnum)));
|
||||
}
|
||||
return Vec::new();
|
||||
}
|
||||
}
|
||||
|
||||
let mut formats = FxHashMap();
|
||||
@ -236,10 +245,9 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
Linkage::Static => "rlib",
|
||||
_ => "dylib",
|
||||
};
|
||||
let name = tcx.crate_name(cnum);
|
||||
sess.err(&format!("crate `{}` required to be available in {}, \
|
||||
but it was not available in this form",
|
||||
name, kind));
|
||||
sess.err(&format!("crate `{}` required to be available in {} format, \
|
||||
but was not found in this form",
|
||||
tcx.crate_name(cnum), kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: dependency `cdylib_dep` not found in rlib format
|
||||
// error-pattern: crate `cdylib_dep` required to be available in rlib format, but was not found
|
||||
// aux-build:cdylib-dep.rs
|
||||
// ignore-musl
|
||||
// ignore-emscripten
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
// aux-build:rmeta_meta.rs
|
||||
// no-prefer-dynamic
|
||||
// error-pattern: crate `rmeta_meta` required to be available in rlib, but it was not available
|
||||
// error-pattern: crate `rmeta_meta` required to be available in rlib format, but was not found
|
||||
|
||||
// Check that building a non-metadata crate fails if a dependent crate is
|
||||
// metadata-only.
|
||||
|
Loading…
Reference in New Issue
Block a user