| // 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() |
| } |