在 Rust FFI 中混合静态和动态库

Flo*_*yon 5 rust rust-cargo

我的可执行 Rust crate 使用libfoo.a依赖于共享库的本机库libbar.so,但根本不公开它。

我的 Rust FFI 使用来自 libfoo 的方法,所以我link在我的外部代码中定义了一个属性:

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

build.rs包括Cargo.toml使用build="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);
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个输出

cargo:rustc-link-search=../libs/foo/1.0/
cargo:rustc-link-lib=static=foo
cargo:rustc-link-lib=bar
Run Code Online (Sandbox Code Playgroud)

从理论上讲,我希望 Rust 链接到libfoo.alibbar.so。问题是 rustc 甚至没有尝试确认libbar

cargo build --debug 以。。结束

/home/author/src/foo/foo.c:21: undefined reference to 'bar_do_stuff'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

当我检查链接器命令时,有一个-L ../libs/foo/1.0参数,以及-l foo,但没有-l bar!

如果我手动添加-l barto cc,它会很好地构建(并运行)。

你能告诉我我缺少什么吗?libbar即使我不在 Rust 中使用它并且它没有从 libfoo 的 API 中公开,我是否应该创建一个 FFI 绑定?

Flo*_*yon 3

#[link]该问题是FFI 定义中的属性与构建脚本的输出之间存在冲突build.rs

#[link]属性似乎指示rustc忽略该cargo:rustc-link-*指令。

修复方法就像删除该#[link]属性一样简单。