Mixing static and dynamic libraries in Rust FFI

My Rust executable uses its own library libfoo.a, which depends on the shared library libbar.so, but does not open it at all.

My Rust FFI uses methods from libfoo, so I defined an attribute linkfor my external code:

#[link(name="foo", kind="static")]
extern "C"{
    pub fn do_foo();
}

and mine build.rsincluded from Cargo.tomlusingbuild="build.rs"

fn main() {
    let libs = &[(Some("../libs/foo/1.0/"), "static=foo"), // use ../libs/foo/1.0/libfoo.a
                 (None, "bar")]; // use libbar.so using LD_LIBRARY_PATH
    for &(ref m_path, ref lib) in libs {
        if let &Some(static_path) = m_path {
            println!("cargo:rustc-link-search={}", &static_path);
        }
        println!("cargo:rustc-link-lib={}", &lib);
    }
}

which outputs

cargo:rustc-link-search=../libs/foo/1.0/
cargo:rustc-link-lib=static=foo
cargo:rustc-link-lib=bar

Theoretically, I expect Rust to contact libfoo.aand libbar.so. The problem is that rustc is not even trying to confirm libbar.

cargo build --debug ends on

/home/author/src/foo/foo.c:21: undefined reference to 'bar_do_stuff'
collect2: error: ld returned 1 exit status

When I check the linker command, there is an argument -L ../libs/foo/1.0as well -l foo, but no trace -l bar!

If I manually add -l barin cc, it builds (and works) just fine.

, ? FFI libbar, Rust API libfoo?

+4
1

#[link] FFI build.rs build script.

, #[link] rustc cargo:rustc-link-*.

, #[link].

+2

All Articles