Best practice to link with cdylib libraries


#1

Hello everyone,
I’m new to rust but I enjoy it a lot.

I would like to know what is the best way to dynamically link with a C library (.so).

If I understand correctly, there are two ways:

  • From the documentation, I should add a links attribute under package in my Cargo.toml and I should create a build script build.rs
  • From what I found on internet, I should use this syntax:
#[link(name = "mylib")]
extern {
    fn external_fun();
}

Currently, the first way is not working for me whereas the second works well.

Can you help me to better understand these syntax ?


#2

For example with build.rs you can look at https://github.com/servo/skia/blob/master/build.rs


#3

For dynamic libraries usually the hard part is finding them on the system (using pkg-config, searching dirs, building from source, etc.) and configuring them, so the simple #[link] directive is not enough (the #[link] directive just adds -l flags to the linker invocation).

So the usual solution is the first one. Do it in a separate $libraryname-sys crate, so that you won’t have to duplicate the search-and-link code each time you use the library, and you’ll just reuse the Rust sys crate for it.


#4

Thanks for your answer.

So If I understand correctly, the only way to link is to use #[link] and the build.rs allows to find the library.
When using only build.rs and links in Cargo.toml, there is no link done.
Moreover, when I add links in my Cargo.toml, I can’t link with two libraries to a common other library whereas with #[link], this limitation is gone.


#5

links in Cargo.toml is just for preventing two crates linking the same library by accident.

#[link] and link directives printed by build.rs script are equivalent. The difference is build.rs can run code to build the link information dynamically rather than hardcoding it.