use std::{
env, fs,
path::{Path, PathBuf},
};
fn collect_cpp_files(dir: &Path) -> Vec<PathBuf> {
let mut files = fs::read_dir(dir)
.unwrap_or_else(|error| panic!("failed to read {}: {error}", dir.display()))
.filter_map(|entry| {
let path = entry.ok()?.path();
(path.extension().and_then(|ext| ext.to_str()) == Some("cpp")).then_some(path)
})
.collect::<Vec<_>>();
files.sort();
files
}
fn main() {
let manifest_dir = PathBuf::from(
env::var_os("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env variable not set"),
);
let bento4_root = manifest_dir.join("vendor").join("bento4-src");
let source_root = bento4_root.join("Source").join("C++");
if !source_root.join("Core").join("Ap4.h").exists() {
panic!(
"Bento4 source snapshot is missing. Expected sources under {}",
manifest_dir.join("vendor").join("bento4-src").display()
);
}
println!("cargo:rerun-if-changed={}", bento4_root.display());
println!("cargo:rerun-if-changed=src/native/rsmp4decrypt.cpp");
println!("cargo:rerun-if-changed=src/native/rsmp4decrypt.h");
let include_dirs = [
source_root.join("Core"),
source_root.join("Codecs"),
source_root.join("Crypto"),
source_root.join("MetaData"),
];
let mut build = cc::Build::new();
build
.cpp(true)
.warnings(false)
.extra_warnings(false)
.includes(include_dirs);
for component in ["Codecs", "Core", "Crypto", "MetaData"] {
for file in collect_cpp_files(&source_root.join(component)) {
build.file(file);
}
}
build.file(
source_root
.join("System")
.join("StdC")
.join("Ap4StdCFileByteStream.cpp"),
);
let random_source = if env::var("CARGO_CFG_TARGET_OS")
.expect("CARGO_CFG_TARGET_OS env variable not set")
== "windows"
{
source_root
.join("System")
.join("Win32")
.join("Ap4Win32Random.cpp")
} else {
source_root
.join("System")
.join("Posix")
.join("Ap4PosixRandom.cpp")
};
build.file(random_source);
build.file(
manifest_dir
.join("src")
.join("native")
.join("rsmp4decrypt.cpp"),
);
build.compile("rsmp4decrypt");
}