Skip to content

Commit 13477c7

Browse files
committed
Implement native library kind and name overrides from the command line.
1 parent 4508e8a commit 13477c7

File tree

5 files changed

+119
-30
lines changed

5 files changed

+119
-30
lines changed

src/librustc/session/config.rs

+50-22
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ top_level_options!(
262262
// much sense: The search path can stay the same while the
263263
// things discovered there might have changed on disk.
264264
search_paths: SearchPaths [TRACKED],
265-
libs: Vec<(String, cstore::NativeLibraryKind)> [TRACKED],
265+
libs: Vec<(String, Option<String>, cstore::NativeLibraryKind)> [TRACKED],
266266
maybe_sysroot: Option<PathBuf> [TRACKED],
267267

268268
target_triple: String [TRACKED],
@@ -1439,6 +1439,8 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
14391439
}
14401440

14411441
let libs = matches.opt_strs("l").into_iter().map(|s| {
1442+
// Parse string of the form "[KIND=]lib[:new_name]",
1443+
// where KIND is one of "dylib", "framework", "static".
14421444
let mut parts = s.splitn(2, '=');
14431445
let kind = parts.next().unwrap();
14441446
let (name, kind) = match (parts.next(), kind) {
@@ -1452,7 +1454,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
14521454
s));
14531455
}
14541456
};
1455-
(name.to_string(), kind)
1457+
let mut name_parts = name.splitn(2, ':');
1458+
let name = name_parts.next().unwrap();
1459+
let new_name = name_parts.next();
1460+
(name.to_string(), new_name.map(|n| n.to_string()), kind)
14561461
}).collect();
14571462

14581463
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
@@ -1716,8 +1721,8 @@ mod dep_tracking {
17161721
impl_dep_tracking_hash_for_sortable_vec_of!(String);
17171722
impl_dep_tracking_hash_for_sortable_vec_of!(CrateType);
17181723
impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level));
1719-
impl_dep_tracking_hash_for_sortable_vec_of!((String, cstore::NativeLibraryKind));
1720-
1724+
impl_dep_tracking_hash_for_sortable_vec_of!((String, Option<String>,
1725+
cstore::NativeLibraryKind));
17211726
impl DepTrackingHash for SearchPaths {
17221727
fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
17231728
let mut elems: Vec<_> = self
@@ -1740,6 +1745,21 @@ mod dep_tracking {
17401745
}
17411746
}
17421747

1748+
impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
1749+
where T1: DepTrackingHash,
1750+
T2: DepTrackingHash,
1751+
T3: DepTrackingHash
1752+
{
1753+
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
1754+
Hash::hash(&0, hasher);
1755+
DepTrackingHash::hash(&self.0, hasher, error_format);
1756+
Hash::hash(&1, hasher);
1757+
DepTrackingHash::hash(&self.1, hasher, error_format);
1758+
Hash::hash(&2, hasher);
1759+
DepTrackingHash::hash(&self.2, hasher, error_format);
1760+
}
1761+
}
1762+
17431763
// This is a stable hash because BTreeMap is a sorted container
17441764
pub fn stable_hash(sub_hashes: BTreeMap<&'static str, &DepTrackingHash>,
17451765
hasher: &mut DefaultHasher,
@@ -2143,29 +2163,37 @@ mod tests {
21432163
let mut v1 = super::basic_options();
21442164
let mut v2 = super::basic_options();
21452165
let mut v3 = super::basic_options();
2166+
let mut v4 = super::basic_options();
21462167

21472168
// Reference
2148-
v1.libs = vec![(String::from("a"), cstore::NativeStatic),
2149-
(String::from("b"), cstore::NativeFramework),
2150-
(String::from("c"), cstore::NativeUnknown)];
2169+
v1.libs = vec![(String::from("a"), None, cstore::NativeStatic),
2170+
(String::from("b"), None, cstore::NativeFramework),
2171+
(String::from("c"), None, cstore::NativeUnknown)];
21512172

21522173
// Change label
2153-
v2.libs = vec![(String::from("a"), cstore::NativeStatic),
2154-
(String::from("X"), cstore::NativeFramework),
2155-
(String::from("c"), cstore::NativeUnknown)];
2174+
v2.libs = vec![(String::from("a"), None, cstore::NativeStatic),
2175+
(String::from("X"), None, cstore::NativeFramework),
2176+
(String::from("c"), None, cstore::NativeUnknown)];
21562177

21572178
// Change kind
2158-
v3.libs = vec![(String::from("a"), cstore::NativeStatic),
2159-
(String::from("b"), cstore::NativeStatic),
2160-
(String::from("c"), cstore::NativeUnknown)];
2179+
v3.libs = vec![(String::from("a"), None, cstore::NativeStatic),
2180+
(String::from("b"), None, cstore::NativeStatic),
2181+
(String::from("c"), None, cstore::NativeUnknown)];
2182+
2183+
// Change new-name
2184+
v4.libs = vec![(String::from("a"), None, cstore::NativeStatic),
2185+
(String::from("b"), Some(String::from("X")), cstore::NativeFramework),
2186+
(String::from("c"), None, cstore::NativeUnknown)];
21612187

21622188
assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
21632189
assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
2190+
assert!(v1.dep_tracking_hash() != v4.dep_tracking_hash());
21642191

21652192
// Check clone
21662193
assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
21672194
assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
21682195
assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
2196+
assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash());
21692197
}
21702198

