| // Copyright 2019 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| /// Minijail's build script invoked by cargo. | |
| /// | |
| /// This script prefers linking against a pkg-config provided libminijail, but will fall back to | |
| /// building libminijail statically. | |
| use std::env; | |
| use std::fs::remove_file; | |
| use std::path::Path; | |
| use anyhow::{Context, Result}; | |
| use bindgen::{Builder, EnumVariation}; | |
| static COMMON_CFLAGS: &[&str] = &[ | |
| "-DUSE_BINDGEN", | |
| "-D_FILE_OFFSET_BITS=64", | |
| "-D_LARGEFILE_SOURCE", | |
| "-D_LARGEFILE64_SOURCE", | |
| ]; | |
| fn get_bindgen_builder() -> Builder { | |
| bindgen::builder() | |
| .default_enum_style(EnumVariation::Rust { | |
| non_exhaustive: false, | |
| }) | |
| .layout_tests(false) | |
| .disable_header_comment() | |
| } | |
| fn generate_crossystem_bindings() -> Result<()> { | |
| let out_dir = env::var("OUT_DIR").unwrap(); | |
| let gen_file = Path::new(&out_dir).join("./crossystem.rs"); | |
| if gen_file.exists() { | |
| remove_file(&gen_file).expect("Failed to remove generated file."); | |
| } | |
| let header_dir = Path::new("."); | |
| let header_path = header_dir.join("crossystem.h"); | |
| println!("cargo:rerun-if-changed={}", header_path.display()); | |
| let bindings = get_bindgen_builder() | |
| .allowlist_function("Vb.*") | |
| .clang_args(COMMON_CFLAGS) | |
| .header(header_path.display().to_string()) | |
| .generate() | |
| .context("unable to generate bindings for crossystem.h")?; | |
| bindings | |
| .write_to_file(gen_file.display().to_string()) | |
| .context("unable to write bindings to file")?; | |
| Ok(()) | |
| } | |
| fn generate_vboot_host_binding() -> Result<()> { | |
| let out_dir = env::var("OUT_DIR").unwrap(); | |
| let gen_file = Path::new(&out_dir).join("./vboot_host.rs"); | |
| if gen_file.exists() { | |
| remove_file(&gen_file).expect("Failed to remove generated file."); | |
| } | |
| let header_dir = Path::new("."); | |
| let header_path = header_dir.join("vboot_host.h"); | |
| println!("cargo:rerun-if-changed={}", header_path.display()); | |
| for file in std::fs::read_dir("include")? { | |
| println!("cargo:rerun-if-changed={}", file?.path().display()); | |
| } | |
| let bindings = get_bindgen_builder() | |
| .allowlist_function("Cgpt.*") | |
| .allowlist_function(".*Guid.*") | |
| .allowlist_function("FindKernelConfig") | |
| .allowlist_function("ExtractVmlinuz") | |
| .allowlist_function("vb2_.*") | |
| .size_t_is_usize(false) | |
| .clang_args(COMMON_CFLAGS) | |
| .clang_arg("-Iinclude") | |
| .header(header_path.display().to_string()) | |
| .generate() | |
| .context("unable to generate bindings for vboot_host.h")?; | |
| bindings | |
| .write_to_file(gen_file.display().to_string()) | |
| .context("unable to write bindings to file")?; | |
| Ok(()) | |
| } | |
| fn main() -> Result<()> { | |
| if pkg_config::Config::new().probe("vboot_host").is_err() { | |
| // Fallback to generate bindings even if the library is not installed. | |
| println!("cargo:rustc-link-lib=dylib=vboot_host"); | |
| println!("cargo:rustc-link-lib=dylib=dl"); | |
| } | |
| generate_crossystem_bindings()?; | |
| generate_vboot_host_binding() | |
| } |