Rust Bindgen因头文件相对路径问题编译失败求助
问题:为VMAF生成Rust绑定时头文件找不到错误
尝试为VMAF生成Rust绑定,遇到头文件查找失败的问题:VMAF仓库的头文件与.c文件分属不同目录,主头文件vmaf.h用相对路径引用同目录下的其他.h文件,导致rust-bindgen报错:'libvmaf/compute_vmaf.h' file not found。
项目目录结构:
. ├── src # lib.rs 所在目录 ├── target │ └── debug └── vmaf ├── libvmaf │ ├── doc │ ├── include │ │ └── libvmaf # vmaf.h及其他.h文件所在目录 │ ├── src # 其他.h文件所在目录 │ │ ├── arm │ │ ├── compat │ │ ├── ext │ │ ├── feature │ │ └── x86 │ ├── test │ └── tools
当前使用的build.rs代码:
extern crate meson; use std::env; use std::path::PathBuf; fn main() { //env::set_var("RUST_BACKTRACE", "1"); let build_path = PathBuf::from(env::var("OUT_DIR").unwrap()); _ = build_path.join("build"); let build_path = build_path.to_str().unwrap(); println!("cargo:rustc-link-lib=libvmaf"); println!("cargo:rustc-link-search=native={build_path}"); meson::build("vmaf/libvmaf", build_path); let bindings = bindgen::Builder::default() .header("vmaf/libvmaf/include/libvmaf/libvmaf.h") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() .expect("Unable to generate bindings"); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings.write_to_file(out_path).expect("Couldn't write bindings!"); }
疑问:
- 如何让rust-bindgen找到正确的头文件目录?
- 使用
cargo:rustc-link-search指向该目录是否会影响已通过meson编译的库链接?
解决方案
1. 让bindgen找到正确的头文件目录
bindgen依赖Clang解析头文件,需要明确告诉Clang头文件的搜索路径。针对你的目录结构,需要添加两个关键的搜索路径:
vmaf/libvmaf/include:vmaf.h中引用libvmaf/compute_vmaf.h时,Clang需要从这个目录出发找到libvmaf子目录vmaf/libvmaf/src:如果代码中引用了src目录下子文件夹(比如compat、ext)里的头文件,也需要添加这个路径
修改build.rs中的bindgen构建部分,添加.clang_arg()传入这些路径:
let bindings = bindgen::Builder::default() .header("vmaf/libvmaf/include/libvmaf/libvmaf.h") // 添加include目录到Clang搜索路径 .clang_arg("-Ivmaf/libvmaf/include") // 如果需要src目录下的头文件,添加这一行 .clang_arg("-Ivmaf/libvmaf/src") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() .expect("Unable to generate bindings");
如果担心相对路径的问题(比如构建时的工作目录变化),可以改用绝对路径:
let include_dir = PathBuf::from(env::current_dir().unwrap()).join("vmaf/libvmaf/include"); let src_dir = PathBuf::from(env::current_dir().unwrap()).join("vmaf/libvmaf/src"); let bindings = bindgen::Builder::default() .header("vmaf/libvmaf/include/libvmaf/libvmaf.h") .clang_arg(format!("-I{}", include_dir.to_str().unwrap())) .clang_arg(format!("-I{}", src_dir.to_str().unwrap())) .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .generate() .expect("Unable to generate bindings");
2. 关于cargo:rustc-link-search的影响
cargo:rustc-link-search=native={path}是告诉Rust编译器去哪里找编译好的库文件(比如.a、.so或.dll),和头文件搜索路径完全无关,不会影响meson编译好的库链接。
不过需要注意:meson编译完成后,库文件通常会放在build_path的子目录(比如lib),你当前的代码直接用build_path可能找不到库。可以调整路径为:
let build_lib_path = build_path.join("lib").to_str().unwrap(); println!("cargo:rustc-link-search=native={build_lib_path}");
具体子目录需要根据meson的编译输出结构调整。
内容的提问来源于stack exchange,提问作者Brandon Piña
相关产品推荐
相关产品推荐