21712199
#[test]
@@ -2175,17 +2203,17 @@ mod tests {
21752203
let mut v3 = super::basic_options();
21762204

21772205
// Reference
2178-
v1.libs = vec![(String::from("a"), cstore::NativeStatic),
2179-
(String::from("b"), cstore::NativeFramework),
2180-
(String::from("c"), cstore::NativeUnknown)];
2206+
v1.libs = vec![(String::from("a"), None, cstore::NativeStatic),
2207+
(String::from("b"), None, cstore::NativeFramework),
2208+
(String::from("c"), None, cstore::NativeUnknown)];
21812209

2182-
v2.libs = vec![(String::from("b"), cstore::NativeFramework),
2183-
(String::from("a"), cstore::NativeStatic),
2184-
(String::from("c"), cstore::NativeUnknown)];
2210+
v2.libs = vec![(String::from("b"), None, cstore::NativeFramework),
2211+
(String::from("a"), None, cstore::NativeStatic),
2212+
(String::from("c"), None, cstore::NativeUnknown)];
21852213

2186-
v3.libs = vec![(String::from("c"), cstore::NativeUnknown),
2187-
(String::from("a"), cstore::NativeStatic),
2188-
(String::from("b"), cstore::NativeFramework)];
2214+
v3.libs = vec![(String::from("c"), None, cstore::NativeUnknown),
2215+
(String::from("a"), None, cstore::NativeStatic),
2216+
(String::from("b"), None, cstore::NativeFramework)];
21892217

21902218
assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
21912219
assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());

src/librustc_metadata/creader.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -966,14 +966,20 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
966966
dump_crates(&self.cstore);
967967
}
968968

969-
for &(ref name, kind) in &self.sess.opts.libs {
970-
let lib = NativeLibrary {
971-
name: Symbol::intern(name),
972-
kind: kind,
973-
cfg: None,
974-
foreign_items: Vec::new(),
975-
};
976-
register_native_lib(self.sess, self.cstore, None, lib);
969+
// Process libs passed on the command line
970+
for &(ref name, ref new_name, kind) in &self.sess.opts.libs {
971+
// First, try to update existing lib(s) added via #[link(...)]
972+
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
973+
if !self.cstore.update_used_library(name, new_name, kind) {
974+
// Add if not found
975+
let lib = NativeLibrary {
976+
name: Symbol::intern(name),
977+
kind: kind,
978+
cfg: None,
979+
foreign_items: Vec::new(),
980+
};
981+
register_native_lib(self.sess, self.cstore, None, lib);
982+
}
977983
}
978984
self.register_statically_included_foreign_items();
979985
self.register_dllimport_foreign_items();

src/librustc_metadata/cstore.rs

+17
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,23 @@ impl CStore {
232232
self.used_libraries.borrow_mut().push(lib);
233233
}
234234

235+
// Update kind and, optionally, the name of all native libaries (there may be more than one)
236+
// with the specified name.
237+
pub fn update_used_library(&self, name: &str, new_name: Option<&str>,
238+
new_kind: NativeLibraryKind) -> bool {
239+
let mut found = false;
240+
for item in self.used_libraries.borrow_mut().iter_mut() {
241+
if item.name == name {
242+
item.kind = new_kind;
243+
if let Some(new_name) = new_name {
244+
item.name = Symbol::intern(new_name);
245+
}
246+
found = true;
247+
}
248+
}
249+
found
250+
}
251+
235252
pub fn get_used_libraries(&self) -> &RefCell<Vec<NativeLibrary>> {
236253
&self.used_libraries
237254
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
#![crate_type = "staticlib"]
13+
14+
#[no_mangle]
15+
pub extern "C" fn foo(x:i32) -> i32 { x }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:clibrary.rs
12+
// compile-flags: -lstatic=wronglibrary:clibrary
13+
14+
#[link(name = "wronglibrary", kind = "dylib")]
15+
extern "C" {
16+
pub fn foo(x:i32) -> i32;
17+
}
18+
19+
fn main() {
20+
unsafe {
21+
foo(42);
22+
}
23+
}

0 commit comments

Comments
 (0)