blob: e3eb501dc748f973aa8a5121a1708943c8913f3d [file] [log] [blame]
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Build rust library and bindings for libyuv.
use std::env;
use std::path::Path;
use std::path::PathBuf;
fn path_buf(inputs: &[&str]) -> PathBuf {
let path: PathBuf = inputs.iter().collect();
path
}
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let build_target = std::env::var("TARGET").unwrap();
let build_dir = if build_target.contains("android") {
if build_target.contains("x86_64") {
"build.android/x86_64"
} else if build_target.contains("x86") {
"build.android/x86"
} else if build_target.contains("aarch64") {
"build.android/arm64-v8a"
} else if build_target.contains("arm") {
"build.android/armeabi-v7a"
} else {
panic!("Unknown target_arch for android. Must be one of x86, x86_64, arm, aarch64.");
}
} else {
"build"
};
let project_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let abs_library_dir = PathBuf::from(&project_root).join("libyuv");
let abs_object_dir = PathBuf::from(&abs_library_dir).join(build_dir);
let library_file = PathBuf::from(&abs_object_dir).join(if cfg!(target_os = "windows") {
"yuv.lib"
} else {
"libyuv.a"
});
let extra_includes_str;
if Path::new(&library_file).exists() {
println!("cargo:rustc-link-lib=static=yuv");
println!("cargo:rustc-link-search={}", abs_object_dir.display());
let version_dir = PathBuf::from(&abs_library_dir).join(path_buf(&["include"]));
extra_includes_str = format!("-I{}", version_dir.display());
} else {
// Local library was not found. Look for a system library.
match pkg_config::Config::new().probe("yuv") {
Ok(library) => {
for lib in &library.libs {
println!("cargo:rustc-link-lib={lib}");
}
for link_path in &library.link_paths {
println!("cargo:rustc-link-search={}", link_path.display());
}
let mut include_str = String::new();
for include_path in &library.include_paths {
include_str.push_str("-I");
include_str.push_str(include_path.to_str().unwrap());
}
extra_includes_str = include_str;
}
Err(_) => {
// Try to build without any extra flags.
println!("cargo:rustc-link-lib=yuv");
extra_includes_str = String::new();
}
}
}
// Generate bindings.
let header_file = PathBuf::from(&project_root).join("wrapper.h");
let outdir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
let outfile = PathBuf::from(&outdir).join("libyuv_bindgen.rs");
let mut bindings = bindgen::Builder::default()
.header(header_file.into_os_string().into_string().unwrap())
.clang_arg(extra_includes_str)
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.layout_tests(false)
.generate_comments(false);
let allowlist_items = &[
"YuvConstants",
"FilterMode",
"ARGBAttenuate",
"ARGBToABGR",
"ARGBUnattenuate",
"Convert16To8Plane",
"HalfFloatPlane",
"ScalePlane_12",
"ScalePlane",
"FilterMode_kFilterBilinear",
"FilterMode_kFilterBox",
"FilterMode_kFilterNone",
"I010AlphaToARGBMatrixFilter",
"I010AlphaToARGBMatrix",
"I010ToARGBMatrixFilter",
"I010ToARGBMatrix",
"I012ToARGBMatrix",
"I210AlphaToARGBMatrixFilter",
"I210AlphaToARGBMatrix",
"I210ToARGBMatrixFilter",
"I210ToARGBMatrix",
"I400ToARGBMatrix",
"I410AlphaToARGBMatrix",
"I410ToARGBMatrix",
"I420AlphaToARGBMatrixFilter",
"I420AlphaToARGBMatrix",
"I420ToARGBMatrixFilter",
"I420ToARGBMatrix",
"I420ToRGB24MatrixFilter",
"I420ToRGB24Matrix",
"I420ToRGB565Matrix",
"I420ToRGBAMatrix",
"I422AlphaToARGBMatrixFilter",
"I422AlphaToARGBMatrix",
"I422ToARGBMatrixFilter",
"I422ToARGBMatrix",
"I422ToRGB24MatrixFilter",
"I422ToRGB565Matrix",
"I422ToRGBAMatrix",
"I444AlphaToARGBMatrix",
"I444ToARGBMatrix",
"I444ToRGB24Matrix",
"NV12ToARGBMatrix",
"NV21ToARGBMatrix",
"P010ToAR30Matrix",
"P010ToARGBMatrix",
"AR30ToAB30",
"kYuv2020Constants",
"kYuvF709Constants",
"kYuvH709Constants",
"kYuvI601Constants",
"kYuvJPEGConstants",
"kYuvV2020Constants",
"kYvu2020Constants",
"kYvuF709Constants",
"kYvuH709Constants",
"kYvuI601Constants",
"kYvuJPEGConstants",
"kYvuV2020Constants",
];
for allowlist_item in allowlist_items {
bindings = bindings.allowlist_item(allowlist_item);
}
let bindings = bindings
.generate()
.unwrap_or_else(|_| panic!("Unable to generate bindings for libyuv."));
bindings
.write_to_file(outfile.as_path())
.unwrap_or_else(|_| panic!("Couldn't write bindings for libyuv"));
}