change rlib format to discern native dependencies
This commit is contained in:
parent
56e7678ca9
commit
ffa83596fe
@ -1,44 +1,16 @@
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_session::cstore::DllImport;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
use object::read::archive::ArchiveFile;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub(super) fn find_library(
|
||||
name: &str,
|
||||
verbatim: bool,
|
||||
search_paths: &[PathBuf],
|
||||
sess: &Session,
|
||||
) -> PathBuf {
|
||||
// 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 {
|
||||
debug!("looking for {} inside {:?}", name, path);
|
||||
let test = path.join(&oslibname);
|
||||
if test.exists() {
|
||||
return test;
|
||||
}
|
||||
if oslibname != unixlibname {
|
||||
let test = path.join(&unixlibname);
|
||||
if test.exists() {
|
||||
return test;
|
||||
}
|
||||
}
|
||||
}
|
||||
sess.fatal(&format!(
|
||||
"could not find native static library `{}`, \
|
||||
perhaps an -L flag is missing?",
|
||||
name
|
||||
));
|
||||
}
|
||||
|
||||
pub trait ArchiveBuilderBuilder {
|
||||
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
|
||||
|
||||
@ -54,6 +26,36 @@ fn create_dll_import_lib(
|
||||
dll_imports: &[DllImport],
|
||||
tmpdir: &Path,
|
||||
) -> PathBuf;
|
||||
|
||||
fn extract_bundled_libs(
|
||||
&self,
|
||||
rlib: &Path,
|
||||
outdir: &Path,
|
||||
bundled_lib_file_names: &FxHashSet<Symbol>,
|
||||
) -> Result<(), String> {
|
||||
let message = |msg: &str, e: &dyn Display| format!("{} '{}': {}", msg, &rlib.display(), e);
|
||||
let archive_map = unsafe {
|
||||
Mmap::map(File::open(rlib).map_err(|e| message("failed to open file", &e))?)
|
||||
.map_err(|e| message("failed to mmap file", &e))?
|
||||
};
|
||||
let archive = ArchiveFile::parse(&*archive_map)
|
||||
.map_err(|e| message("failed to parse archive", &e))?;
|
||||
|
||||
for entry in archive.members() {
|
||||
let entry = entry.map_err(|e| message("failed to read entry", &e))?;
|
||||
let data = entry
|
||||
.data(&*archive_map)
|
||||
.map_err(|e| message("failed to get data from archive member", &e))?;
|
||||
let name = std::str::from_utf8(entry.name())
|
||||
.map_err(|e| message("failed to convert name", &e))?;
|
||||
if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
|
||||
continue; // We need to extract only native libraries.
|
||||
}
|
||||
std::fs::write(&outdir.join(&name), data)
|
||||
.map_err(|e| message("failed to write file", &e))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ArchiveBuilder<'a> {
|
||||
|
@ -1,11 +1,13 @@
|
||||
use rustc_arena::TypedArena;
|
||||
use rustc_ast::CRATE_NODE_ID;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||
use rustc_errors::{ErrorGuaranteed, Handler};
|
||||
use rustc_fs_util::fix_windows_verbatim_for_gcc;
|
||||
use rustc_hir::def_id::CrateNum;
|
||||
use rustc_metadata::find_native_static_library;
|
||||
use rustc_metadata::fs::{emit_metadata, METADATA_FILENAME};
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
use rustc_middle::middle::exported_symbols::SymbolExportKind;
|
||||
@ -24,7 +26,7 @@
|
||||
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
|
||||
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
|
||||
|
||||
use super::archive::{find_library, ArchiveBuilder, ArchiveBuilderBuilder};
|
||||
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
|
||||
use super::command::Command;
|
||||
use super::linker::{self, Linker};
|
||||
use super::metadata::{create_rmeta_file, MetadataPosition};
|
||||
@ -307,6 +309,9 @@ fn link_rlib<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
// Used if packed_bundled_libs flag enabled.
|
||||
let mut packed_bundled_libs = Vec::new();
|
||||
|
||||
// Note that in this loop we are ignoring the value of `lib.cfg`. That is,
|
||||
// we may not be configured to actually include a static library if we're
|
||||
// adding it here. That's because later when we consume this rlib we'll
|
||||
@ -325,6 +330,8 @@ fn link_rlib<'a>(
|
||||
// metadata of the rlib we're generating somehow.
|
||||
for lib in codegen_results.crate_info.used_libraries.iter() {
|
||||
match lib.kind {
|
||||
NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
|
||||
if flavor == RlibFlavor::Normal && sess.opts.unstable_opts.packed_bundled_libs => {}
|
||||
NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
|
||||
if flavor == RlibFlavor::Normal =>
|
||||
{
|
||||
@ -348,7 +355,16 @@ fn link_rlib<'a>(
|
||||
}
|
||||
if let Some(name) = lib.name {
|
||||
let location =
|
||||
find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
|
||||
find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
|
||||
if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
|
||||
packed_bundled_libs.push(find_native_static_library(
|
||||
lib.filename.unwrap().as_str(),
|
||||
Some(true),
|
||||
&lib_search_paths,
|
||||
sess,
|
||||
));
|
||||
continue;
|
||||
}
|
||||
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
|
||||
sess.fatal(&format!(
|
||||
"failed to add native library {}: {}",
|
||||
@ -403,6 +419,12 @@ fn link_rlib<'a>(
|
||||
ab.add_file(&trailing_metadata);
|
||||
}
|
||||
|
||||
// Add all bundled static native library dependencies.
|
||||
// Archives added to the end of .rlib archive, see comment above for the reason.
|
||||
for lib in packed_bundled_libs {
|
||||
ab.add_file(&lib)
|
||||
}
|
||||
|
||||
return Ok(ab);
|
||||
}
|
||||
|
||||
@ -2350,7 +2372,15 @@ fn add_upstream_rust_crates<'a>(
|
||||
let src = &codegen_results.crate_info.used_crate_source[&cnum];
|
||||
match data[cnum.as_usize() - 1] {
|
||||
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
|
||||
add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
|
||||
add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&Default::default(),
|
||||
);
|
||||
}
|
||||
// compiler-builtins are always placed last to ensure that they're
|
||||
// linked correctly.
|
||||
@ -2360,7 +2390,23 @@ fn add_upstream_rust_crates<'a>(
|
||||
}
|
||||
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
|
||||
Linkage::Static => {
|
||||
add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
|
||||
let bundled_libs = if sess.opts.unstable_opts.packed_bundled_libs {
|
||||
codegen_results.crate_info.native_libraries[&cnum]
|
||||
.iter()
|
||||
.filter_map(|lib| lib.filename)
|
||||
.collect::<FxHashSet<_>>()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&bundled_libs,
|
||||
);
|
||||
|
||||
// Link static native libs with "-bundle" modifier only if the crate they originate from
|
||||
// is being linked statically to the current crate. If it's linked dynamically
|
||||
@ -2371,6 +2417,14 @@ fn add_upstream_rust_crates<'a>(
|
||||
// external build system already has the native dependencies defined, and it
|
||||
// will provide them to the linker itself.
|
||||
if sess.opts.unstable_opts.link_native_libraries {
|
||||
if sess.opts.unstable_opts.packed_bundled_libs {
|
||||
// If rlib contains native libs as archives, unpack them to tmpdir.
|
||||
let rlib = &src.rlib.as_ref().unwrap().0;
|
||||
archive_builder_builder
|
||||
.extract_bundled_libs(rlib, tmpdir, &bundled_libs)
|
||||
.unwrap_or_else(|e| sess.fatal(e));
|
||||
}
|
||||
|
||||
let mut last = (None, NativeLibKind::Unspecified, None);
|
||||
for lib in &codegen_results.crate_info.native_libraries[&cnum] {
|
||||
let Some(name) = lib.name else {
|
||||
@ -2420,10 +2474,17 @@ fn add_upstream_rust_crates<'a>(
|
||||
| NativeLibKind::Framework { .. }
|
||||
| NativeLibKind::Unspecified
|
||||
| NativeLibKind::RawDylib => {}
|
||||
NativeLibKind::Static {
|
||||
bundle: Some(true) | None,
|
||||
whole_archive: _,
|
||||
} => {}
|
||||
NativeLibKind::Static { bundle: Some(true) | None, whole_archive } => {
|
||||
if sess.opts.unstable_opts.packed_bundled_libs {
|
||||
// If rlib contains native libs as archives, they are unpacked to tmpdir.
|
||||
let path = tmpdir.join(lib.filename.unwrap().as_str());
|
||||
if whole_archive == Some(true) {
|
||||
cmd.link_whole_rlib(&path);
|
||||
} else {
|
||||
cmd.link_rlib(&path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2438,7 +2499,15 @@ fn add_upstream_rust_crates<'a>(
|
||||
// was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
|
||||
// is used)
|
||||
if let Some(cnum) = compiler_builtins {
|
||||
add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
|
||||
add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&Default::default(),
|
||||
);
|
||||
}
|
||||
|
||||
// Converts a library file-stem into a cc -l argument
|
||||
@ -2471,6 +2540,7 @@ fn add_static_crate<'a>(
|
||||
codegen_results: &CodegenResults,
|
||||
tmpdir: &Path,
|
||||
cnum: CrateNum,
|
||||
bundled_lib_file_names: &FxHashSet<Symbol>,
|
||||
) {
|
||||
let src = &codegen_results.crate_info.used_crate_source[&cnum];
|
||||
let cratepath = &src.rlib.as_ref().unwrap().0;
|
||||
@ -2499,6 +2569,7 @@ fn add_static_crate<'a>(
|
||||
let dst = tmpdir.join(cratepath.file_name().unwrap());
|
||||
let name = cratepath.file_name().unwrap().to_str().unwrap();
|
||||
let name = &name[3..name.len() - 5]; // chop off lib/.rlib
|
||||
let bundled_lib_file_names = bundled_lib_file_names.clone();
|
||||
|
||||
sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| {
|
||||
let canonical_name = name.replace('-', "_");
|
||||
@ -2532,6 +2603,15 @@ fn add_static_crate<'a>(
|
||||
let skip_because_lto =
|
||||
upstream_rust_objects_already_included && is_rust_object && is_builtins;
|
||||
|
||||
// We skip native libraries because:
|
||||
// 1. This native libraries won't be used from the generated rlib,
|
||||
// so we can throw them away to avoid the copying work.
|
||||
// 2. We can't allow it to be a single remaining entry in archive
|
||||
// as some linkers may complain on that.
|
||||
if bundled_lib_file_names.contains(&Symbol::intern(f)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if skip_because_cfg_say_so || skip_because_lto {
|
||||
return true;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
use super::archive;
|
||||
use super::command::Command;
|
||||
use super::symbol_export;
|
||||
use rustc_span::symbol::sym;
|
||||
@ -11,6 +10,7 @@
|
||||
use std::{env, mem, str};
|
||||
|
||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||
use rustc_metadata::find_native_static_library;
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
@ -514,7 +514,7 @@ fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, search_path: &[Pat
|
||||
// -force_load is the macOS equivalent of --whole-archive, but it
|
||||
// involves passing the full path to the library to link.
|
||||
self.linker_arg("-force_load");
|
||||
let lib = archive::find_library(lib, verbatim, search_path, &self.sess);
|
||||
let lib = find_native_static_library(lib, Some(verbatim), search_path, &self.sess);
|
||||
self.linker_arg(&lib);
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ pub struct MemFlags: u8 {
|
||||
pub struct NativeLib {
|
||||
pub kind: NativeLibKind,
|
||||
pub name: Option<Symbol>,
|
||||
pub filename: Option<Symbol>,
|
||||
pub cfg: Option<ast::MetaItem>,
|
||||
pub verbatim: Option<bool>,
|
||||
pub dll_imports: Vec<cstore::DllImport>,
|
||||
@ -121,6 +122,7 @@ impl From<&cstore::NativeLib> for NativeLib {
|
||||
fn from(lib: &cstore::NativeLib) -> Self {
|
||||
NativeLib {
|
||||
kind: lib.kind,
|
||||
filename: lib.filename,
|
||||
name: lib.name,
|
||||
cfg: lib.cfg.clone(),
|
||||
verbatim: lib.verbatim,
|
||||
|
@ -162,6 +162,9 @@ metadata_no_transitive_needs_dep =
|
||||
metadata_failed_write_error =
|
||||
failed to write {$filename}: {$err}
|
||||
|
||||
metadata_missing_native_library =
|
||||
could not find native static library `{$libname}`, perhaps an -L flag is missing?
|
||||
|
||||
metadata_failed_create_tempdir =
|
||||
couldn't create a temp dir: {$err}
|
||||
|
||||
|
@ -765,6 +765,7 @@ macro_rules! tracked {
|
||||
tracked!(no_profiler_runtime, true);
|
||||
tracked!(oom, OomStrategy::Panic);
|
||||
tracked!(osx_rpath_install_name, true);
|
||||
tracked!(packed_bundled_libs, true);
|
||||
tracked!(panic_abort_tests, true);
|
||||
tracked!(panic_in_drop, PanicStrategy::Abort);
|
||||
tracked!(pick_stable_methods_before_any_unstable, false);
|
||||
|
@ -369,6 +369,12 @@ pub struct FailedWriteError {
|
||||
pub err: Error,
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
@ -44,4 +44,5 @@
|
||||
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};
|
||||
|
@ -4,8 +4,10 @@
|
||||
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 @@
|
||||
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 @@ fn process_item(&mut self, id: rustc_hir::ItemId) {
|
||||
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 @@ fn process_command_line(&mut self) {
|
||||
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,
|
||||
|
@ -68,6 +68,8 @@ pub enum LinkagePreference {
|
||||
pub struct NativeLib {
|
||||
pub kind: NativeLibKind,
|
||||
pub name: Option<Symbol>,
|
||||
/// If packed_bundled_libs enabled, actual filename of library is stored.
|
||||
pub filename: Option<Symbol>,
|
||||
pub cfg: Option<ast::MetaItem>,
|
||||
pub foreign_module: Option<DefId>,
|
||||
pub wasm_import_module: Option<Symbol>,
|
||||
|
@ -1439,6 +1439,8 @@ pub(crate) fn parse_proc_macro_execution_strategy(
|
||||
"pass `-install_name @rpath/...` to the macOS linker (default: no)"),
|
||||
diagnostic_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
|
||||
"set the current output width for diagnostic truncation"),
|
||||
packed_bundled_libs: bool = (false, parse_bool, [TRACKED],
|
||||
"change rlib format to store native libraries as archives"),
|
||||
panic_abort_tests: bool = (false, parse_bool, [TRACKED],
|
||||
"support compiling tests with panic=abort (default: no)"),
|
||||
panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
|
||||
|
22
src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
Normal file
22
src/test/run-make/rlib-format-packed-bundled-libs-2/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
-include ../../run-make-fulldeps/tools.mk
|
||||
|
||||
# ignore-cross-compile
|
||||
|
||||
# Make sure -Zpacked_bundled_libs is compatible with verbatim.
|
||||
|
||||
# We're using the llvm-nm instead of the system nm to ensure it is compatible
|
||||
# with the LLVM bitcode generated by rustc.
|
||||
NM = "$(LLVM_BIN_DIR)"/llvm-nm
|
||||
|
||||
all:
|
||||
# Build strange-named dep.
|
||||
$(RUSTC) native_dep.rs --crate-type=staticlib -o $(TMPDIR)/native_dep.ext
|
||||
|
||||
$(RUSTC) rust_dep.rs --crate-type=rlib -Zpacked_bundled_libs
|
||||
$(NM) $(TMPDIR)/librust_dep.rlib | $(CGREP) -e "U.*native_f1"
|
||||
$(AR) t $(TMPDIR)/librust_dep.rlib | $(CGREP) "native_dep.ext"
|
||||
|
||||
# Make sure compiler doesn't use files, that it shouldn't know about.
|
||||
rm $(TMPDIR)/native_dep.ext
|
||||
|
||||
$(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep.rlib -Zpacked_bundled_libs
|
@ -0,0 +1,5 @@
|
||||
extern crate rust_dep;
|
||||
|
||||
pub fn main() {
|
||||
rust_dep::rust_dep();
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub fn native_f1() -> i32 {
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#![feature(native_link_modifiers_verbatim)]
|
||||
#[link(name = "native_dep.ext", kind = "static", modifiers = "+verbatim")]
|
||||
extern "C" {
|
||||
fn native_f1() -> i32;
|
||||
}
|
||||
|
||||
pub fn rust_dep() {
|
||||
unsafe {
|
||||
assert!(native_f1() == 1);
|
||||
}
|
||||
}
|
34
src/test/run-make/rlib-format-packed-bundled-libs/Makefile
Normal file
34
src/test/run-make/rlib-format-packed-bundled-libs/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
-include ../../run-make-fulldeps/tools.mk
|
||||
|
||||
# ignore-cross-compile
|
||||
|
||||
# Make sure rlib format with -Zpacked_bundled_libs is correct.
|
||||
|
||||
# We're using the llvm-nm instead of the system nm to ensure it is compatible
|
||||
# with the LLVM bitcode generated by rustc.
|
||||
NM = "$(LLVM_BIN_DIR)"/llvm-nm
|
||||
|
||||
all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3)
|
||||
$(RUSTC) rust_dep_up.rs --crate-type=rlib -Zpacked_bundled_libs
|
||||
$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f2"
|
||||
$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "U.*native_f3"
|
||||
$(NM) $(TMPDIR)/librust_dep_up.rlib | $(CGREP) -e "T.*rust_dep_up"
|
||||
$(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_2"
|
||||
$(AR) t $(TMPDIR)/librust_dep_up.rlib | $(CGREP) "native_dep_3"
|
||||
$(RUSTC) rust_dep_local.rs --extern rlib=$(TMPDIR)/librust_dep_up.rlib -Zpacked_bundled_libs --crate-type=rlib
|
||||
$(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "U.*native_f1"
|
||||
$(NM) $(TMPDIR)/librust_dep_local.rlib | $(CGREP) -e "T.*rust_dep_local"
|
||||
$(AR) t $(TMPDIR)/librust_dep_local.rlib | $(CGREP) "native_dep_1"
|
||||
|
||||
# Make sure compiler doesn't use files, that it shouldn't know about.
|
||||
rm $(TMPDIR)/*native_dep_*
|
||||
|
||||
$(RUSTC) main.rs --extern lib=$(TMPDIR)/librust_dep_local.rlib -o $(TMPDIR)/main.exe -Zpacked_bundled_libs --print link-args | $(CGREP) -e "native_dep_1.*native_dep_2.*native_dep_3"
|
||||
|
||||
ifndef IS_MSVC
|
||||
$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f1"
|
||||
$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f2"
|
||||
$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*native_f3"
|
||||
$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_local"
|
||||
$(NM) $(TMPDIR)/main.exe | $(CGREP) -e "T.*rust_dep_up"
|
||||
endif
|
@ -0,0 +1,4 @@
|
||||
extern crate rust_dep_local;
|
||||
pub fn main() {
|
||||
rust_dep_local::rust_dep_local();
|
||||
}
|
@ -0,0 +1 @@
|
||||
int native_f1() { return 1; }
|
@ -0,0 +1 @@
|
||||
int native_f2() { return 2; }
|
@ -0,0 +1 @@
|
||||
int native_f3() { return 3; }
|
@ -0,0 +1,13 @@
|
||||
#[link(name = "native_dep_1", kind = "static")]
|
||||
extern "C" {
|
||||
fn native_f1() -> i32;
|
||||
}
|
||||
|
||||
extern crate rust_dep_up;
|
||||
|
||||
pub fn rust_dep_local() {
|
||||
unsafe {
|
||||
assert!(native_f1() == 1);
|
||||
}
|
||||
rust_dep_up::rust_dep_up();
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
#[link(name = "native_dep_2", kind = "static")]
|
||||
#[link(name = "native_dep_3", kind = "static")]
|
||||
extern "C" {
|
||||
fn native_f2() -> i32;
|
||||
fn native_f3() -> i32;
|
||||
}
|
||||
|
||||
pub fn rust_dep_up() {
|
||||
unsafe {
|
||||
assert!(native_f2() == 2);
|
||||
assert!(native_f3() == 3);
|
||||
}
|
||||
}
|
@ -97,6 +97,7 @@
|
||||
-Z oom=val -- panic strategy for out-of-memory handling
|
||||
-Z osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no)
|
||||
-Z diagnostic-width=val -- set the current output width for diagnostic truncation
|
||||
-Z packed-bundled-libs=val -- change rlib format to store native libraries as archives
|
||||
-Z panic-abort-tests=val -- support compiling tests with panic=abort (default: no)
|
||||
-Z panic-in-drop=val -- panic strategy for panics in drops
|
||||
-Z parse-only=val -- parse only; do not compile, assemble, or link (default: no)
|
||||
|
Loading…
Reference in New Issue
Block a user