84 lines
3.2 KiB
Rust
Executable File
84 lines
3.2 KiB
Rust
Executable File
// build.rs — generate raw FFI bindings to libmpv via bindgen.
|
|
//
|
|
// We resolve libmpv through pkg-config. The setup script generates
|
|
// mpv-prefix/usr/lib/x86_64-linux-gnu/pkgconfig/mpv.pc and exports
|
|
// PKG_CONFIG_PATH via mpv-prefix/env.sh — `cargo build` picks it up
|
|
// automatically once env.sh is sourced.
|
|
//
|
|
// The generated bindings end up in OUT_DIR/bindings.rs and are re-exported
|
|
// from `crate::sys`.
|
|
|
|
use std::env;
|
|
use std::path::PathBuf;
|
|
|
|
fn main() {
|
|
// Re-run if the env or any pkg-config .pc file under the prefix changes.
|
|
println!("cargo:rerun-if-env-changed=PKG_CONFIG_PATH");
|
|
if let Ok(prefix) = env::var("MPV_PREFIX") {
|
|
let pc = PathBuf::from(&prefix)
|
|
.join("usr/lib/x86_64-linux-gnu/pkgconfig/mpv.pc");
|
|
println!("cargo:rerun-if-changed={}", pc.display());
|
|
}
|
|
|
|
let mpv = pkg_config::Config::new()
|
|
.atleast_version("2.0")
|
|
.probe("mpv")
|
|
.expect("failed to locate libmpv via pkg-config (did you `source ./mpv-prefix/env.sh`?)");
|
|
|
|
// Tell cargo to link libmpv.
|
|
for path in &mpv.link_paths {
|
|
println!("cargo:rustc-link-search=native={}", path.display());
|
|
}
|
|
println!("cargo:rustc-link-lib=dylib=mpv");
|
|
|
|
// Embed rpath so the binary finds libmpv.so.2 at runtime without
|
|
// requiring LD_LIBRARY_PATH. We use the first link path from pkg-config.
|
|
if let Some(first) = mpv.link_paths.first() {
|
|
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", first.display());
|
|
}
|
|
|
|
// Find the canonical client.h — it #includes the other public headers.
|
|
let client_h = mpv
|
|
.include_paths
|
|
.iter()
|
|
.map(|p| p.join("mpv/client.h"))
|
|
.find(|p| p.exists())
|
|
.expect("could not find mpv/client.h in include paths");
|
|
|
|
// Clang's builtin headers (stddef.h etc.) — needed because we ship our
|
|
// own libclang without a system sysroot.
|
|
let clang_resource_dir = env::var("CLANG_RESOURCE_DIR")
|
|
.unwrap_or_else(|_| "/usr/lib/llvm-19/lib/clang/19".to_string());
|
|
let clang_include = format!("{clang_resource_dir}/include");
|
|
|
|
let bindings = bindgen::Builder::default()
|
|
.header(client_h.to_string_lossy().into_owned())
|
|
// Pull in the other public headers transitively.
|
|
.clang_arg("-include")
|
|
.clang_arg("mpv/render.h")
|
|
.clang_arg("-include")
|
|
.clang_arg("mpv/render_gl.h")
|
|
.clang_arg("-include")
|
|
.clang_arg("mpv/stream_cb.h")
|
|
// Clang builtin headers (stddef.h, stdarg.h, etc.)
|
|
.clang_arg("-isystem")
|
|
.clang_arg(&clang_include)
|
|
// Allowlist: only the public mpv API surface.
|
|
.allowlist_function("mpv_.*")
|
|
.allowlist_type("mpv_.*")
|
|
.allowlist_var("MPV_.*")
|
|
.allowlist_var("mpv_.*")
|
|
// Layout tests break across glibc versions for some reason; we don't need them.
|
|
.layout_tests(false)
|
|
.derive_default(true)
|
|
.derive_debug(true)
|
|
.fit_macro_constants(false)
|
|
.generate()
|
|
.expect("bindgen failed to generate mpv bindings");
|
|
|
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
bindings
|
|
.write_to_file(out_path.join("bindings.rs"))
|
|
.expect("failed to write bindings.rs");
|
|
}
|