about summary refs log tree commit diff
path: root/compiler/rustc_metadata/src
diff options
context:
space:
mode:
authorDaniil Belov <70999565+BelovDV@users.noreply.github.com>2022-08-24 13:10:40 +0300
committerDaniil Belov <70999565+BelovDV@users.noreply.github.com>2022-09-12 16:45:03 +0300
commitffa83596fe216c19e9d58c8318786edd07d23d5f (patch)
treec4c1947168a229b527608a92095f38498a4755a2 /compiler/rustc_metadata/src
parent56e7678ca97e9740f7d09206f767d5bb676917f7 (diff)
downloadrust-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.rs6
-rw-r--r--compiler/rustc_metadata/src/lib.rs1
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs81
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,