Cargo Test加载共享库失败,无需手动设置LD_LIBRARY_PATH的解决方法?
解决cargo test时找不到cmake构建的共享库的替代方案
除了手动设置LD_LIBRARY_PATH,还有以下几种可行方法:
1. 在build.rs中嵌入rpath到可执行文件
将共享库的路径直接嵌入到测试可执行文件的rpath中,运行时系统会自动从这个路径加载库。在build.rs中添加以下代码:
use std::env; fn main() { // 假设cmake构建的库在OUT_DIR下的lib目录中 let lib_path = format!("{}", env::var("OUT_DIR").unwrap() + "/lib"); // 向rustc传递rpath链接参数,用相对路径指向库位置 println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/{}", lib_path.strip_prefix(env::var("CARGO_TARGET_DIR").unwrap()).unwrap_or(&lib_path)); }
- 原理:
$ORIGIN表示当前可执行文件所在的目录,通过相对路径关联共享库位置,无需依赖环境变量。 - 注意:macOS系统需将
$ORIGIN替换为@loader_path。
2. 将共享库复制到系统标准库目录
把构建好的.so文件复制到系统默认搜索路径(如/usr/local/lib),并更新库缓存:
sudo cp /path/to/libxyz.so.1.0.0 /usr/local/lib/ sudo ldconfig
- 优点:全局生效,所有程序都能找到该库。
- 缺点:需要root权限,不适合开发阶段频繁更新的库,易污染系统环境。
3. 让cmake将库安装到cargo的target目录
在build.rs中配置cmake时,指定安装前缀为cargo的输出目录,让cmake自动把库安装到target下的标准位置:
use cmake::Config; use std::env; fn main() { let out_dir = env::var("OUT_DIR").unwrap(); let cmake_build = Config::new("path/to/cmake_project") .define("CMAKE_INSTALL_PREFIX", &out_dir) .build(); // 让cargo链接安装后的库 println!("cargo:rustc-link-search=native={}/lib", out_dir); println!("cargo:rustc-link-lib=dylib=xyz"); }
同时确保cmake项目的CMakeLists.txt包含安装规则:
install(TARGETS xyz LIBRARY DESTINATION lib)
- 原理:cmake安装后,库会被放到
OUT_DIR/lib下,cargo能自动搜索该路径,测试运行时可直接找到库。
4. 通过cargo配置文件自动设置环境变量
在项目根目录创建.cargo/config.toml,添加环境变量配置,让cargo运行test时自动加载LD_LIBRARY_PATH:
[env] # 绝对路径写法 LD_LIBRARY_PATH = "/path/to/library" # 相对项目根目录的路径写法 # LD_LIBRARY_PATH = { value = "./target/cmake-build/lib", relative = true }
- 优点:无需每次手动设置环境变量,本地开发时自动生效。
- 缺点:仅对当前项目生效,路径变更后需修改配置文件。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

