From bc019dfb39bab6979009bb89ecc2d3af460b3c37 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Wed, 23 Nov 2016 16:09:51 -0800 Subject: [PATCH 1/9] Emit 'dllimport' attribute for dylib foreign items on Windows. --- src/librustc/middle/cstore.rs | 11 +-- src/librustc_metadata/creader.rs | 78 +++++++++++++------ src/librustc_metadata/cstore.rs | 21 +++-- src/librustc_metadata/cstore_impl.rs | 14 +++- src/librustc_metadata/decoder.rs | 17 +++- src/librustc_trans/base.rs | 3 +- src/librustc_trans/callee.rs | 6 +- src/librustc_trans/consts.rs | 13 +++- .../codegen/dllimports/auxiliary/dummy.rs | 16 ++++ .../codegen/dllimports/auxiliary/wrapper.rs | 24 ++++++ src/test/codegen/dllimports/main.rs | 63 +++++++++++++++ 11 files changed, 220 insertions(+), 46 deletions(-) create mode 100644 src/test/codegen/dllimports/auxiliary/dummy.rs create mode 100644 src/test/codegen/dllimports/auxiliary/wrapper.rs create mode 100644 src/test/codegen/dllimports/main.rs diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 484e2f1535e7a..9275c01c8b16f 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -131,6 +131,7 @@ pub struct NativeLibrary { pub kind: NativeLibraryKind, pub name: Symbol, pub cfg: Option, + pub foreign_items: Vec, } /// The data we save and restore about an inlined item or method. This is not @@ -305,7 +306,8 @@ pub trait CrateStore<'tcx> { fn is_defaulted_trait(&self, did: DefId) -> bool; fn is_default_impl(&self, impl_did: DefId) -> bool; fn is_foreign_item(&self, did: DefId) -> bool; - fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool; + fn is_dllimport_foreign_item(&self, def: DefId) -> bool; + fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool; // crate metadata fn dylib_dependency_formats(&self, cnum: CrateNum) @@ -462,7 +464,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") } fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") } fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") } - fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false } + fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false } + fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false } // crate metadata fn dylib_dependency_formats(&self, cnum: CrateNum) @@ -526,9 +529,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { // This is basically a 1-based range of ints, which is a little // silly - I may fix that. fn crates(&self) -> Vec { vec![] } - fn used_libraries(&self) -> Vec { - vec![] - } + fn used_libraries(&self) -> Vec { vec![] } fn used_link_args(&self) -> Vec { vec![] } // utility functions diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 2c266068fe814..436b1b3159f8a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -52,7 +52,7 @@ pub struct CrateLoader<'a> { pub sess: &'a Session, cstore: &'a CStore, next_crate_num: CrateNum, - foreign_item_map: FxHashMap>, + foreign_item_map: FxHashMap>, local_crate_name: Symbol, } @@ -310,6 +310,7 @@ impl<'a> CrateLoader<'a> { rlib: rlib, rmeta: rmeta, }, + dllimport_foreign_items: RefCell::new(None), }); self.cstore.set_crate_data(cnum, cmeta.clone()); @@ -640,18 +641,36 @@ impl<'a> CrateLoader<'a> { } } - fn register_statically_included_foreign_items(&mut self) { + fn get_foreign_items_of_kind(&self, kind: cstore::NativeLibraryKind) -> Vec { + let mut items = vec![]; let libs = self.cstore.get_used_libraries(); + for lib in libs.borrow().iter() { + if lib.kind == kind { + items.extend(&lib.foreign_items); + } + } for (foreign_lib, list) in self.foreign_item_map.iter() { - let is_static = libs.borrow().iter().any(|lib| { - lib.name == &**foreign_lib && lib.kind == cstore::NativeStatic + let kind_matches = libs.borrow().iter().any(|lib| { + lib.name == &**foreign_lib && lib.kind == kind }); - if is_static { - for id in list { - self.cstore.add_statically_included_foreign_item(*id); - } + if kind_matches { + items.extend(list) } } + items + } + + fn register_statically_included_foreign_items(&mut self) { + for id in self.get_foreign_items_of_kind(cstore::NativeStatic) { + self.cstore.add_statically_included_foreign_item(id); + } + } + + fn register_dllimport_foreign_items(&mut self) { + let mut dllimports = self.cstore.dllimport_foreign_items.borrow_mut(); + for id in self.get_foreign_items_of_kind(cstore::NativeUnknown) { + dllimports.insert(id); + } } fn inject_panic_runtime(&mut self, krate: &ast::Crate) { @@ -861,7 +880,8 @@ impl<'a> CrateLoader<'a> { } } - fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) { + fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod, + definitions: &Definitions) { if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic { return; } @@ -912,10 +932,14 @@ impl<'a> CrateLoader<'a> { let cfg = cfg.map(|list| { list[0].meta_item().unwrap().clone() }); + let foreign_items = fm.items.iter() + .map(|it| definitions.opt_def_index(it.id).unwrap()) + .collect(); let lib = NativeLibrary { name: n, kind: kind, cfg: cfg, + foreign_items: foreign_items, }; register_native_lib(self.sess, self.cstore, Some(m.span), lib); } @@ -928,7 +952,7 @@ impl<'a> CrateLoader<'a> { }; let list = self.foreign_item_map.entry(lib_name.to_string()) .or_insert(Vec::new()); - list.extend(fm.items.iter().map(|it| it.id)); + list.extend(fm.items.iter().map(|it| definitions.opt_def_index(it.id).unwrap())); } } } @@ -947,30 +971,34 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { name: Symbol::intern(name), kind: kind, cfg: None, + foreign_items: Vec::new(), }; register_native_lib(self.sess, self.cstore, None, lib); } self.register_statically_included_foreign_items(); + self.register_dllimport_foreign_items(); } fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) { match item.node { - ast::ItemKind::ExternCrate(_) => {} - ast::ItemKind::ForeignMod(ref fm) => return self.process_foreign_mod(item, fm), - _ => return, - } - - let info = self.extract_crate_info(item).unwrap(); - let (cnum, ..) = self.resolve_crate( - &None, info.ident, info.name, None, item.span, PathKind::Crate, info.dep_kind, - ); + ast::ItemKind::ForeignMod(ref fm) => { + self.process_foreign_mod(item, fm, definitions) + }, + ast::ItemKind::ExternCrate(_) => { + let info = self.extract_crate_info(item).unwrap(); + let (cnum, ..) = self.resolve_crate( + &None, info.ident, info.name, None, item.span, PathKind::Crate, info.dep_kind, + ); - let def_id = definitions.opt_local_def_id(item.id).unwrap(); - let len = definitions.def_path(def_id.index).data.len(); + let def_id = definitions.opt_local_def_id(item.id).unwrap(); + let len = definitions.def_path(def_id.index).data.len(); - let extern_crate = - ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len }; - self.update_extern_crate(cnum, extern_crate, &mut FxHashSet()); - self.cstore.add_extern_mod_stmt_cnum(info.id, cnum); + let extern_crate = + ExternCrate { def_id: def_id, span: item.span, direct: true, path_len: len }; + self.update_extern_crate(cnum, extern_crate, &mut FxHashSet()); + self.cstore.add_extern_mod_stmt_cnum(info.id, cnum); + } + _ => {} + } } } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 73e03a4519664..279ef5bfb7276 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -15,13 +15,13 @@ use locator; use schema; use rustc::dep_graph::DepGraph; -use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefIndex, DefId}; use rustc::hir::map::DefKey; use rustc::hir::svh::Svh; use rustc::middle::cstore::{DepKind, ExternCrate}; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; -use rustc::util::nodemap::{FxHashMap, NodeMap, NodeSet, DefIdMap}; +use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap, DefIdMap}; use std::cell::{RefCell, Cell}; use std::rc::Rc; @@ -31,7 +31,7 @@ use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; use syntax_pos; -pub use rustc::middle::cstore::{NativeLibrary, LinkagePreference}; +pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference}; pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown}; pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource}; @@ -84,6 +84,8 @@ pub struct CrateMetadata { pub source: CrateSource, pub proc_macros: Option)>>, + // Foreign items imported from a dylib (Windows only) + pub dllimport_foreign_items: RefCell>>, } pub struct CachedInlinedItem { @@ -100,7 +102,8 @@ pub struct CStore { extern_mod_crate_map: RefCell>, used_libraries: RefCell>, used_link_args: RefCell>, - statically_included_foreign_items: RefCell, + statically_included_foreign_items: RefCell>, + pub dllimport_foreign_items: RefCell>, pub inlined_item_cache: RefCell>>, pub defid_for_inlined_node: RefCell>, pub visible_parent_map: RefCell>, @@ -114,7 +117,8 @@ impl CStore { extern_mod_crate_map: RefCell::new(FxHashMap()), used_libraries: RefCell::new(Vec::new()), used_link_args: RefCell::new(Vec::new()), - statically_included_foreign_items: RefCell::new(NodeSet()), + statically_included_foreign_items: RefCell::new(FxHashSet()), + dllimport_foreign_items: RefCell::new(FxHashSet()), visible_parent_map: RefCell::new(FxHashMap()), inlined_item_cache: RefCell::new(FxHashMap()), defid_for_inlined_node: RefCell::new(FxHashMap()), @@ -246,12 +250,13 @@ impl CStore { self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum); } - pub fn add_statically_included_foreign_item(&self, id: ast::NodeId) { + pub fn add_statically_included_foreign_item(&self, id: DefIndex) { self.statically_included_foreign_items.borrow_mut().insert(id); } - pub fn do_is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { - self.statically_included_foreign_items.borrow().contains(&id) + pub fn do_is_statically_included_foreign_item(&self, def_id: DefId) -> bool { + assert!(def_id.krate == LOCAL_CRATE); + self.statically_included_foreign_items.borrow().contains(&def_id.index) } pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index c41c3afb83ed5..e3193d322bf3b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -19,7 +19,7 @@ use rustc::hir::def::{self, Def}; use rustc::middle::lang_items; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; +use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::dep_graph::DepNode; use rustc::hir::map as hir_map; @@ -217,9 +217,17 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(did.krate).is_foreign_item(did.index) } - fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool + fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { - self.do_is_statically_included_foreign_item(id) + self.do_is_statically_included_foreign_item(def_id) + } + + fn is_dllimport_foreign_item(&self, def_id: DefId) -> bool { + if def_id.krate == LOCAL_CRATE { + self.dllimport_foreign_items.borrow().contains(&def_id.index) + } else { + self.get_crate_data(def_id.krate).is_dllimport_foreign_item(def_id.index) + } } fn dylib_dependency_formats(&self, cnum: CrateNum) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 308cd6a83db7e..f8f80a60c1696 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -11,13 +11,13 @@ // Decoding metadata from a single crate's metadata use astencode::decode_inlined_item; -use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; +use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, NativeLibraryKind}; use index::Index; use schema::*; use rustc::hir::map as hir_map; use rustc::hir::map::{DefKey, DefPathData}; -use rustc::util::nodemap::FxHashMap; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc::hir; use rustc::hir::intravisit::IdRange; @@ -36,6 +36,7 @@ use rustc::mir::Mir; use std::borrow::Cow; use std::cell::Ref; use std::io; +use std::iter::FromIterator; use std::mem; use std::str; use std::u32; @@ -1087,6 +1088,18 @@ impl<'a, 'tcx> CrateMetadata { } } + pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool { + if self.dllimport_foreign_items.borrow().is_none() { + *self.dllimport_foreign_items.borrow_mut() = Some(FxHashSet::from_iter( + self.get_native_libraries().iter() + .filter(|lib| lib.kind == NativeLibraryKind::NativeUnknown) + .flat_map(|lib| &lib.foreign_items) + .map(|id| *id) + )); + } + self.dllimport_foreign_items.borrow().as_ref().unwrap().contains(&id) + } + pub fn is_defaulted_trait(&self, trait_id: DefIndex) -> bool { match self.entry(trait_id).kind { EntryKind::Trait(data) => data.decode(self).has_default_impl, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index f1126e6fd256c..6a9c81dfd5d5a 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1498,7 +1498,8 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet { // let it through if it's included statically. match tcx.map.get(id) { hir_map::NodeForeignItem(..) => { - tcx.sess.cstore.is_statically_included_foreign_item(id) + let def_id = tcx.map.local_def_id(id); + tcx.sess.cstore.is_statically_included_foreign_item(def_id) } // Only consider nodes that actually have exported symbols. diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index df56e27128c7e..9fd61caf6fe53 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -629,7 +629,11 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage); } } - + if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) { + unsafe { + llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); + } + } llfn }; diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 4186721c122ac..730a4025a59a8 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -191,7 +191,12 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { llvm::set_thread_local(g, true); } } - if ccx.use_dll_storage_attrs() { + if ccx.use_dll_storage_attrs() && !ccx.sess().cstore.is_foreign_item(def_id) { + // This item is external but not foreign, i.e. it originates from an external Rust + // crate. Since we don't know whether this crate will be linked dynamically or + // statically in the final application, we always mark such symbols as 'dllimport'. + // If final linkage happens to be static, we rely on compiler-emitted __imp_ stubs to + // make things work. unsafe { llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); } @@ -199,6 +204,12 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { g }; + if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) { + // For foreign (native) libs we know the exact storage type to use. + unsafe { + llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); + } + } ccx.instances().borrow_mut().insert(instance, g); ccx.statics().borrow_mut().insert(g, def_id); g diff --git a/src/test/codegen/dllimports/auxiliary/dummy.rs b/src/test/codegen/dllimports/auxiliary/dummy.rs new file mode 100644 index 0000000000000..06001c6b01426 --- /dev/null +++ b/src/test/codegen/dllimports/auxiliary/dummy.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +#![crate_type = "staticlib"] + +// Since codegen tests don't actually perform linking, this library doesn't need to export +// any symbols. It's here just to satisfy the compiler looking for a .lib file when processing +// #[link(...)] attributes in wrapper.rs. diff --git a/src/test/codegen/dllimports/auxiliary/wrapper.rs b/src/test/codegen/dllimports/auxiliary/wrapper.rs new file mode 100644 index 0000000000000..c03f88092e583 --- /dev/null +++ b/src/test/codegen/dllimports/auxiliary/wrapper.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +#![crate_type = "rlib"] + +#[link(name = "dummy", kind="dylib")] +extern "C" { + pub fn dylib_func2(x: i32) -> i32; + pub static dylib_global2: i32; +} + +#[link(name = "dummy", kind="static")] +extern "C" { + pub fn static_func2(x: i32) -> i32; + pub static static_global2: i32; +} diff --git a/src/test/codegen/dllimports/main.rs b/src/test/codegen/dllimports/main.rs new file mode 100644 index 0000000000000..140d95fb7be2d --- /dev/null +++ b/src/test/codegen/dllimports/main.rs @@ -0,0 +1,63 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test is for Windows only. +// ignore-android +// ignore-bitrig +// ignore-macos +// ignore-dragonfly +// ignore-freebsd +// ignore-haiku +// ignore-ios +// ignore-linux +// ignore-netbsd +// ignore-openbsd +// ignore-solaris +// ignore-emscripten + +// aux-build:dummy.rs +// aux-build:wrapper.rs + +extern crate wrapper; + +// Check that external symbols coming from foreign dylibs are adorned with 'dllimport', +// whereas symbols coming from foreign staticlibs are not. (RFC-1717) + +// CHECK: @dylib_global1 = external dllimport local_unnamed_addr global i32 +// CHECK: @dylib_global2 = external dllimport local_unnamed_addr global i32 +// CHECK: @static_global1 = external local_unnamed_addr global i32 +// CHECK: @static_global2 = external local_unnamed_addr global i32 + +// CHECK: declare dllimport i32 @dylib_func1(i32) +// CHECK: declare dllimport i32 @dylib_func2(i32) +// CHECK: declare i32 @static_func1(i32) +// CHECK: declare i32 @static_func2(i32) + +#[link(name = "dummy", kind="dylib")] +extern "C" { + pub fn dylib_func1(x: i32) -> i32; + pub static dylib_global1: i32; +} + +#[link(name = "dummy", kind="static")] +extern "C" { + pub fn static_func1(x: i32) -> i32; + pub static static_global1: i32; +} + +fn main() { + unsafe { + dylib_func1(dylib_global1); + wrapper::dylib_func2(wrapper::dylib_global2); + + static_func1(static_global1); + wrapper::static_func2(wrapper::static_global2); + } +} From 4508e8a847c57b2eb8c7bf7e318c49b7cd327cb7 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Wed, 23 Nov 2016 16:09:51 -0800 Subject: [PATCH 2/9] Fix rust_test_helpers linkage. --- src/test/run-pass/abi-sysv64-arg-passing.rs | 2 +- src/test/run-pass/anon-extern-mod.rs | 2 +- src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs | 2 +- src/test/run-pass/auxiliary/extern-crosscrate-source.rs | 2 +- src/test/run-pass/auxiliary/foreign_lib.rs | 2 +- src/test/run-pass/c-stack-as-value.rs | 2 +- src/test/run-pass/cabi-int-widening.rs | 2 +- src/test/run-pass/extern-call-deep.rs | 2 +- src/test/run-pass/extern-call-deep2.rs | 2 +- src/test/run-pass/extern-call-indirect.rs | 2 +- src/test/run-pass/extern-call-scrub.rs | 2 +- src/test/run-pass/extern-pass-TwoU16s.rs | 2 +- src/test/run-pass/extern-pass-TwoU32s.rs | 2 +- src/test/run-pass/extern-pass-TwoU64s.rs | 2 +- src/test/run-pass/extern-pass-TwoU8s.rs | 2 +- src/test/run-pass/extern-pass-char.rs | 2 +- src/test/run-pass/extern-pass-double.rs | 2 +- src/test/run-pass/extern-pass-empty.rs | 2 +- src/test/run-pass/extern-pass-u32.rs | 2 +- src/test/run-pass/extern-pass-u64.rs | 2 +- src/test/run-pass/extern-return-TwoU16s.rs | 2 +- src/test/run-pass/extern-return-TwoU32s.rs | 2 +- src/test/run-pass/extern-return-TwoU64s.rs | 2 +- src/test/run-pass/extern-return-TwoU8s.rs | 2 +- src/test/run-pass/foreign-call-no-runtime.rs | 2 +- src/test/run-pass/foreign-fn-with-byval.rs | 2 +- src/test/run-pass/foreign-no-abi.rs | 2 +- src/test/run-pass/issue-28676.rs | 2 +- src/test/run-pass/mir_trans_calls_variadic.rs | 2 +- src/test/run-pass/segfault-no-out-of-stack.rs | 2 +- src/test/run-pass/static-mut-foreign.rs | 2 +- src/test/run-pass/struct-return.rs | 2 +- src/test/run-pass/union/union-c-interop.rs | 2 +- src/test/run-pass/variadic-ffi.rs | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/test/run-pass/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi-sysv64-arg-passing.rs index 989155bdfd98b..23dd060318484 100644 --- a/src/test/run-pass/abi-sysv64-arg-passing.rs +++ b/src/test/run-pass/abi-sysv64-arg-passing.rs @@ -98,7 +98,7 @@ mod tests { #[derive(Copy, Clone)] pub struct Floats { a: f64, b: u8, c: f64 } - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern "sysv64" { pub fn rust_int8_to_int32(_: i8) -> i32; pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; diff --git a/src/test/run-pass/anon-extern-mod.rs b/src/test/run-pass/anon-extern-mod.rs index e96b0cc1442c6..208b4df3c3e7e 100644 --- a/src/test/run-pass/anon-extern-mod.rs +++ b/src/test/run-pass/anon-extern-mod.rs @@ -14,7 +14,7 @@ extern crate libc; -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_get_test_int() -> libc::intptr_t; } diff --git a/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs b/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs index 197fb9a6d018c..741ce351da38e 100644 --- a/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs +++ b/src/test/run-pass/auxiliary/anon-extern-mod-cross-crate-1.rs @@ -13,7 +13,7 @@ extern crate libc; -#[link(name="rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_get_test_int() -> libc::intptr_t; } diff --git a/src/test/run-pass/auxiliary/extern-crosscrate-source.rs b/src/test/run-pass/auxiliary/extern-crosscrate-source.rs index fc2e328f68657..150dffeea886c 100644 --- a/src/test/run-pass/auxiliary/extern-crosscrate-source.rs +++ b/src/test/run-pass/auxiliary/extern-crosscrate-source.rs @@ -17,7 +17,7 @@ extern crate libc; pub mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, data: libc::uintptr_t) diff --git a/src/test/run-pass/auxiliary/foreign_lib.rs b/src/test/run-pass/auxiliary/foreign_lib.rs index 460d0a0088ce2..cef36274c625e 100644 --- a/src/test/run-pass/auxiliary/foreign_lib.rs +++ b/src/test/run-pass/auxiliary/foreign_lib.rs @@ -15,7 +15,7 @@ pub mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_get_test_int() -> libc::intptr_t; } diff --git a/src/test/run-pass/c-stack-as-value.rs b/src/test/run-pass/c-stack-as-value.rs index b678f149fa240..5319693405b5d 100644 --- a/src/test/run-pass/c-stack-as-value.rs +++ b/src/test/run-pass/c-stack-as-value.rs @@ -15,7 +15,7 @@ mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_get_test_int() -> libc::intptr_t; } diff --git a/src/test/run-pass/cabi-int-widening.rs b/src/test/run-pass/cabi-int-widening.rs index c7a2275933335..bf94dd178821a 100644 --- a/src/test/run-pass/cabi-int-widening.rs +++ b/src/test/run-pass/cabi-int-widening.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_int8_to_int32(_: i8) -> i32; } diff --git a/src/test/run-pass/extern-call-deep.rs b/src/test/run-pass/extern-call-deep.rs index 2138b12fb12ab..6a9da767ad6eb 100644 --- a/src/test/run-pass/extern-call-deep.rs +++ b/src/test/run-pass/extern-call-deep.rs @@ -15,7 +15,7 @@ extern crate libc; mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, data: libc::uintptr_t) diff --git a/src/test/run-pass/extern-call-deep2.rs b/src/test/run-pass/extern-call-deep2.rs index 1a0191b70530a..3bdc8c18864fd 100644 --- a/src/test/run-pass/extern-call-deep2.rs +++ b/src/test/run-pass/extern-call-deep2.rs @@ -18,7 +18,7 @@ use std::thread; mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, data: libc::uintptr_t) diff --git a/src/test/run-pass/extern-call-indirect.rs b/src/test/run-pass/extern-call-indirect.rs index 4f1abbeb5c7ed..256eedccb8bfa 100644 --- a/src/test/run-pass/extern-call-indirect.rs +++ b/src/test/run-pass/extern-call-indirect.rs @@ -15,7 +15,7 @@ extern crate libc; mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, data: libc::uintptr_t) diff --git a/src/test/run-pass/extern-call-scrub.rs b/src/test/run-pass/extern-call-scrub.rs index 1beb6d3519aee..a27474dcf866a 100644 --- a/src/test/run-pass/extern-call-scrub.rs +++ b/src/test/run-pass/extern-call-scrub.rs @@ -22,7 +22,7 @@ use std::thread; mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, data: libc::uintptr_t) diff --git a/src/test/run-pass/extern-pass-TwoU16s.rs b/src/test/run-pass/extern-pass-TwoU16s.rs index 9d304ea9e10b6..afdd53db775a8 100644 --- a/src/test/run-pass/extern-pass-TwoU16s.rs +++ b/src/test/run-pass/extern-pass-TwoU16s.rs @@ -16,7 +16,7 @@ pub struct TwoU16s { one: u16, two: u16 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s; } diff --git a/src/test/run-pass/extern-pass-TwoU32s.rs b/src/test/run-pass/extern-pass-TwoU32s.rs index 8dae0473fd5ed..035084ae9bd3a 100644 --- a/src/test/run-pass/extern-pass-TwoU32s.rs +++ b/src/test/run-pass/extern-pass-TwoU32s.rs @@ -16,7 +16,7 @@ pub struct TwoU32s { one: u32, two: u32 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s; } diff --git a/src/test/run-pass/extern-pass-TwoU64s.rs b/src/test/run-pass/extern-pass-TwoU64s.rs index 14aeea3465798..cb1a4d278256a 100644 --- a/src/test/run-pass/extern-pass-TwoU64s.rs +++ b/src/test/run-pass/extern-pass-TwoU64s.rs @@ -16,7 +16,7 @@ pub struct TwoU64s { one: u64, two: u64 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s; } diff --git a/src/test/run-pass/extern-pass-TwoU8s.rs b/src/test/run-pass/extern-pass-TwoU8s.rs index 75a109e442911..657348c99aad8 100644 --- a/src/test/run-pass/extern-pass-TwoU8s.rs +++ b/src/test/run-pass/extern-pass-TwoU8s.rs @@ -16,7 +16,7 @@ pub struct TwoU8s { one: u8, two: u8 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s; } diff --git a/src/test/run-pass/extern-pass-char.rs b/src/test/run-pass/extern-pass-char.rs index e75aa2d72c925..9042aed6639b8 100644 --- a/src/test/run-pass/extern-pass-char.rs +++ b/src/test/run-pass/extern-pass-char.rs @@ -11,7 +11,7 @@ // Test a function that takes/returns a u8. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_u8(v: u8) -> u8; } diff --git a/src/test/run-pass/extern-pass-double.rs b/src/test/run-pass/extern-pass-double.rs index e92f9b6a1a172..38d29180fbc8f 100644 --- a/src/test/run-pass/extern-pass-double.rs +++ b/src/test/run-pass/extern-pass-double.rs @@ -9,7 +9,7 @@ // except according to those terms. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_double(v: f64) -> f64; } diff --git a/src/test/run-pass/extern-pass-empty.rs b/src/test/run-pass/extern-pass-empty.rs index 801a3c40ab47d..cce7dc5bf32ef 100644 --- a/src/test/run-pass/extern-pass-empty.rs +++ b/src/test/run-pass/extern-pass-empty.rs @@ -30,7 +30,7 @@ struct ManyInts { struct Empty; -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); } diff --git a/src/test/run-pass/extern-pass-u32.rs b/src/test/run-pass/extern-pass-u32.rs index 0753ea1bcfead..ed254ac46f20b 100644 --- a/src/test/run-pass/extern-pass-u32.rs +++ b/src/test/run-pass/extern-pass-u32.rs @@ -11,7 +11,7 @@ // Test a function that takes/returns a u32. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_u32(v: u32) -> u32; } diff --git a/src/test/run-pass/extern-pass-u64.rs b/src/test/run-pass/extern-pass-u64.rs index 89faa3bb47141..6fc630e6d7e1a 100644 --- a/src/test/run-pass/extern-pass-u64.rs +++ b/src/test/run-pass/extern-pass-u64.rs @@ -11,7 +11,7 @@ // Test a call to a function that takes/returns a u64. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_identity_u64(v: u64) -> u64; } diff --git a/src/test/run-pass/extern-return-TwoU16s.rs b/src/test/run-pass/extern-return-TwoU16s.rs index 3c58646e0c302..ec1c6130e7adc 100644 --- a/src/test/run-pass/extern-return-TwoU16s.rs +++ b/src/test/run-pass/extern-return-TwoU16s.rs @@ -13,7 +13,7 @@ pub struct TwoU16s { one: u16, two: u16 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s; } diff --git a/src/test/run-pass/extern-return-TwoU32s.rs b/src/test/run-pass/extern-return-TwoU32s.rs index 0eb6be2d687a4..e829e993052a5 100644 --- a/src/test/run-pass/extern-return-TwoU32s.rs +++ b/src/test/run-pass/extern-return-TwoU32s.rs @@ -13,7 +13,7 @@ pub struct TwoU32s { one: u32, two: u32 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s; } diff --git a/src/test/run-pass/extern-return-TwoU64s.rs b/src/test/run-pass/extern-return-TwoU64s.rs index d5eab86351e10..ef7325b33fe3d 100644 --- a/src/test/run-pass/extern-return-TwoU64s.rs +++ b/src/test/run-pass/extern-return-TwoU64s.rs @@ -13,7 +13,7 @@ pub struct TwoU64s { one: u64, two: u64 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s; } diff --git a/src/test/run-pass/extern-return-TwoU8s.rs b/src/test/run-pass/extern-return-TwoU8s.rs index d8f476bcd0cbb..46f2e81a5564a 100644 --- a/src/test/run-pass/extern-return-TwoU8s.rs +++ b/src/test/run-pass/extern-return-TwoU8s.rs @@ -13,7 +13,7 @@ pub struct TwoU8s { one: u8, two: u8 } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s; } diff --git a/src/test/run-pass/foreign-call-no-runtime.rs b/src/test/run-pass/foreign-call-no-runtime.rs index ca118899798b8..697e9074c448c 100644 --- a/src/test/run-pass/foreign-call-no-runtime.rs +++ b/src/test/run-pass/foreign-call-no-runtime.rs @@ -18,7 +18,7 @@ extern crate libc; use std::mem; use std::thread; -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), data: libc::uintptr_t) -> libc::uintptr_t; diff --git a/src/test/run-pass/foreign-fn-with-byval.rs b/src/test/run-pass/foreign-fn-with-byval.rs index d3d872620c38b..2d4542540e7a3 100644 --- a/src/test/run-pass/foreign-fn-with-byval.rs +++ b/src/test/run-pass/foreign-fn-with-byval.rs @@ -16,7 +16,7 @@ pub struct S { z: u64, } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { pub fn get_x(x: S) -> u64; pub fn get_y(x: S) -> u64; diff --git a/src/test/run-pass/foreign-no-abi.rs b/src/test/run-pass/foreign-no-abi.rs index a9b3f60566d4e..979e57eba9d1a 100644 --- a/src/test/run-pass/foreign-no-abi.rs +++ b/src/test/run-pass/foreign-no-abi.rs @@ -17,7 +17,7 @@ mod rustrt { extern crate libc; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_get_test_int() -> libc::intptr_t; } diff --git a/src/test/run-pass/issue-28676.rs b/src/test/run-pass/issue-28676.rs index b8d43c392dd94..8f83e51f0a02d 100644 --- a/src/test/run-pass/issue-28676.rs +++ b/src/test/run-pass/issue-28676.rs @@ -15,7 +15,7 @@ pub struct Quad { a: u64, b: u64, c: u64, d: u64 } mod rustrt { use super::Quad; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn get_c_many_params(_: *const (), _: *const (), _: *const (), _: *const (), f: Quad) -> u64; diff --git a/src/test/run-pass/mir_trans_calls_variadic.rs b/src/test/run-pass/mir_trans_calls_variadic.rs index 4e06738da4fd5..e4d528e80e104 100644 --- a/src/test/run-pass/mir_trans_calls_variadic.rs +++ b/src/test/run-pass/mir_trans_calls_variadic.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_interesting_average(_: i64, ...) -> f64; } diff --git a/src/test/run-pass/segfault-no-out-of-stack.rs b/src/test/run-pass/segfault-no-out-of-stack.rs index df64d7140b4b5..0f98cfe27f648 100644 --- a/src/test/run-pass/segfault-no-out-of-stack.rs +++ b/src/test/run-pass/segfault-no-out-of-stack.rs @@ -17,7 +17,7 @@ extern crate libc; use std::process::{Command, ExitStatus}; use std::env; -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_get_null_ptr() -> *mut ::libc::c_char; } diff --git a/src/test/run-pass/static-mut-foreign.rs b/src/test/run-pass/static-mut-foreign.rs index 4dcb82c4b43b5..24d58487f061e 100644 --- a/src/test/run-pass/static-mut-foreign.rs +++ b/src/test/run-pass/static-mut-foreign.rs @@ -17,7 +17,7 @@ extern crate libc; -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { static mut rust_dbg_static_mut: libc::c_int; pub fn rust_dbg_static_mut_check_four(); diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs index 6f23263790cb7..3d4601ad0cfa1 100644 --- a/src/test/run-pass/struct-return.rs +++ b/src/test/run-pass/struct-return.rs @@ -18,7 +18,7 @@ pub struct Floats { a: f64, b: u8, c: f64 } mod rustrt { use super::{Floats, Quad}; - #[link(name = "rust_test_helpers")] + #[link(name = "rust_test_helpers", kind = "static")] extern { pub fn rust_dbg_abi_1(q: Quad) -> Quad; pub fn rust_dbg_abi_2(f: Floats) -> Floats; diff --git a/src/test/run-pass/union/union-c-interop.rs b/src/test/run-pass/union/union-c-interop.rs index bea4d5f923e21..13dfd414615c5 100644 --- a/src/test/run-pass/union/union-c-interop.rs +++ b/src/test/run-pass/union/union-c-interop.rs @@ -25,7 +25,7 @@ union LARGE_INTEGER { QuadPart: u64, } -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern "C" { fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER; } diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index 0131563d36d35..ec6261febc54d 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[link(name = "rust_test_helpers")] +#[link(name = "rust_test_helpers", kind = "static")] extern { fn rust_interesting_average(_: u64, ...) -> f64; } From 13477c77bf07b1c9a8ddcbd4613e173312c33d59 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Wed, 23 Nov 2016 16:09:51 -0800 Subject: [PATCH 3/9] Implement native library kind and name overrides from the command line. --- src/librustc/session/config.rs | 72 +++++++++++++------ src/librustc_metadata/creader.rs | 22 +++--- src/librustc_metadata/cstore.rs | 17 +++++ .../run-pass/rfc1717/auxiliary/clibrary.rs | 15 ++++ src/test/run-pass/rfc1717/library-override.rs | 23 ++++++ 5 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 src/test/run-pass/rfc1717/auxiliary/clibrary.rs create mode 100644 src/test/run-pass/rfc1717/library-override.rs diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 26dafed7019ed..48bc390ddcaa8 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -262,7 +262,7 @@ top_level_options!( // much sense: The search path can stay the same while the // things discovered there might have changed on disk. search_paths: SearchPaths [TRACKED], - libs: Vec<(String, cstore::NativeLibraryKind)> [TRACKED], + libs: Vec<(String, Option, cstore::NativeLibraryKind)> [TRACKED], maybe_sysroot: Option [TRACKED], target_triple: String [TRACKED], @@ -1439,6 +1439,8 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) } let libs = matches.opt_strs("l").into_iter().map(|s| { + // Parse string of the form "[KIND=]lib[:new_name]", + // where KIND is one of "dylib", "framework", "static". let mut parts = s.splitn(2, '='); let kind = parts.next().unwrap(); let (name, kind) = match (parts.next(), kind) { @@ -1452,7 +1454,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) s)); } }; - (name.to_string(), kind) + let mut name_parts = name.splitn(2, ':'); + let name = name_parts.next().unwrap(); + let new_name = name_parts.next(); + (name.to_string(), new_name.map(|n| n.to_string()), kind) }).collect(); let cfg = parse_cfgspecs(matches.opt_strs("cfg")); @@ -1716,8 +1721,8 @@ mod dep_tracking { impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(CrateType); impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level)); - impl_dep_tracking_hash_for_sortable_vec_of!((String, cstore::NativeLibraryKind)); - + impl_dep_tracking_hash_for_sortable_vec_of!((String, Option, + cstore::NativeLibraryKind)); impl DepTrackingHash for SearchPaths { fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) { let mut elems: Vec<_> = self @@ -1740,6 +1745,21 @@ mod dep_tracking { } } + impl DepTrackingHash for (T1, T2, T3) + where T1: DepTrackingHash, + T2: DepTrackingHash, + T3: DepTrackingHash + { + fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) { + Hash::hash(&0, hasher); + DepTrackingHash::hash(&self.0, hasher, error_format); + Hash::hash(&1, hasher); + DepTrackingHash::hash(&self.1, hasher, error_format); + Hash::hash(&2, hasher); + DepTrackingHash::hash(&self.2, hasher, error_format); + } + } + // This is a stable hash because BTreeMap is a sorted container pub fn stable_hash(sub_hashes: BTreeMap<&'static str, &DepTrackingHash>, hasher: &mut DefaultHasher, @@ -2143,29 +2163,37 @@ mod tests { let mut v1 = super::basic_options(); let mut v2 = super::basic_options(); let mut v3 = super::basic_options(); + let mut v4 = super::basic_options(); // Reference - v1.libs = vec![(String::from("a"), cstore::NativeStatic), - (String::from("b"), cstore::NativeFramework), - (String::from("c"), cstore::NativeUnknown)]; + v1.libs = vec![(String::from("a"), None, cstore::NativeStatic), + (String::from("b"), None, cstore::NativeFramework), + (String::from("c"), None, cstore::NativeUnknown)]; // Change label - v2.libs = vec![(String::from("a"), cstore::NativeStatic), - (String::from("X"), cstore::NativeFramework), - (String::from("c"), cstore::NativeUnknown)]; + v2.libs = vec![(String::from("a"), None, cstore::NativeStatic), + (String::from("X"), None, cstore::NativeFramework), + (String::from("c"), None, cstore::NativeUnknown)]; // Change kind - v3.libs = vec![(String::from("a"), cstore::NativeStatic), - (String::from("b"), cstore::NativeStatic), - (String::from("c"), cstore::NativeUnknown)]; + v3.libs = vec![(String::from("a"), None, cstore::NativeStatic), + (String::from("b"), None, cstore::NativeStatic), + (String::from("c"), None, cstore::NativeUnknown)]; + + // Change new-name + v4.libs = vec![(String::from("a"), None, cstore::NativeStatic), + (String::from("b"), Some(String::from("X")), cstore::NativeFramework), + (String::from("c"), None, cstore::NativeUnknown)]; assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash()); + assert!(v1.dep_tracking_hash() != v4.dep_tracking_hash()); // Check clone assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash()); assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash()); assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash()); + assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash()); } #[test] @@ -2175,17 +2203,17 @@ mod tests { let mut v3 = super::basic_options(); // Reference - v1.libs = vec![(String::from("a"), cstore::NativeStatic), - (String::from("b"), cstore::NativeFramework), - (String::from("c"), cstore::NativeUnknown)]; + v1.libs = vec![(String::from("a"), None, cstore::NativeStatic), + (String::from("b"), None, cstore::NativeFramework), + (String::from("c"), None, cstore::NativeUnknown)]; - v2.libs = vec![(String::from("b"), cstore::NativeFramework), - (String::from("a"), cstore::NativeStatic), - (String::from("c"), cstore::NativeUnknown)]; + v2.libs = vec![(String::from("b"), None, cstore::NativeFramework), + (String::from("a"), None, cstore::NativeStatic), + (String::from("c"), None, cstore::NativeUnknown)]; - v3.libs = vec![(String::from("c"), cstore::NativeUnknown), - (String::from("a"), cstore::NativeStatic), - (String::from("b"), cstore::NativeFramework)]; + v3.libs = vec![(String::from("c"), None, cstore::NativeUnknown), + (String::from("a"), None, cstore::NativeStatic), + (String::from("b"), None, cstore::NativeFramework)]; assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash()); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 436b1b3159f8a..ccbe90ebe7c92 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -966,14 +966,20 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { dump_crates(&self.cstore); } - for &(ref name, kind) in &self.sess.opts.libs { - let lib = NativeLibrary { - name: Symbol::intern(name), - kind: kind, - cfg: None, - foreign_items: Vec::new(), - }; - register_native_lib(self.sess, self.cstore, None, lib); + // Process libs passed on the command line + for &(ref name, ref new_name, kind) in &self.sess.opts.libs { + // First, try to update existing lib(s) added via #[link(...)] + let new_name = new_name.as_ref().map(|s| &**s); // &Option -> Option<&str> + if !self.cstore.update_used_library(name, new_name, kind) { + // Add if not found + let lib = NativeLibrary { + name: Symbol::intern(name), + kind: kind, + cfg: None, + foreign_items: Vec::new(), + }; + register_native_lib(self.sess, self.cstore, None, lib); + } } self.register_statically_included_foreign_items(); self.register_dllimport_foreign_items(); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 279ef5bfb7276..e00278d28db50 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -232,6 +232,23 @@ impl CStore { self.used_libraries.borrow_mut().push(lib); } + // Update kind and, optionally, the name of all native libaries (there may be more than one) + // with the specified name. + pub fn update_used_library(&self, name: &str, new_name: Option<&str>, + new_kind: NativeLibraryKind) -> bool { + let mut found = false; + for item in self.used_libraries.borrow_mut().iter_mut() { + if item.name == name { + item.kind = new_kind; + if let Some(new_name) = new_name { + item.name = Symbol::intern(new_name); + } + found = true; + } + } + found + } + pub fn get_used_libraries(&self) -> &RefCell> { &self.used_libraries } diff --git a/src/test/run-pass/rfc1717/auxiliary/clibrary.rs b/src/test/run-pass/rfc1717/auxiliary/clibrary.rs new file mode 100644 index 0000000000000..7438ba21bfc4a --- /dev/null +++ b/src/test/run-pass/rfc1717/auxiliary/clibrary.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +#![crate_type = "staticlib"] + +#[no_mangle] +pub extern "C" fn foo(x:i32) -> i32 { x } diff --git a/src/test/run-pass/rfc1717/library-override.rs b/src/test/run-pass/rfc1717/library-override.rs new file mode 100644 index 0000000000000..d6ef96c5add01 --- /dev/null +++ b/src/test/run-pass/rfc1717/library-override.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:clibrary.rs +// compile-flags: -lstatic=wronglibrary:clibrary + +#[link(name = "wronglibrary", kind = "dylib")] +extern "C" { + pub fn foo(x:i32) -> i32; +} + +fn main() { + unsafe { + foo(42); + } +} From a9a6f8c8eddba12c72a8caa73bdb236f089bda3c Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Thu, 1 Dec 2016 15:21:59 -0800 Subject: [PATCH 4/9] Remove the "linked_from" feature. --- src/librustc_llvm/ffi.rs | 8 +++---- src/librustc_llvm/lib.rs | 2 +- src/librustc_metadata/creader.rs | 23 +------------------ src/libsyntax/feature_gate.rs | 7 ------ .../compile-fail/feature-gate-linked-from.rs | 16 ------------- src/test/run-make/issue-15460/foo.rs | 2 -- src/test/run-pass/auxiliary/issue-25185-1.rs | 3 --- 7 files changed, 5 insertions(+), 56 deletions(-) delete mode 100644 src/test/compile-fail/feature-gate-linked-from.rs diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 98816826b9ed2..4ee157233eded 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -465,11 +465,9 @@ pub mod debuginfo { // generates an llvmdeps.rs file next to this one which will be // automatically updated whenever LLVM is updated to include an up-to-date // set of the libraries we need to link to LLVM for. -#[link(name = "rustllvm", kind = "static")] -#[cfg(not(cargobuild))] -extern "C" {} - -#[linked_from = "rustllvm"] // not quite true but good enough +#[cfg_attr(not(all(stage0,cargobuild)), + link(name = "rustllvm", kind = "static"))] // not quite true but good enough +#[cfg_attr(stage0, linked_from = "rustllvm")] extern "C" { // Create and destroy contexts. pub fn LLVMContextCreate() -> ContextRef; diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 0229776c94833..8ac2c4677eead 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -27,7 +27,7 @@ #![feature(concat_idents)] #![feature(libc)] #![feature(link_args)] -#![feature(linked_from)] +#![cfg_attr(stage0, feature(linked_from))] #![feature(staged_api)] extern crate libc; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index ccbe90ebe7c92..90bd65386e466 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -22,7 +22,7 @@ use rustc_back::PanicStrategy; use rustc::session::search_paths::PathKind; use rustc::middle; use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate}; -use rustc::util::nodemap::{FxHashMap, FxHashSet}; +use rustc::util::nodemap::FxHashSet; use rustc::middle::cstore::NativeLibrary; use rustc::hir::map::Definitions; @@ -52,7 +52,6 @@ pub struct CrateLoader<'a> { pub sess: &'a Session, cstore: &'a CStore, next_crate_num: CrateNum, - foreign_item_map: FxHashMap>, local_crate_name: Symbol, } @@ -148,7 +147,6 @@ impl<'a> CrateLoader<'a> { sess: sess, cstore: cstore, next_crate_num: cstore.next_crate_num(), - foreign_item_map: FxHashMap(), local_crate_name: Symbol::intern(local_crate_name), } } @@ -649,14 +647,6 @@ impl<'a> CrateLoader<'a> { items.extend(&lib.foreign_items); } } - for (foreign_lib, list) in self.foreign_item_map.iter() { - let kind_matches = libs.borrow().iter().any(|lib| { - lib.name == &**foreign_lib && lib.kind == kind - }); - if kind_matches { - items.extend(list) - } - } items } @@ -943,17 +933,6 @@ impl<'a> CrateLoader<'a> { }; register_native_lib(self.sess, self.cstore, Some(m.span), lib); } - - // Finally, process the #[linked_from = "..."] attribute - for m in i.attrs.iter().filter(|a| a.check_name("linked_from")) { - let lib_name = match m.value_str() { - Some(name) => name, - None => continue, - }; - let list = self.foreign_item_map.entry(lib_name.to_string()) - .or_insert(Vec::new()); - list.extend(fm.items.iter().map(|it| definitions.opt_def_index(it.id).unwrap())); - } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index aa6a29b78b075..33d99d37c2db6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -132,7 +132,6 @@ declare_features! ( (active, allocator, "1.0.0", Some(27389)), (active, fundamental, "1.0.0", Some(29635)), - (active, linked_from, "1.3.0", Some(29629)), (active, main, "1.0.0", Some(29634)), (active, needs_allocator, "1.4.0", Some(27389)), (active, on_unimplemented, "1.0.0", Some(29628)), @@ -636,12 +635,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG is an experimental feature", cfg_fn!(fundamental))), - ("linked_from", Normal, Gated(Stability::Unstable, - "linked_from", - "the `#[linked_from]` attribute \ - is an experimental feature", - cfg_fn!(linked_from))), - ("proc_macro_derive", Normal, Gated(Stability::Unstable, "proc_macro", "the `#[proc_macro_derive]` attribute \ diff --git a/src/test/compile-fail/feature-gate-linked-from.rs b/src/test/compile-fail/feature-gate-linked-from.rs deleted file mode 100644 index 8705684111eb4..0000000000000 --- a/src/test/compile-fail/feature-gate-linked-from.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[linked_from = "foo"] //~ ERROR experimental feature -extern { - fn foo(); -} - -fn main() {} diff --git a/src/test/run-make/issue-15460/foo.rs b/src/test/run-make/issue-15460/foo.rs index 8b96fe3682471..6917fa5557980 100644 --- a/src/test/run-make/issue-15460/foo.rs +++ b/src/test/run-make/issue-15460/foo.rs @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(linked_from)] #![crate_type = "dylib"] #[link(name = "foo", kind = "static")] -#[linked_from = "foo"] extern { pub fn foo(); } diff --git a/src/test/run-pass/auxiliary/issue-25185-1.rs b/src/test/run-pass/auxiliary/issue-25185-1.rs index 1ec29501b763c..b9da39cbbcb4e 100644 --- a/src/test/run-pass/auxiliary/issue-25185-1.rs +++ b/src/test/run-pass/auxiliary/issue-25185-1.rs @@ -10,12 +10,9 @@ // no-prefer-dynamic -#![feature(linked_from)] - #![crate_type = "rlib"] #[link(name = "rust_test_helpers", kind = "static")] -#[linked_from = "rust_test_helpers"] extern { pub fn rust_dbg_extern_identity_u32(u: u32) -> u32; } From a23c4704336b7869f3671ef6a6eb416701511ddb Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Thu, 1 Dec 2016 15:57:16 -0800 Subject: [PATCH 5/9] Tighten up error checking of library renames. --- src/librustc_metadata/creader.rs | 42 ++++++++++++++++--- src/librustc_metadata/cstore.rs | 17 -------- .../compile-fail/rfc1717/missing-link-attr.rs | 14 +++++++ .../compile-fail/rfc1717/multiple-renames.rs | 17 ++++++++ .../compile-fail/rfc1717/rename-to-empty.rs | 17 ++++++++ 5 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 src/test/compile-fail/rfc1717/missing-link-attr.rs create mode 100644 src/test/compile-fail/rfc1717/multiple-renames.rs create mode 100644 src/test/compile-fail/rfc1717/rename-to-empty.rs diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 90bd65386e466..e46162f39d98a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -946,19 +946,51 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { } // Process libs passed on the command line + // First, check for errors + let mut renames = FxHashSet(); + for &(ref name, ref new_name, _) in &self.sess.opts.libs { + if let &Some(ref new_name) = new_name { + if new_name.is_empty() { + self.sess.err( + &format!("an empty renaming target was specified for library `{}`",name)); + } else if !self.cstore.get_used_libraries().borrow().iter() + .any(|lib| lib.name == name as &str) { + self.sess.err(&format!("renaming of the library `{}` was specified, \ + however this crate contains no #[link(...)] \ + attributes referencing this library.", name)); + } else if renames.contains(name) { + self.sess.err(&format!("multiple renamings were specified for library `{}` .", + name)); + } else { + renames.insert(name); + } + } + } + // Update kind and, optionally, the name of all native libaries + // (there may be more than one) with the specified name. for &(ref name, ref new_name, kind) in &self.sess.opts.libs { - // First, try to update existing lib(s) added via #[link(...)] - let new_name = new_name.as_ref().map(|s| &**s); // &Option -> Option<&str> - if !self.cstore.update_used_library(name, new_name, kind) { + let mut found = false; + for lib in self.cstore.get_used_libraries().borrow_mut().iter_mut() { + if lib.name == name as &str { + lib.kind = kind; + if let &Some(ref new_name) = new_name { + lib.name = Symbol::intern(new_name); + } + found = true; + break; + } + } + if !found { // Add if not found + let new_name = new_name.as_ref().map(|s| &**s); // &Option -> Option<&str> let lib = NativeLibrary { - name: Symbol::intern(name), + name: Symbol::intern(new_name.unwrap_or(name)), kind: kind, cfg: None, foreign_items: Vec::new(), }; register_native_lib(self.sess, self.cstore, None, lib); - } + } } self.register_statically_included_foreign_items(); self.register_dllimport_foreign_items(); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index e00278d28db50..279ef5bfb7276 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -232,23 +232,6 @@ impl CStore { self.used_libraries.borrow_mut().push(lib); } - // Update kind and, optionally, the name of all native libaries (there may be more than one) - // with the specified name. - pub fn update_used_library(&self, name: &str, new_name: Option<&str>, - new_kind: NativeLibraryKind) -> bool { - let mut found = false; - for item in self.used_libraries.borrow_mut().iter_mut() { - if item.name == name { - item.kind = new_kind; - if let Some(new_name) = new_name { - item.name = Symbol::intern(new_name); - } - found = true; - } - } - found - } - pub fn get_used_libraries(&self) -> &RefCell> { &self.used_libraries } diff --git a/src/test/compile-fail/rfc1717/missing-link-attr.rs b/src/test/compile-fail/rfc1717/missing-link-attr.rs new file mode 100644 index 0000000000000..810efdedfd6c6 --- /dev/null +++ b/src/test/compile-fail/rfc1717/missing-link-attr.rs @@ -0,0 +1,14 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -l foo:bar +// error-pattern: renaming of the library `foo` was specified + +#![crate_type = "lib"] diff --git a/src/test/compile-fail/rfc1717/multiple-renames.rs b/src/test/compile-fail/rfc1717/multiple-renames.rs new file mode 100644 index 0000000000000..e75c1a14b24d3 --- /dev/null +++ b/src/test/compile-fail/rfc1717/multiple-renames.rs @@ -0,0 +1,17 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -l foo:bar -l foo:baz +// error-pattern: multiple renamings were specified for library + +#![crate_type = "lib"] + +#[link(name = "foo")] +extern "C" {} diff --git a/src/test/compile-fail/rfc1717/rename-to-empty.rs b/src/test/compile-fail/rfc1717/rename-to-empty.rs new file mode 100644 index 0000000000000..ab8c238bc27a3 --- /dev/null +++ b/src/test/compile-fail/rfc1717/rename-to-empty.rs @@ -0,0 +1,17 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -l foo: +// error-pattern: an empty renaming target was specified for library + +#![crate_type = "lib"] + +#[link(name = "foo")] +extern "C" {} From 923034ffd28ce2f5bc05da11a34f848b71b99b01 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Fri, 2 Dec 2016 17:51:54 -0800 Subject: [PATCH 6/9] Rename _all_ library instances. --- src/librustc_metadata/creader.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index e46162f39d98a..691bec19994d4 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -977,7 +977,6 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { lib.name = Symbol::intern(new_name); } found = true; - break; } } if !found { From 2e03549e67a48b6a2b3a83d26dd3540c294b9d6a Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Sat, 3 Dec 2016 15:01:09 -0800 Subject: [PATCH 7/9] Ignore test on -windows-gnu. --- src/test/codegen/dllimports/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/codegen/dllimports/main.rs b/src/test/codegen/dllimports/main.rs index 140d95fb7be2d..64f516aa272e6 100644 --- a/src/test/codegen/dllimports/main.rs +++ b/src/test/codegen/dllimports/main.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// This test is for Windows only. +// This test is for *-windows-msvc only. +// ignore-gnu // ignore-android // ignore-bitrig // ignore-macos From b700dd35e7fe9f3a987cca47a00ac0bdd1cfd425 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 5 Dec 2016 16:31:05 -0800 Subject: [PATCH 8/9] Annotate more tests with kind="static" --- src/test/run-make/c-static-dylib/foo.rs | 2 +- src/test/run-make/c-static-rlib/foo.rs | 2 +- src/test/run-make/extern-fn-generic/test.rs | 2 +- src/test/run-make/extern-fn-generic/testcrate.rs | 2 +- src/test/run-make/interdependent-c-libraries/bar.rs | 2 +- src/test/run-make/interdependent-c-libraries/foo.rs | 2 +- src/test/run-make/issue-25581/test.rs | 2 +- src/test/run-make/link-path-order/main.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/run-make/c-static-dylib/foo.rs b/src/test/run-make/c-static-dylib/foo.rs index 04253be71d454..44be5ac890d6e 100644 --- a/src/test/run-make/c-static-dylib/foo.rs +++ b/src/test/run-make/c-static-dylib/foo.rs @@ -10,7 +10,7 @@ #![crate_type = "dylib"] -#[link(name = "cfoo")] +#[link(name = "cfoo", kind = "static")] extern { fn foo(); } diff --git a/src/test/run-make/c-static-rlib/foo.rs b/src/test/run-make/c-static-rlib/foo.rs index a1f01bd2b626c..cbd7b020bd812 100644 --- a/src/test/run-make/c-static-rlib/foo.rs +++ b/src/test/run-make/c-static-rlib/foo.rs @@ -10,7 +10,7 @@ #![crate_type = "rlib"] -#[link(name = "cfoo")] +#[link(name = "cfoo", kind = "static")] extern { fn foo(); } diff --git a/src/test/run-make/extern-fn-generic/test.rs b/src/test/run-make/extern-fn-generic/test.rs index ee0485683ecc8..8f5ff091b3b6b 100644 --- a/src/test/run-make/extern-fn-generic/test.rs +++ b/src/test/run-make/extern-fn-generic/test.rs @@ -12,7 +12,7 @@ extern crate testcrate; extern "C" fn bar(ts: testcrate::TestStruct) -> T { ts.y } -#[link(name = "test")] +#[link(name = "test", kind = "static")] extern { fn call(c: extern "C" fn(testcrate::TestStruct) -> i32) -> i32; } diff --git a/src/test/run-make/extern-fn-generic/testcrate.rs b/src/test/run-make/extern-fn-generic/testcrate.rs index 5fd61bb419ca9..d02c05047c009 100644 --- a/src/test/run-make/extern-fn-generic/testcrate.rs +++ b/src/test/run-make/extern-fn-generic/testcrate.rs @@ -18,7 +18,7 @@ pub struct TestStruct { pub extern "C" fn foo(ts: TestStruct) -> T { ts.y } -#[link(name = "test")] +#[link(name = "test", kind = "static")] extern { pub fn call(c: extern "C" fn(TestStruct) -> i32) -> i32; } diff --git a/src/test/run-make/interdependent-c-libraries/bar.rs b/src/test/run-make/interdependent-c-libraries/bar.rs index 88fc98615f0b3..1963976b4b0f5 100644 --- a/src/test/run-make/interdependent-c-libraries/bar.rs +++ b/src/test/run-make/interdependent-c-libraries/bar.rs @@ -12,7 +12,7 @@ extern crate foo; -#[link(name = "bar")] +#[link(name = "bar", kind = "static")] extern { fn bar(); } diff --git a/src/test/run-make/interdependent-c-libraries/foo.rs b/src/test/run-make/interdependent-c-libraries/foo.rs index f94c6edb97d71..7a0fe6bb18f90 100644 --- a/src/test/run-make/interdependent-c-libraries/foo.rs +++ b/src/test/run-make/interdependent-c-libraries/foo.rs @@ -10,7 +10,7 @@ #![crate_type = "rlib"] -#[link(name = "foo")] +#[link(name = "foo", kind = "static")] extern { fn foo(); } diff --git a/src/test/run-make/issue-25581/test.rs b/src/test/run-make/issue-25581/test.rs index e2e86df59cd38..6717d16cb7c41 100644 --- a/src/test/run-make/issue-25581/test.rs +++ b/src/test/run-make/issue-25581/test.rs @@ -12,7 +12,7 @@ extern crate libc; -#[link(name = "test")] +#[link(name = "test", kind = "static")] extern { fn slice_len(s: &[u8]) -> libc::size_t; fn slice_elem(s: &[u8], idx: libc::size_t) -> u8; diff --git a/src/test/run-make/link-path-order/main.rs b/src/test/run-make/link-path-order/main.rs index 450460cf19214..aaac3927f1cf3 100644 --- a/src/test/run-make/link-path-order/main.rs +++ b/src/test/run-make/link-path-order/main.rs @@ -12,7 +12,7 @@ extern crate libc; -#[link(name="foo")] +#[link(name="foo", kind = "static")] extern { fn should_return_one() -> libc::c_int; } From 7d05d1e7f0add9e5151d48d51d92b6fb5885e257 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Mon, 5 Dec 2016 10:15:14 -0800 Subject: [PATCH 9/9] Consider only libs that aren't excluded by #[link(cfg=...)] --- src/librustc_metadata/creader.rs | 24 ++++++++++++++++++++---- src/librustc_metadata/cstore.rs | 2 +- src/librustc_metadata/decoder.rs | 15 +++------------ 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 691bec19994d4..d36242537b8e5 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -113,6 +113,13 @@ fn register_native_lib(sess: &Session, cstore.add_used_library(lib); } +fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool { + match lib.cfg { + Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None), + None => true, + } +} + // Extra info about a crate loaded for plugins or exported macros. struct ExtensionCrate { metadata: PMDSource, @@ -290,7 +297,7 @@ impl<'a> CrateLoader<'a> { let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind); - let cmeta = Rc::new(cstore::CrateMetadata { + let mut cmeta = cstore::CrateMetadata { name: name, extern_crate: Cell::new(None), key_map: metadata.load_key_map(crate_root.index), @@ -308,9 +315,18 @@ impl<'a> CrateLoader<'a> { rlib: rlib, rmeta: rmeta, }, - dllimport_foreign_items: RefCell::new(None), - }); + dllimport_foreign_items: FxHashSet(), + }; + + let dllimports: Vec<_> = cmeta.get_native_libraries().iter() + .filter(|lib| relevant_lib(self.sess, lib) && + lib.kind == cstore::NativeLibraryKind::NativeUnknown) + .flat_map(|lib| &lib.foreign_items) + .map(|id| *id) + .collect(); + cmeta.dllimport_foreign_items.extend(dllimports); + let cmeta = Rc::new(cmeta); self.cstore.set_crate_data(cnum, cmeta.clone()); (cnum, cmeta) } @@ -643,7 +659,7 @@ impl<'a> CrateLoader<'a> { let mut items = vec![]; let libs = self.cstore.get_used_libraries(); for lib in libs.borrow().iter() { - if lib.kind == kind { + if relevant_lib(self.sess, lib) && lib.kind == kind { items.extend(&lib.foreign_items); } } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 279ef5bfb7276..7700ebde18133 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -85,7 +85,7 @@ pub struct CrateMetadata { pub proc_macros: Option)>>, // Foreign items imported from a dylib (Windows only) - pub dllimport_foreign_items: RefCell>>, + pub dllimport_foreign_items: FxHashSet, } pub struct CachedInlinedItem { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f8f80a60c1696..5bd1dea1d79c8 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -11,13 +11,13 @@ // Decoding metadata from a single crate's metadata use astencode::decode_inlined_item; -use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, NativeLibraryKind}; +use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; use index::Index; use schema::*; use rustc::hir::map as hir_map; use rustc::hir::map::{DefKey, DefPathData}; -use rustc::util::nodemap::{FxHashMap, FxHashSet}; +use rustc::util::nodemap::FxHashMap; use rustc::hir; use rustc::hir::intravisit::IdRange; @@ -36,7 +36,6 @@ use rustc::mir::Mir; use std::borrow::Cow; use std::cell::Ref; use std::io; -use std::iter::FromIterator; use std::mem; use std::str; use std::u32; @@ -1089,15 +1088,7 @@ impl<'a, 'tcx> CrateMetadata { } pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool { - if self.dllimport_foreign_items.borrow().is_none() { - *self.dllimport_foreign_items.borrow_mut() = Some(FxHashSet::from_iter( - self.get_native_libraries().iter() - .filter(|lib| lib.kind == NativeLibraryKind::NativeUnknown) - .flat_map(|lib| &lib.foreign_items) - .map(|id| *id) - )); - } - self.dllimport_foreign_items.borrow().as_ref().unwrap().contains(&id) + self.dllimport_foreign_items.contains(&id) } pub fn is_defaulted_trait(&self, trait_id: DefIndex) -> bool {