我的可执行文件Rust crate使用的本地库libfoo.a
依赖于共享库libbar.so
,但根本不会公开它。
My 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
。
cargo build --debug
以
/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 bar
添加到cc
,它就可以构建(并运行)。
libbar
创建一个FFI绑定,即使我没有在Rust中使用它并且它没有从libfoo的API中公开?
答案 0 :(得分:2)
问题是FFI定义中的#[link]
属性与build.rs
构建脚本的输出之间存在冲突。
似乎#[link]
属性指示rustc
忽略cargo:rustc-link-*
指令。
修复就像删除#[link]
属性一样简单。