63 lines
2.9 KiB
Rust
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");
|
|
}
|