16

The state of dynamic linking in rust is very confusing to me currently. I can only find old sources that say rust doesn't support dynamic linking, yet I know multiple libraries that do dynamic linking (ex bevy_dylib).
Is it currently possible to create a bin crate and a lib crate, and link the bin to the lib at runtime using dylib or rlib?
Something like

// lib.rs
fn hi() {
   println!("hi");
}


// main.rs
fn main() {
   // whatever to link to lib.rs/lib.so
   link("./lib.so");
   hi();
}
5
  • Not sure what you're asking, the reference page on linkage seems pretty clear. Commented Mar 31, 2023 at 23:11
  • I've looked through that but it doesn't really say if and how the above is possible, it just lists what rust can be compiled too and stuff about linking to C. Commented Mar 31, 2023 at 23:17
  • 1
    "--crate-type=dylib, #![crate_type = "dylib"] - A dynamic Rust library will be produced. This is different from the lib output type in that this forces dynamic library generation. The resulting dynamic library can be used as a dependency for other libraries and/or executables. This output type will create *.so files on Linux, *.dylib files on macOS, and *.dll files on Windows" clearly says it's possible, you use the type dylib Commented Mar 31, 2023 at 23:18
  • I know how to make a dylib, but how do I actually link to it from the main binary? Commented Mar 31, 2023 at 23:22
  • "use [it] as a dependency" in Cargo.toml [dependencies] yourcrate = {path = "whatever", version = "*" } the same as for a static library Commented Mar 31, 2023 at 23:39

1 Answer 1

14

To link dynamically instead of statically the only thing you have to change is the crate type of your library from the default to dylib:

Generate a library:

cargo new --lib dy-lib

Add the type in dy-lib/Cargo.toml everything else can stay unchanged:

[lib]
crate-type = ["dylib"]

Generate a binary and add library as dependency:

cargo new dy-bin
cd dy-bin
cargo add dy-lib --path ../dy-lib

Replace the contents of dy-bin/src/main.rs with something that uses the library:

fn main() {
    println!("{}", dy_lib::add(1, 2));
}

build the binary

cargo build # or cargo run, ...

The binary is now dynamically linked to our dynamic library as can be seen by for example readelf on linux:

$ readelf -d target/debug/dy-bin

Dynamic section at offset 0x2d70 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libdy_lib.so]
...

And if you remove it there will be a runtime error:

$ rm target/debug/libdy_lib.so
$ target/debug/dy-bin
target/debug/dy-bin: error while loading shared libraries: libdy_lib.so: cannot open shared object file: No such file or directory
Sign up to request clarification or add additional context in comments.

1 Comment

Note that Rust ABI is not stable, so one would better use cdylib instead of dylib and make all necessary functions extern "C".

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.