Skip to content

Commit 7504897

Browse files
committed
Don't link "nobundle" libs which had already been included in upstream crate.
1 parent 3ae2174 commit 7504897

File tree

8 files changed

+67
-21
lines changed

8 files changed

+67
-21
lines changed

src/librustc_metadata/creader.rs

+3
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,9 @@ impl<'a> CrateLoader<'a> {
685685
for id in self.get_foreign_items_of_kind(cstore::NativeStatic) {
686686
self.cstore.add_statically_included_foreign_item(id);
687687
}
688+
for id in self.get_foreign_items_of_kind(cstore::NativeStaticNobundle) {
689+
self.cstore.add_statically_included_foreign_item(id);
690+
}
688691
}
689692

690693
fn register_dllimport_foreign_items(&mut self) {

src/librustc_trans/back/link.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ fn link_args(cmd: &mut Linker,
896896
// on other dylibs (e.g. other native deps).
897897
add_local_native_libraries(cmd, sess);
898898
add_upstream_rust_crates(cmd, sess, crate_type, tmpdir);
899-
add_upstream_native_libraries(cmd, sess);
899+
add_upstream_native_libraries(cmd, sess, crate_type);
900900

901901
// # Telling the linker what we're doing
902902

@@ -1213,7 +1213,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
12131213
// generic function calls a native function, then the generic function must
12141214
// be instantiated in the target crate, meaning that the native symbol must
12151215
// also be resolved in the target crate.
1216-
fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
1216+
fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session, crate_type: config::CrateType) {
12171217
// Be sure to use a topological sorting of crates because there may be
12181218
// interdependencies between native libraries. When passing -nodefaultlibs,
12191219
// for example, almost all native libraries depend on libc, so we have to
@@ -1223,6 +1223,9 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
12231223
// This passes RequireStatic, but the actual requirement doesn't matter,
12241224
// we're just getting an ordering of crate numbers, we're not worried about
12251225
// the paths.
1226+
let formats = sess.dependency_formats.borrow();
1227+
let data = formats.get(&crate_type).unwrap();
1228+
12261229
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic);
12271230
for (cnum, _) in crates {
12281231
for lib in sess.cstore.native_libraries(cnum) {
@@ -1232,8 +1235,15 @@ fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
12321235
match lib.kind {
12331236
NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
12341237
NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
1235-
NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&lib.name.as_str()),
1236-
1238+
NativeLibraryKind::NativeStaticNobundle => {
1239+
// Link "static-nobundle" native libs only if the crate they originate from
1240+
// is being linked statically to the current crate. If it's linked dynamically
1241+
// or is an rlib already included via some other dylib crate, the symbols from
1242+
// native libs will have already been included in that dylib.
1243+
if data[cnum.as_usize() - 1] == Linkage::Static {
1244+
cmd.link_staticlib(&lib.name.as_str())
1245+
}
1246+
},
12371247
// ignore statically included native libraries here as we've
12381248
// already included them when we included the rust library
12391249
// previously

src/librustc_trans/back/linker.rs

+1
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ impl<'a> Linker for MsvcLinker<'a> {
450450
writeln!(f, "LIBRARY")?;
451451
writeln!(f, "EXPORTS")?;
452452
for symbol in self.info.exports[&crate_type].iter() {
453+
debug!(" _{}", symbol);
453454
writeln!(f, " {}", symbol)?;
454455
}
455456
Ok(())
+16-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
-include ../tools.mk
22

3-
all: $(call NATIVE_STATICLIB,foo)
4-
$(RUSTC) bar.rs
3+
# aaa is a native static library
4+
# bbb is a rlib
5+
# ccc is a dylib
6+
# ddd is an executable
57

6-
# Check that libbar.rlib does not contain the definition of `func`
7-
nm $(TMPDIR)/libbar.rlib | (! grep "T _*func")
8-
nm $(TMPDIR)/libbar.rlib | grep "U _*func"
8+
all: $(call NATIVE_STATICLIB,aaa)
9+
$(RUSTC) bbb.rs --crate-type=rlib
910

10-
# Check that foo gets passed to the linker (as either `-l foo` or `foo.lib`)
11-
$(RUSTC) main.rs -Z print-link-args | grep -e "-l[\" ]*foo" -e "foo.lib"
11+
# Check that bbb does NOT contain the definition of `native_func`
12+
nm $(TMPDIR)/libbbb.rlib | (! grep "T _*native_func")
13+
nm $(TMPDIR)/libbbb.rlib | grep "U _*native_func"
1214

13-
$(call RUN,main)
15+
# Check that aaa gets linked (either as `-l aaa` or `aaa.lib`) when building ccc.
16+
$(RUSTC) ccc.rs -C prefer-dynamic --crate-type=dylib -Z print-link-args | grep -e "-l[\" ]*aaa" -e "aaa.lib"
17+
18+
# Check that aaa does NOT get linked when building ddd.
19+
$(RUSTC) ddd.rs -Z print-link-args | (! grep -e "-l[\" ]*aaa" -e "aaa.lib")
20+
21+
$(call RUN,ddd)
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -8,4 +8,4 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
void func() {}
11+
void native_func() {}

src/test/run-make/static-nobundle/bar.rs renamed to src/test/run-make/static-nobundle/bbb.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -11,13 +11,13 @@
1111
#![crate_type = "rlib"]
1212
#![feature(static_nobundle)]
1313

14-
#[link(name = "foo", kind = "static-nobundle")]
14+
#[link(name = "aaa", kind = "static-nobundle")]
1515
extern {
16-
pub fn func();
16+
pub fn native_func();
1717
}
1818

1919
pub fn wrapped_func() {
2020
unsafe {
21-
func();
21+
native_func();
2222
}
2323
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2017 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+
#![crate_type = "dylib"]
12+
13+
extern crate bbb;
14+
15+
pub fn do_work() {
16+
unsafe { bbb::native_func(); }
17+
bbb::wrapped_func();
18+
}
19+
20+
pub fn do_work_generic<T>() {
21+
unsafe { bbb::native_func(); }
22+
bbb::wrapped_func();
23+
}

src/test/run-make/static-nobundle/main.rs renamed to src/test/run-make/static-nobundle/ddd.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
extern crate bar;
11+
extern crate ccc;
1212

1313
fn main() {
14-
unsafe { bar::func(); }
15-
bar::wrapped_func();
14+
ccc::do_work();
15+
ccc::do_work_generic::<i16>();
16+
ccc::do_work_generic::<i32>();
1617
}

0 commit comments

Comments
 (0)