Linking a `.so` shared library into a static binary

I've been trying to set up a rust program along with a *-sys crate to build a shared library (downloaded from elsewhere) into a static binary which does not depend on that library being in the LD_LIBRARY_PATH. I have a file that does roughly this:

fn main() {

where /path/to/foo/lib/ is present. The rest of the foo-sys crate uses extern blocks etc to import the symbols from the library. This crate is used by the test executable crate which just depends on foo-sys.

When set up as described, it builds successfully, but the resulting executable does not run unless I also use LD_LIBRARY_PATH=/path/to/foo/lib, and this is not good because the library will only be available at build time. I would like to statically link to the shared library.

I read some things that suggested that I should instead use


but this fails at build time with could not find native static library `foo`, perhaps an -L flag is missing?. It's also a bit weird to put this in the foo-sys crate since the decision to statically link seems like something for the executable to decide. I also have a line


which I'm not sure whether to use or not.

A shared library doesn't contain any of its dependencies and expects the loader to resolve them on startup. That means it's not possible to take a shared library and statically link it into your crate because you don't have all the information you need.

This answer on StackOverflow explains it better than I could:

I was actually basing this off of a C build script that does seem to do the right thing, but after looking at it more carefully I see now that it is linking some other libraries (.a files in the same directory) instead of the shared library, and linking with those works as intended.

1 Like

Note that rustc has the --print native-static-libs option to print all dynamic libraries necessary to link the produced staticlib (which includes those passed by cargo when using cargo:rustc-link-lib). You have to pass this argument when compiling the staticlib and then rustc will print a bunch of arguments you need to pass to the linker.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.