rust - build.rs 找不到 native 静态库 'libvmaf,可能缺少 -L 标志?

标签 rust linker linker-errors

我正尝试在 Rust 中生成到 libvmaf 的绑定(bind)。我已将 vmaf 作为 git 子模块导入,我的构建步骤似乎正常工作,因为当我检查构建工件时,我可以看到文件正在按预期生成。

这是我遇到的具体错误:

cargo build
   Compiling libvmaf-rs v0.1.0 (/home/brandon/repos/libvmaf-rs)
error: could not find native static library `libvmaf`, perhaps an -L flag is missing?

error: could not compile `libvmaf-rs` due to previous error

这是构建目录的树,深度为四; 我关心的静态库在 ./out/build/src/libvmaf.a

.
├── invoked.timestamp
├── out
│   ├── bindings.rs
│   └── build
│       ├── build.ninja
│       ├── compile_commands.json
│       ├── doc
│       ├── include
│       │   ├── libvmaf
│       │   └── vcs_version.h
│       ├── meson-info
│       │   ├── intro-benchmarks.json
│       │   ├── intro-buildoptions.json
│       │   ├── intro-buildsystem_files.json
│       │   ├── intro-dependencies.json
│       │   ├── intro-installed.json
│       │   ├── intro-install_plan.json
│       │   ├── intro-projectinfo.json
│       │   ├── intro-targets.json
│       │   ├── intro-tests.json
│       │   └── meson-info.json
│       ├── meson-logs
│       │   └── meson-log.txt
│       ├── meson-private
│       │   ├── build.dat
│       │   ├── cleantrees.dat
│       │   ├── cmd_line.txt
│       │   ├── coredata.dat
│       │   ├── install.dat
│       │   ├── libvmaf.pc
│       │   ├── meson_benchmark_setup.dat
│       │   ├── meson.lock
│       │   ├── meson_test_setup.dat
│       │   ├── sanitycheckc.c
│       │   ├── sanitycheckc.exe
│       │   ├── sanitycheckcpp.cc
│       │   └── sanitycheckcpp.exe
│       ├── meson-uninstalled
│       │   └── libvmaf-uninstalled.pc
│       ├── src
│       │   ├── config.asm
│       │   ├── config.h
│       │   ├── liblibvmaf_cpu.a
│       │   ├── liblibvmaf_cpu.a.p
│       │   ├── liblibvmaf_feature.a
│       │   ├── liblibvmaf_feature.a.p
│       │   ├── libvmaf.a # Trying to link to this!
│       │   ├── libvmaf.a.p
│       │   ├── libvmaf.so -> libvmaf.so.1
│       │   ├── libvmaf.so.1 -> libvmaf.so.1.1.3
│       │   ├── libvmaf.so.1.1.3
│       │   ├── libvmaf.so.1.1.3.p
│       │   ├── libx86_avx2.a
│       │   ├── libx86_avx2.a.p
│       │   ├── vmaf_4k_v0.6.1.json
│       │   ├── vmaf_4k_v0.6.1.json.c
│       │   ├── vmaf_b_v0.6.3.json
│       │   ├── vmaf_b_v0.6.3.json.c
│       │   ├── vmaf_v0.6.1.json
│       │   ├── vmaf_v0.6.1.json.c
│       │   ├── vmaf_v0.6.1neg.json
│       │   └── vmaf_v0.6.1neg.json.c
│       ├── test
│       │   ├── test_cambi
│       │   ├── test_cambi.p
│       │   ├── test_ciede
│       │   ├── test_ciede.p
│       │   ├── test_context
│       │   ├── test_context.p
│       │   ├── test_cpu
│       │   ├── test_cpu.p
│       │   ├── test_dict
│       │   ├── test_dict.p
│       │   ├── test_feature
│       │   ├── test_feature_collector
│       │   ├── test_feature_collector.p
│       │   ├── test_feature_extractor
│       │   ├── test_feature_extractor.p
│       │   ├── test_feature.p
│       │   ├── test_log
│       │   ├── test_log.p
│       │   ├── test_luminance_tools
│       │   ├── test_luminance_tools.p
│       │   ├── test_model
│       │   ├── test_model.p
│       │   ├── test_picture
│       │   ├── test_picture.p
│       │   ├── test_predict
│       │   ├── test_predict.p
│       │   ├── test_ref
│       │   ├── test_ref.p
│       │   ├── test_thread_pool
│       │   └── test_thread_pool.p
│       └── tools
│           ├── vmaf
│           ├── vmafossexec
│           ├── vmafossexec.p
│           └── vmaf.p
├── output
├── root-output
└── stderr

