在 Rust FFI 中混合静态库和动态库
Mixing static and dynamic libraries in Rust FFI
我的可执行 Rust crate 使用了一个本地库 libfoo.a
,它依赖于一个共享库 libbar.so
,但根本没有公开它。
我的 Rust FFI 使用 libfoo 中的方法,所以我在我的外部代码上定义了一个 link
属性::
#[link(name="foo", kind="static")]
extern "C"{
pub fn do_foo();
}
和我的 build.rs
使用 build="build.rs"
从 Cargo.toml
中包含
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 link 对抗 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
当我检查 linker 命令时,有一个 -L ../libs/foo/1.0
参数,还有 -l foo
,但是没有 -l bar
的痕迹!
如果我手动将 -l bar
添加到 cc
,它可以正常构建(并运行)。
你能告诉我我错过了什么吗?我是否应该为 libbar
创建一个 FFI 绑定,即使我没有在 Rust 中使用它并且它没有从 libfoo 的 API 中公开?
问题是 FFI 定义中的 #[link]
属性与 build.rs
构建脚本的输出之间存在冲突。
#[link]
属性似乎指示 rustc
忽略 cargo:rustc-link-*
指令。
修复就像删除 #[link]
属性一样简单。
我的可执行 Rust crate 使用了一个本地库 libfoo.a
,它依赖于一个共享库 libbar.so
,但根本没有公开它。
我的 Rust FFI 使用 libfoo 中的方法,所以我在我的外部代码上定义了一个 link
属性::
#[link(name="foo", kind="static")]
extern "C"{
pub fn do_foo();
}
和我的 build.rs
使用 build="build.rs"
Cargo.toml
中包含
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 link 对抗 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
当我检查 linker 命令时,有一个 -L ../libs/foo/1.0
参数,还有 -l foo
,但是没有 -l bar
的痕迹!
如果我手动将 -l bar
添加到 cc
,它可以正常构建(并运行)。
你能告诉我我错过了什么吗?我是否应该为 libbar
创建一个 FFI 绑定,即使我没有在 Rust 中使用它并且它没有从 libfoo 的 API 中公开?
问题是 FFI 定义中的 #[link]
属性与 build.rs
构建脚本的输出之间存在冲突。
#[link]
属性似乎指示 rustc
忽略 cargo:rustc-link-*
指令。
修复就像删除 #[link]
属性一样简单。