Rust Bindgen не удается связать заголовки C в MacOS 14, библиотека не найдена
Я работаю над оболочкой Rust для базы данных quaser, которая имеет API C для всех клиентов FFI.
Я использую Bindgen для генерации привязок Rust, и это работает хорошо, то есть я сгенерировал все привязки и написал для них некоторый тестовый код, который компилируется.
Однако тесты не запускаются, потому что заголовочные файлы C полагаются на связывание с dylib под названием libqdb_api, и почему-то я не могу убедить Cargo найти эту библиотеку, необходимую для связывания.
Вопрос в следующем: как мне настроить груз, чтобы найти dylib, который находится в папке проекта?
Что я сделал:
- Скопировал C API в корневую папку проекта.
- относительный путь: qdb/lib
- Добавлен привязка в качестве зависимости разработчика к Cargo.toml.
- Установил llvm через Brew.
- Установите LLVM_CONFIG_PATH и LIBCLANG_PATH в build.rs.
- Написал файл-оболочку, включающий заголовки для генерации привязок.
- Написал файл сборки, см. ниже:
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 ищет библиотеки?