我正在为quaser DB开发一个Rust Package 器,它为所有FFI客户端提供了一个C API。
我使用Bindgen来生成Rust绑定,它工作得很好,这意味着我生成了所有绑定,并针对它们编写了一些测试代码。
然而,测试没有运行,因为C头文件依赖于一个名为libqdb_API的dylib链接,不知何故,我无法说服cargo找到链接所需的这个lib。
问题是:我如何配置cargo来查找项目文件夹中的dylib?
我做了什么:
- 已将C API复制到项目的根文件夹中
- 相对路径:qdb/lib
- 添加了bindgen作为cargo. toml的开发依赖项。
- 通过brew安装llvm
- 在build.rs中设置LLVM_CONFIG_PATH和LIBCLANG_PATH
- 编写了一个 Package 文件,以包含用于生成绑定的头
- 编写了一个构建文件,请参见下面:
use std::env;
use std::path::PathBuf;
fn main() {
let key = "LLVM_CONFIG_PATH";
env::set_var(key, env::var(key).unwrap_or("/opt/homebrew/opt/llvm/bin/llvm-config".to_string()));
// https://rust-lang.github.io/rust-bindgen/requirements.html#clang
let key = "LIBCLANG_PATH";
env::set_var(key, env::var(key).unwrap_or("/opt/homebrew/opt/llvm/lib".to_string()));
// Tell cargo to look for shared libraries in the specified directory
println!("cargo:rustc-link-search=dylib=/Users/marvin/CLionProjects/quasar-rs/qdb/lib/");
// Tell rustc to link the qdb library.
println!("cargo:rustc-link-lib=dylib=libqdb_api");
// Tell cargo to invalidate the built crate whenever the wrapper changes
println!("cargo:rerun-if-changed=wrapper.h");
// The bindgen::Builder is the main entry point to bindgen,
// and lets you build up options for the resulting bindings.
let bindings = bindgen::Builder::default()
// Derive debug implementation for structs and enums
.derive_debug(true)
// The input header we would like to generate bindings for.
.header("wrapper.h")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
// The resulting bindings will be written to $OUT_DIR/bindings.rs where $OUT_DIR is chosen by cargo and is something like
// ./target/debug/build/quasar-rs..../out/.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
字符串
货物测试结果出现以下错误:
= note: ld: warning: search path 'dylib=qdb/lib/' not found
ld: library 'libqdb_api' not found
clang: error: linker command failed with exit code 1 (use -v to see invocation)
型
我怀疑输出中的链接器参数:
"-L" "dylib=qdb/lib/" "-L" "/Users/marvin/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/lib" "-llibqdb_api" "/Users/marvin/
型
链接到文件,我已经添加:
- wrapper-似乎工作正常,因为绑定生成
- Cargo.toml-不知道在此配置w.r.t. lib路径
- build.rs的
- The repo的
我尝试过的事情:
- 在build.rs中配置绝对路径-相同错误
- 在build.rs中配置相对于项目的路径-相同错误
- 导出DYLD_LIBRARY_PATH -相同错误
- 导出DYLD_BELLBACK_LIBRARY_PATH -相同错误
- 将库复制到目标并将路径设置为B/C有人发布路径是相对于目标文件夹的-相同错误
当我使用CARGO_MANIFEST_MANIFenv变量来构造正确的lib文件夹的完整绝对路径时,cargo test抛出另一个错误,即使路径实际上是正确的,这意味着lib实际上在那里。
ld: warning: search path 'dylib=/Users/marvin/CLionProjects/quasar-rs/qdb/lib/' not found
ld: library 'libqdb_api' not found
clang: error: linker command failed with exit code 1 (use -v to see invocation)
型
到目前为止,没有任何工作。我在网上搜索了很多,但我只发现了多个相互冲突的想法,没有一个工作。我有点困惑,在这一点上,因为我从来没有这样的东西在Linux,但显然MacOS是完全不同的。
如何在MacOS上正确配置cargo以在项目文件夹中找到dylib?
更具体地说,C链接器相对于哪个文件夹查找库?
1条答案
按热度按时间6ju8rftf1#
显然,问题是提供的dylib是为AMD 64编译的,但不知何故,不清楚是否有ARM-64版本。推荐的解决方案是为AMD/Intel交叉编译,并通过Rosetta在ARM/Apple芯片上运行二进制文件。