//! 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"); }