diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 24615f2fa6992..5f399db893da3 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -288,7 +288,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, Option, cstore::NativeLibraryKind)> [TRACKED], + libs: Vec<(String, Option, Option)> [TRACKED], maybe_sysroot: Option [TRACKED], target_triple: String [TRACKED], @@ -1495,18 +1495,18 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches) let mut parts = s.splitn(2, '='); let kind = parts.next().unwrap(); let (name, kind) = match (parts.next(), kind) { - (None, name) | - (Some(name), "dylib") => (name, cstore::NativeUnknown), - (Some(name), "framework") => (name, cstore::NativeFramework), - (Some(name), "static") => (name, cstore::NativeStatic), - (Some(name), "static-nobundle") => (name, cstore::NativeStaticNobundle), + (None, name) => (name, None), + (Some(name), "dylib") => (name, Some(cstore::NativeUnknown)), + (Some(name), "framework") => (name, Some(cstore::NativeFramework)), + (Some(name), "static") => (name, Some(cstore::NativeStatic)), + (Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)), (_, s) => { early_error(error_format, &format!("unknown library kind `{}`, expected \ one of dylib, framework, or static", s)); } }; - if kind == cstore::NativeStaticNobundle && !nightly_options::is_nightly_build() { + if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() { early_error(error_format, &format!("the library kind 'static-nobundle' is only \ accepted on the nightly compiler")); } @@ -1772,6 +1772,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(CrateType); impl_dep_tracking_hash_via_hash!(PanicStrategy); impl_dep_tracking_hash_via_hash!(Passes); @@ -1786,7 +1787,7 @@ mod dep_tracking { 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, Option, - cstore::NativeLibraryKind)); + Option)); impl DepTrackingHash for SearchPaths { fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) { let mut elems: Vec<_> = self @@ -2230,24 +2231,24 @@ mod tests { let mut v4 = super::basic_options(); // Reference - v1.libs = vec![(String::from("a"), None, cstore::NativeStatic), - (String::from("b"), None, cstore::NativeFramework), - (String::from("c"), None, cstore::NativeUnknown)]; + v1.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown))]; // Change label - v2.libs = vec![(String::from("a"), None, cstore::NativeStatic), - (String::from("X"), None, cstore::NativeFramework), - (String::from("c"), None, cstore::NativeUnknown)]; + v2.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("X"), None, Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown))]; // Change kind - v3.libs = vec![(String::from("a"), None, cstore::NativeStatic), - (String::from("b"), None, cstore::NativeStatic), - (String::from("c"), None, cstore::NativeUnknown)]; + v3.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeStatic)), + (String::from("c"), None, Some(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)]; + v4.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), Some(String::from("X")), Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown))]; assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash()); assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash()); @@ -2267,17 +2268,17 @@ mod tests { let mut v3 = super::basic_options(); // Reference - v1.libs = vec![(String::from("a"), None, cstore::NativeStatic), - (String::from("b"), None, cstore::NativeFramework), - (String::from("c"), None, cstore::NativeUnknown)]; + v1.libs = vec![(String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(cstore::NativeFramework)), + (String::from("c"), None, Some(cstore::NativeUnknown))]; - v2.libs = vec![(String::from("b"), None, cstore::NativeFramework), - (String::from("a"), None, cstore::NativeStatic), - (String::from("c"), None, cstore::NativeUnknown)]; + v2.libs = vec![(String::from("b"), None, Some(cstore::NativeFramework)), + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("c"), None, Some(cstore::NativeUnknown))]; - v3.libs = vec![(String::from("c"), None, cstore::NativeUnknown), - (String::from("a"), None, cstore::NativeStatic), - (String::from("b"), None, cstore::NativeFramework)]; + v3.libs = vec![(String::from("c"), None, Some(cstore::NativeUnknown)), + (String::from("a"), None, Some(cstore::NativeStatic)), + (String::from("b"), None, Some(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 104d76b1f600d..4477488f6cb38 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1077,10 +1077,20 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { 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; + let mut changed = false; + if let Some(k) = kind { + lib.kind = k; + changed = true; + } if let &Some(ref new_name) = new_name { lib.name = Symbol::intern(new_name); + changed = true; + } + if !changed { + self.sess.warn(&format!("redundant linker flag specified for library `{}`", + name)); } + found = true; } } @@ -1089,7 +1099,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { let new_name = new_name.as_ref().map(|s| &**s); // &Option -> Option<&str> let lib = NativeLibrary { name: Symbol::intern(new_name.unwrap_or(name)), - kind: kind, + kind: if let Some(k) = kind { k } else { cstore::NativeUnknown }, cfg: None, foreign_items: Vec::new(), }; diff --git a/src/test/run-pass/auxiliary/clibrary.rs b/src/test/run-pass/auxiliary/clibrary.rs new file mode 100644 index 0000000000000..7438ba21bfc4a --- /dev/null +++ b/src/test/run-pass/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/lib-defaults.rs b/src/test/run-pass/lib-defaults.rs new file mode 100644 index 0000000000000..a38080f8cfe75 --- /dev/null +++ b/src/test/run-pass/lib-defaults.rs @@ -0,0 +1,23 @@ +// Copyright 2017 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: -lclibrary + +#[link(name = "clibrary", kind = "static")] +extern "C" { + pub fn foo(x:i32) -> i32; +} + +fn main() { + unsafe { + foo(42); + } +}