diff options
| author | Samuel Holland <samuel@sholland.org> | 2017-09-02 18:15:57 -0500 |
|---|---|---|
| committer | Samuel Holland <samuel@sholland.org> | 2017-09-18 22:31:57 -0500 |
| commit | 779041cd5a27c7b775c9ed45948a1343a3f25f04 (patch) | |
| tree | 668811806b75912feedcfff697085979f7906d16 /src/librustc | |
| parent | 0701b37d97d08da7074ece7a7dcb4449498f4bfa (diff) | |
| download | rust-779041cd5a27c7b775c9ed45948a1343a3f25f04.tar.gz rust-779041cd5a27c7b775c9ed45948a1343a3f25f04.zip | |
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`.
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/middle/dependency_format.rs | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 1c7d0b76a64..41fcce27bc5 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -112,26 +112,51 @@ 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; - } - } + 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 => 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 => 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; - } + 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; + } + + // 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); @@ -141,23 +166,6 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } return Vec::new(); } - - // 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 => { - 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 => {}, } let mut formats = FxHashMap(); |
