Closed
Description
// foo.c
void foo() {}
// foo.rs
#![crate_type = "dylib"]
#[link(name = "foo", kind = "static")]
extern {
pub fn foo();
}
// bar.rs
extern crate foo;
fn main() { unsafe { foo::foo() } }
$ gcc -c foo.c
$ ar crus libfoo.a foo.o
$ rustc foo.rs -L.
$ rustc bar.rs -L.
error: linking with `cc` failed: exit code: 1
note: cc '-m64' '-L' '/Users/acrichton/code/rust/lib/rustlib/x86_64-apple-darwin/lib' '-o' 'bar' 'bar.o' '-Wl,-force_load,/Users/acrichton/code/rust/lib/rustlib/x86_64-apple-darwin/lib/libmorestack.a' '-nodefaultlibs' '-Wl,-dead_strip' '-L' '/Users/acrichton/code/rust/lib/rustlib/x86_64-apple-darwin/lib' '-lnative-1fb5e2c0-0.11.0-pre' '-L' '/Users/acrichton/tmp' '-lfoo-aab0fa9e-0.0' '-L' '/Users/acrichton/code/rust/lib/rustlib/x86_64-apple-darwin/lib' '-lstd-59beb4f7-0.11.0-pre' '-L' '/Users/acrichton/code/rust/lib/rustlib/x86_64-apple-darwin/lib' '-lsync-305341d2-0.11.0-pre' '-L' '/Users/acrichton/code/rust/lib/rustlib/x86_64-apple-darwin/lib' '-lrustrt-d8560cb2-0.11.0-pre' '-L' '.' '-L' '/Users/acrichton/tmp/.rust' '-L' '/Users/acrichton/tmp' '-L' '/Users/acrichton/.rust' '-lSystem' '-lpthread' '-lc' '-lm' '-Wl,-rpath,@loader_path/../code/rust/lib/rustlib/x86_64-apple-darwin/lib' '-Wl,-rpath,@loader_path/.' '-Wl,-rpath,/usr/local/lib/rustlib/x86_64-apple-darwin/lib' '-lcompiler-rt'
note: ld: warning: directory not found for option '-L/Users/acrichton/tmp/.rust'
Undefined symbols for architecture x86_64:
"_foo", referenced from:
main::hdcb342faf114af9efaa::v0.0 in bar.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: aborting due to previous error
The problem is that if the dynamic library doesn't actually reference any symbols from the native library then the native library is stripped from the command line.
Possible solutions
- Stop using
-Wl,--as-needed
- Pass
-Wl,--whole-archive
for immediately dependent static libraries - For all extern blocks with a
#[link(kind = "static")]
, generate a reference to all symbols in the extern block to force the library to be linked. (in some sort of 0-cost manner)