// crate as well.
//
// The use case for this is a little subtle. In theory the native
-// dependencies of a crate a purely an implementation detail of the crate
+// dependencies of a crate are purely an implementation detail of the crate
// itself, but the problem arises with generic and inlined functions. If a
// generic function calls a native function, then the generic function must
// be instantiated in the target crate, meaning that the native symbol must
// also be resolved in the target crate.
fn add_upstream_native_libraries(args: &mut Vec<~str>, sess: &Session) {
- let cstore = &sess.cstore;
- cstore.iter_crate_data(|cnum, _| {
- let libs = csearch::get_native_libraries(cstore, cnum);
+ // Be sure to use a topological sorting of crates becuase there may be
+ // interdependencies between native libraries. When passing -nodefaultlibs,
+ // for example, almost all native libraries depend on libc, so we have to
+ // make sure that's all the way at the right (liblibc is near the base of
+ // the dependency chain).
+ //
+ // This passes RequireStatic, but the actual requirement doesn't matter,
+ // we're just getting an ordering of crate numbers, we're not worried about
+ // the paths.
+ let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
+ for (cnum, _) in crates.move_iter() {
+ let libs = csearch::get_native_libraries(&sess.cstore, cnum);
for &(kind, ref lib) in libs.iter() {
match kind {
cstore::NativeUnknown => args.push("-l" + *lib),
}
}
}
- });
+ }
}
--- /dev/null
+-include ../tools.mk
+
+# The rust crate foo will link to the native library foo, while the rust crate
+# bar will link to the native library bar. There is also a dependency between
+# the native library bar to the natibe library foo.
+#
+# This test ensures that the ordering of -lfoo and -lbar on the command line is
+# correct to complete the linkage. If passed as "-lfoo -lbar", then the 'foo'
+# library will be stripped out, and the linkage will fail.
+
+all: $(call STATICLIB,foo) $(call STATICLIB,bar)
+ $(RUSTC) foo.rs
+ $(RUSTC) bar.rs
+ $(RUSTC) main.rs -Z print-link-args
+
--- /dev/null
+void foo();
+
+void bar() { foo(); }
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
+
+extern crate foo;
+
+#[link(name = "bar")]
+extern {
+ fn bar();
+}
+
+pub fn doit() {
+ unsafe { bar(); }
+}
+
--- /dev/null
+void foo() {}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type = "rlib"]
+
+#[link(name = "foo")]
+extern {
+ fn foo();
+}
+
+pub fn doit() {
+ unsafe { foo(); }
+}
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate foo;
+extern crate bar;
+
+fn main() {
+ bar::doit();
+}