Rust Bindgen не удается связать заголовки C в MacOS 14, библиотека не найдена

Я работаю над оболочкой Rust для базы данных quaser, которая имеет API C для всех клиентов FFI.

Я использую Bindgen для генерации привязок Rust, и это работает хорошо, то есть я сгенерировал все привязки и написал для них некоторый тестовый код, который компилируется.

Однако тесты не запускаются, потому что заголовочные файлы C полагаются на связывание с dylib под названием libqdb_api, и почему-то я не могу убедить Cargo найти эту библиотеку, необходимую для связывания.

Вопрос в следующем: как мне настроить груз, чтобы найти dylib, который находится в папке проекта?

Что я сделал:

  1. Скопировал C API в корневую папку проекта.
    • относительный путь: qdb/lib
  2. Добавлен привязка в качестве зависимости разработчика к Cargo.toml.
  3. Установил llvm через Brew.
  4. Установите LLVM_CONFIG_PATH и LIBCLANG_PATH в build.rs.
  5. Написал файл-оболочку, включающий заголовки для генерации привязок.
  6. Написал файл сборки, см. ниже:
      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/

Ссылки на файлы, которые я добавил:

  • оболочка - кажется, работает нормально, поскольку привязки генерируют
  • Cargo.toml — не знаю, что здесь настроить относительно путей к библиотекам
  • build.rs
  • Репо

Вещи, которые я пробовал:

  • Настройте абсолютный путь в build.rs – та же ошибка
  • Настройте путь относительно проекта в build.rs – та же ошибка
  • экспортировать DYLD_LIBRARY_PATH – та же ошибка
  • экспортировать DYLD_FALLBACK_LIBRARY_PATH – та же ошибка
  • Скопировал библиотеку в целевую папку и установил туда путь, потому что кто-то написал, что пути относятся к целевой папке - та же ошибка.

Когда я использую переменную env CARGO_MANIFEST_DIR для создания полного абсолютного пути к правильной папке библиотеки, тест груза выдает еще одну ошибку, хотя путь на самом деле правильный, что означает, что библиотека действительно существует.

       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, чтобы найти dylib в папке проекта?

Точнее, относительно какой папки компоновщик C ищет библиотеки?

0 ответов

Другие вопросы по тегам