diff options
| author | Daniil Belov <70999565+BelovDV@users.noreply.github.com> | 2022-08-24 13:10:40 +0300 |
|---|---|---|
| committer | Daniil Belov <70999565+BelovDV@users.noreply.github.com> | 2022-09-12 16:45:03 +0300 |
| commit | ffa83596fe216c19e9d58c8318786edd07d23d5f (patch) | |
| tree | c4c1947168a229b527608a92095f38498a4755a2 /compiler/rustc_metadata/src | |
| parent | 56e7678ca97e9740f7d09206f767d5bb676917f7 (diff) | |
| download | rust-ffa83596fe216c19e9d58c8318786edd07d23d5f.tar.gz rust-ffa83596fe216c19e9d58c8318786edd07d23d5f.zip | |
change rlib format to discern native dependencies
Diffstat (limited to 'compiler/rustc_metadata/src')
| -rw-r--r-- | compiler/rustc_metadata/src/errors.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/native_libs.rs | 81 |
3 files changed, 80 insertions, 8 deletions
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 1406ee914af..7d63fad3240 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -370,6 +370,12 @@ pub struct FailedWriteError { } #[derive(SessionDiagnostic)] +#[diag(metadata::missing_native_library)] +pub struct MissingNativeLibrary<'a> { + pub libname: &'a str, +} + +#[derive(SessionDiagnostic)] #[diag(metadata::failed_create_tempdir)] pub struct FailedCreateTempdir { pub err: Error, diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 8e0291fc3ad..57c5ec2f28c 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -44,4 +44,5 @@ pub mod fs; pub mod locator; pub use fs::{emit_metadata, METADATA_FILENAME}; +pub use native_libs::find_native_static_library; pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER}; diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 3acabc4e69c..cc33ad07db6 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -4,8 +4,10 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; +use rustc_session::config::CrateType; use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib, PeImportNameType}; use rustc_session::parse::feature_err; +use rustc_session::search_paths::PathKind; use rustc_session::utils::NativeLibKind; use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; @@ -16,13 +18,66 @@ use crate::errors::{ FrameworkOnlyWindows, ImportNameTypeForm, ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier, LibFrameworkApple, LinkCfgForm, LinkCfgSinglePredicate, LinkFrameworkApple, LinkKindForm, LinkModifiersForm, LinkNameForm, - LinkOrdinalRawDylib, LinkRequiresName, MultipleCfgs, MultipleImportNameType, - MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers, MultipleNamesInLink, - MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul, RenamingNoLink, - UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier, UnsupportedAbi, - UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic, + LinkOrdinalRawDylib, LinkRequiresName, MissingNativeLibrary, MultipleCfgs, + MultipleImportNameType, MultipleKindsInLink, MultipleLinkModifiers, MultipleModifiers, + MultipleNamesInLink, MultipleRenamings, MultipleWasmImport, NoLinkModOverride, RawDylibNoNul, + RenamingNoLink, UnexpectedLinkArg, UnknownImportNameType, UnknownLinkKind, UnknownLinkModifier, + UnsupportedAbi, UnsupportedAbiI686, WasmImportForm, WholeArchiveNeedsStatic, }; +use std::path::PathBuf; + +pub fn find_native_static_library( + name: &str, + verbatim: Option<bool>, + search_paths: &[PathBuf], + sess: &Session, +) -> PathBuf { + let verbatim = verbatim.unwrap_or(false); + // On Windows, static libraries sometimes show up as libfoo.a and other + // times show up as foo.lib + let oslibname = if verbatim { + name.to_string() + } else { + format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix) + }; + let unixlibname = format!("lib{}.a", name); + + for path in search_paths { + let test = path.join(&oslibname); + if test.exists() { + return test; + } + if oslibname != unixlibname { + let test = path.join(&unixlibname); + if test.exists() { + return test; + } + } + } + sess.emit_fatal(MissingNativeLibrary { libname: name }); +} + +fn find_bundled_library( + name: Option<Symbol>, + verbatim: Option<bool>, + kind: NativeLibKind, + sess: &Session, +) -> Option<Symbol> { + if sess.opts.unstable_opts.packed_bundled_libs && + sess.crate_types().iter().any(|ct| ct == &CrateType::Rlib || ct == &CrateType::Staticlib) && + let NativeLibKind::Static { bundle: Some(true) | None, .. } = kind { + find_native_static_library( + name.unwrap().as_str(), + verbatim, + &sess.target_filesearch(PathKind::Native).search_path_dirs(), + sess, + ).file_name().and_then(|s| s.to_str()).map(Symbol::intern) + } else { + None + } +} + pub(crate) fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLib> { let mut collector = Collector { tcx, libs: Vec::new() }; for id in tcx.hir().items() { @@ -341,9 +396,14 @@ impl<'tcx> Collector<'tcx> { Vec::new() } }; + + let name = name.map(|(name, _)| name); + let kind = kind.unwrap_or(NativeLibKind::Unspecified); + let filename = find_bundled_library(name, verbatim, kind, sess); self.libs.push(NativeLib { - name: name.map(|(name, _)| name), - kind: kind.unwrap_or(NativeLibKind::Unspecified), + name, + filename, + kind, cfg, foreign_module: Some(it.def_id.to_def_id()), wasm_import_module: wasm_import_module.map(|(name, _)| name), @@ -423,8 +483,13 @@ impl<'tcx> Collector<'tcx> { if existing.is_empty() { // Add if not found let new_name: Option<&str> = passed_lib.new_name.as_deref(); + let name = Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))); + let sess = self.tcx.sess; + let filename = + find_bundled_library(name, passed_lib.verbatim, passed_lib.kind, sess); self.libs.push(NativeLib { - name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))), + name, + filename, kind: passed_lib.kind, cfg: None, foreign_module: None, |
