Cucumber测试编译时Rust链接器无法找到已引入的FFI库
Cucumber测试编译时Rust链接器无法找到已引入的FFI库
最近我在维护一个用Cucumber测试Rust FFI库的项目时,碰到了个头疼的问题——之前运行正常的代码,升级到nightly-2024-08-03之后的Rust版本就编译失败,链接器死活找不到我明明已经引入的FFI库。先跟你说说我的项目配置和问题场景:
- 依赖配置:我在Cucumber测试 crate 的
Cargo.toml里,通过相对路径引入了目标FFI库:ffi_lib = { path = "../base/ffi_lib" } - 代码链接方式:在测试代码中,我用标准的Rust FFI写法声明并链接库函数:
#[link(name = "ffi_lib")] #[allow(dead_code)] extern "C" { pub fn create_vector(tag: TTypeTag) -> *mut TVector; // 项目里还有其他FFI函数声明 } - 问题表现:这套配置在
nightly-2024-08-03及更早的Rust版本里完全正常,编译、测试都没毛病,但只要升级到比这个版本新的nightly版本,编译Cucumber测试时链接器就会抛出“找不到ffi_lib库”的错误。
折腾了好一阵之后,我总结了几个能解决这类问题的方向,你可以挨个试试:
- 先确认FFI库本身是否正常编译:手动进入
../base/ffi_lib目录执行cargo build,去target目录下检查有没有生成对应的库文件(比如Linux下的libffi_lib.a/libffi_lib.so,Windows下的ffi_lib.dll/ffi_lib.lib),如果库文件没生成,那肯定会链接失败。 - 明确指定链接库的类型:新版本Rust可能对链接属性的校验更严格,你可以试试给
#[link]属性加上kind参数,明确告诉链接器要找的是静态库还是动态库,比如:#[link(name = "ffi_lib", kind = "static")] // 或者 kind = "dylib",根据你的FFI库编译类型来选 extern "C" { // 函数声明不变 } - 检查Cargo编译配置的兼容性:有时候测试 crate 的编译profile和FFI库的profile不匹配也会出问题,比如FFI库用release模式编译,测试用debug模式,导致链接器找不到对应profile下的库。你可以在测试 crate 的
Cargo.toml里加上强制同步的配置:[profile.test] build-override = { profile = "dev" } # 和FFI库的debug profile同步 - 清理Cargo缓存后重新编译:有时候Cargo的缓存会残留旧的编译信息,执行
cargo clean清空缓存,先编译ffi_lib,再编译测试 crate,很多时候能解决这类诡异的链接问题。
这些方法我自己试下来,大部分场景下都能搞定链接器找不到库的问题,你可以根据自己的项目情况调整尝试。
内容来源于stack exchange
相关产品推荐
相关产品推荐

