I have two Hello World programs, one in C and one in Rust.
They both define an extern function called foo
, which I want to leave undefined and have dynamically linked into the final executable binary. The C file looks like this:
#include <stdio.h>
extern int foo(int arg1);
int main() {
printf("Hello World! %d\n", foo(1));
return 0;
}
The Rust version looks like this:
#[link(name = "foo", kind = "dylib")]
extern "C" {
fn foo(x: i64) -> i64;
}
fn main() {
println!("Hello World! {}", unsafe { foo(1) });
}
I can compile the C version successfully to a binary executable that dynamically links foo
:
$ clang c_hello.c -undefined dynamic_lookup -o c_hello
When I run the binary, it crashes at runtime - which is exactly what I'm looking for here!
dyld: lazy symbol binding failed: Symbol not found: _foo
However, when I run rustc
on the Rust version, it doesn't successfully produce a binary:
$ rustc rs_hello.rs
error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-m64" "-arch" "x86_64" "-L" [ ... lots of arguments omitted ... ]
= note: ld: library not found for -lfoo
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I thought that maybe this would fix it:
$ rustc -C link-args="-undefined dynamic_lookup" rs_hello.rs
...but it didn't. All it did was add those arguments to the end of the linker invocation:
… "-lSystem" "-lresolv" "-lc" "-lm" "-liconv" "-undefined" "dynamic_lookup"
...but linking still failed with the exact same ld: library not found for -lfoo
error.
I also tried link-arg="-undefined dynamic_lookup"
instead of -link-args="-undefined dynamic_lookup"
(link-arg
instead of link-args
) which did the same as link-args
except then the end of the invocation looked like this:
… "-lSystem" "-lresolv" "-lc" "-lm" "-liconv" "-undefined dynamic_lookup"
...and there was a different error message:
= note: ld: invalid option to -undefined [ warning | error | suppress | dynamic_lookup ]
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Is there some way to do this dynamic linking with rustc
or cargo
?