Rust Bindgen在MacOS 14上链接C头文件失败,未找到lib

eqqqjvef  于 12个月前  发布在  Mac
关注(0)|答案(1)|浏览(249)

我正在为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/


链接到文件,我已经添加:

我尝试过的事情:

  • 在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链接器相对于哪个文件夹查找库?

6ju8rftf

6ju8rftf1#

显然,问题是提供的dylib是为AMD 64编译的,但不知何故,不清楚是否有ARM-64版本。推荐的解决方案是为AMD/Intel交叉编译,并通过Rosetta在ARM/Apple芯片上运行二进制文件。

相关问题