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

我的可执行文件Rust crate使用本机库libfoo.a,它依赖于共享库libbar.so,但根本不暴露它.

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

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

和我的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);
    }
}

哪个输出

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

从理论上讲,我希望Rust能够链接到libfoo.a和libbar.so.问题是rustc甚至没有尝试承认libbar.

货物构建 – 调试结束

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

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

如果我手动将-l栏添加到cc,它就可以构建(并运行).

你能让我知道我错过了什么吗?我是否应该为libbar创建一个FFI绑定,即使我没有在Rust中使用它并且它没有从libfoo的API中公开?

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

似乎#[link]属性指示rustc忽略货物:rustc-link- *指令.

修复就像删除#[link]属性一样简单.

点赞