这是我的 build.rs 文件

extern crate meson;
use std::env;
use std::fs::canonicalize;
use std::path::PathBuf;

fn main() {
    //env::set_var("RUST_BACKTRACE", "1");
    let build_dir = PathBuf::from(env::var("OUT_DIR").unwrap()).join("build");
    let lib_dir = build_dir.join("src");

    let build_dir_str = build_dir.to_str().unwrap();
    let lib_dir_str = lib_dir.to_str().unwrap();

    meson::build("vmaf/libvmaf", build_dir_str);

    println!("cargo:rustc-link-lib=static=libvmaf");
    println!("cargo:rustc-link-search=native={lib_dir_str}"); // I believe this linker option is the problem

    // Path to vendor header files
    let headers_dir = PathBuf::from("vmaf/libvmaf/include");
    let headers_dir_canonical = canonicalize(headers_dir).unwrap();
    let include_path = headers_dir_canonical.to_str().unwrap();

    // Generate bindings to libvmaf using rust-bindgen
    let bindings = bindgen::Builder::default()
        .header("vmaf/libvmaf/include/libvmaf/libvmaf.h")
        .clang_arg(format!("-I{include_path}"))
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()
        .expect("Unable to generate bindings");

    // Write bindings to build directory
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

据我所知,我的 cargo:rustc-link-search 链接器选项是正确的,但我可以使用一些指导来了解为什么链接器找不到 libvmaf

-- 编辑:我在构建脚本中添加了一部分,将 lib_dir_str 输出到 stderr 此外,我在将 lib_dir 转换为字符串之前规范化了 lib_dir 以查看是否有帮助。在构建目录中,我可以看到一个包含 stderr 输出的文件。如果我 ls 我希望找到(并链接到)libvmaf.a 的构建目录部分的规范路径,我可以按照我的预期看到 libvmaf.a。 如果我理解正确,cargo:rustc-link-search 选项等同于编译器中的 -L 标志,所以我很困惑为什么要检查目录,我可以看到我想要链接到的 native 静态库,但 cargo 仍然无法找到并链接到 libvmaf。

--edit 使用 cargo build -v 我可以看到构建命令的详细输出。这样我就可以准确地看到 rustc 是如何被调用的

`rustc --crate-name libvmaf_rs --edition=2021 src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 -C metadata=5225226d4097e5e3 -C extra-filename=-5225226d4097e5e3 --out-dir /home/brandon/repos/libvmaf-rs/target/debug/deps -C incremental=/home/brandon/repos/libvmaf-rs/target/debug/incremental -L dependency=/home/brandon/repos/libvmaf-rs/target/debug/deps -L native=/home/brandon/repos/libvmaf-rs/target/debug/build/libvmaf-rs-f8ca4c95356c61cf/out/build/src -l static=libvmaf`

如您所见,有两个 -L 参数传递给编译器,而 -l 参数设置为 libvmaf

最佳答案

在类 unix 系统上,编译器和链接器会自动将 lib 后缀添加到您通过 -l 提供的库名称中。因此你需要你的 build.rs 发出:

cargo:rustc-link-lib=static=vmaf

有一个链接修饰符 verbatim 可以用来抑制这种行为,但它是 currently unstable .在任何情况下我都不会推荐它 - 在类 unix 系统上,约定是所有库都以 lib 为前缀,而在 Windows 上不是这种情况,因此让编译器根据平台是个好东西。

关于rust - build.rs 找不到 native 静态库 'libvmaf,可能缺少 -L 标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74469691/

相关文章:

rust - "overflow evaluating the requirement"尝试延迟关联类型时

linux - 使用较新版本的 glibc 时出错

C++ 模板链表链接器错误

c++ - C++共享库中基类的 undefined symbol 错误

rust - Rust 是如何编译成机器码的?

vector - 需要矢量切片才能活得更久

rust - 如何使用 Rust Hyper HTTP 客户端将请求绑定(bind)到特定的网络接口(interface)?

c++ - 为什么链接器不提示重复的符号?

c - 在两个模块之间共享 sizeof(array)

c++ - 静态类成员,这是一个结构