Files
netdesk/native/vpx/build.rs
T

63 lines
2.9 KiB
Rust

//! Link the vendored static libvpx (UCRT MinGW ABI) + generate FFI bindings
//! from the vendored vpx headers via bindgen (libclang). RustDesk does the same
//! (its vpx.rs include!s an OUT_DIR/vpx_ffi.rs). We vendor a UCRT-ABI libvpx.a
//! so there is no vcpkg/MSYS2 or runtime DLL dependency.
use std::path::PathBuf;
fn main() {
let manifest = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let tp = manifest.join("..").join("third_party").join("ucrt64");
let lib = tp.join("lib");
let inc = tp.join("include");
println!("cargo:rustc-link-search=native={}", lib.display());
println!("cargo:rustc-link-lib=static=vpx");
println!("cargo:rustc-link-lib=pthread");
println!("cargo:rerun-if-changed=wrapper.h");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed={}", lib.join("libvpx.a").display());
// bindgen needs libclang; point at the installed LLVM if the env is unset.
if std::env::var("LIBCLANG_PATH").is_err() {
for p in ["C:/Program Files/LLVM/bin", "C:/Program Files (x86)/LLVM/bin"] {
if PathBuf::from(p).join("libclang.dll").exists() {
std::env::set_var("LIBCLANG_PATH", p);
break;
}
}
}
// Based on RustDesk's proven bindgen config (libs/scrap/build.rs): a single
// `^[vV].*` allowlist for types/vars/functions, rustified enums.
//
// vpx_codec_enc_cfg and vpx_codec_dec_cfg are forward-declared (by pointer)
// in vpx_codec.h's iface struct BEFORE vpx_encoder.h/vpx_decoder.h define
// them. libclang 22 then reports them to bindgen as incomplete, so bindgen
// emits them as opaque `_address: u8` blobs with no fields — making g_w /
// rc_target_bitrate / threads unsettable. (bindgen version, trust_clang_
// mangling, rustified_enum, and a by-value use all failed to change this.)
// So we blocklist both here and hand-write their exact #[repr(C)] layouts
// in src/lib.rs (ffi module) from the vendored headers. Everything else
// (vpx_image, cx_pkt, ctx, enums, functions) still comes from bindgen.
let regex = "^[vV].*";
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.clang_arg(format!("-I{}", inc.display()))
.allowlist_type(regex)
.allowlist_var(regex)
.allowlist_function(regex)
.rustified_enum(regex)
.blocklist_type("vpx_codec_enc_cfg")
.blocklist_type("vpx_codec_enc_cfg_t")
.blocklist_type("vpx_codec_dec_cfg")
.blocklist_type("vpx_codec_dec_cfg_t")
.trust_clang_mangling(false)
.layout_tests(false)
.generate_comments(false)
.generate()
.expect("bindgen libvpx");
bindings
.write_to_file(PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("vpx_ffi.rs"))
.expect("write vpx_ffi.rs");
}