I am trying to build a library around a C library libbgpstream. There already exists a libbgpstream-sys crate. The library also requires libwandio, for which there exists wandio-sys crate.
I can compile both libraries fine. However, as soon as try to link to libbgpstream
for any binary, the linker throws errors: There are undefined references to function names, both from libwandio
and libbgpstream
. In addition, it cannot link to functions from parsebgp
, a library that is part of libbgpstream
. Further, it cannot link to functions from rd_kafka
, a dependency of libwandio
.
The way I managed to fix those issues it to write a build.rs
script that explicitly adds the linker flags to all dependencies of libbgpstream
and libwandio
:
fn main() {
println!("cargo:rustc-link-lib=rdkafka");
println!("cargo:rustc-link-lib=parsebgp");
println!("cargo:rustc-link-lib=bgpstream");
println!("cargo:rustc-link-lib=wandio");
println!("cargo:rustc-link-lib=bz2");
println!("cargo:rustc-link-lib=z");
println!("cargo:rustc-link-lib=lzo2");
println!("cargo:rustc-link-lib=lzma");
println!("cargo:rustc-link-lib=zstd");
println!("cargo:rustc-link-lib=lz4");
println!("cargo:rustc-link-lib=curl");
}
I mannually checked which -l
flags are generated by Cargo. Without the build script above, Cargo adds the following flags (while the -L
flags are correct and point to the locations where the .a
files are found):
... -lgcc_s -lutil -lrt -lpthread -lm -ldl -lc ...
I have a few questions:
libbgpstream-sys
print the linecargo:rustc-link-lib=static=bgpstream
(andwandio-sys
printscargo:rustc-link-lib=static=wandio
). Why do I have to explicitly say to link to bothbgpstream
andwandio
explicitly in my crate? Is that related somehow to therustc-link-lib=static=...
part? When I request rustc to statically link a library, doesn't that mean that the library becomes part of the binary, and any subsequent caller libraries don't have to dynamically link to that library using the-l
flag?
Edit: Removing thestatic=
fromlibbgpstream-sys
makes sure that my links with the argument-lbgpstream
. So what does thatstatic=
do?- The library
parsebgp
is compiled bylibbgpstream-sys
. Shouldparsebgp
also be added as a link tag tolibbgpstream-sys
crate? - How can I avoid linking to all the other libraries (like libz, libzstd, libcurl, etc...) from my crate? Those are dependencies of
wandio-sys
. I could not find sys crates for all of those (except libcurl-sys, but the author ofwandio
explicitly says that they could not complie the thing withlibcurl-sys
.
Do you have any recommendations for solving the dependency mess here?