xref: /aosp_15_r20/external/vboot_reference/rust/vboot_reference-sys/build.rs (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 // Copyright 2019 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 /// Minijail's build script invoked by cargo.
6 ///
7 /// This script prefers linking against a pkg-config provided libminijail, but will fall back to
8 /// building libminijail statically.
9 use std::env;
10 use std::fs::remove_file;
11 use std::path::Path;
12 
13 use anyhow::{Context, Result};
14 use bindgen::{Builder, EnumVariation};
15 
16 static COMMON_CFLAGS: &[&str] = &[
17     "-DUSE_BINDGEN",
18     "-D_FILE_OFFSET_BITS=64",
19     "-D_LARGEFILE_SOURCE",
20     "-D_LARGEFILE64_SOURCE",
21 ];
22 
get_bindgen_builder() -> Builder23 fn get_bindgen_builder() -> Builder {
24     bindgen::builder()
25         .default_enum_style(EnumVariation::Rust {
26             non_exhaustive: false,
27         })
28         .layout_tests(false)
29         .disable_header_comment()
30 }
31 
generate_crossystem_bindings() -> Result<()>32 fn generate_crossystem_bindings() -> Result<()> {
33     let out_dir = env::var("OUT_DIR").unwrap();
34     let gen_file = Path::new(&out_dir).join("./crossystem.rs");
35     if gen_file.exists() {
36         remove_file(&gen_file).expect("Failed to remove generated file.");
37     }
38     let header_dir = Path::new(".");
39     let header_path = header_dir.join("crossystem.h");
40     println!("cargo:rerun-if-changed={}", header_path.display());
41 
42     let bindings = get_bindgen_builder()
43         .allowlist_function("Vb.*")
44         .clang_args(COMMON_CFLAGS)
45         .header(header_path.display().to_string())
46         .generate()
47         .context("unable to generate bindings for crossystem.h")?;
48 
49     bindings
50         .write_to_file(gen_file.display().to_string())
51         .context("unable to write bindings to file")?;
52 
53     Ok(())
54 }
55 
generate_vboot_host_binding() -> Result<()>56 fn generate_vboot_host_binding() -> Result<()> {
57     let out_dir = env::var("OUT_DIR").unwrap();
58     let gen_file = Path::new(&out_dir).join("./vboot_host.rs");
59     if gen_file.exists() {
60         remove_file(&gen_file).expect("Failed to remove generated file.");
61     }
62     let header_dir = Path::new(".");
63     let header_path = header_dir.join("vboot_host.h");
64     println!("cargo:rerun-if-changed={}", header_path.display());
65     for file in std::fs::read_dir("include")? {
66         println!("cargo:rerun-if-changed={}", file?.path().display());
67     }
68 
69     let bindings = get_bindgen_builder()
70         .allowlist_function("Cgpt.*")
71         .allowlist_function(".*Guid.*")
72         .allowlist_function("FindKernelConfig")
73         .allowlist_function("ExtractVmlinuz")
74         .allowlist_function("vb2_.*")
75         .size_t_is_usize(false)
76         .clang_args(COMMON_CFLAGS)
77         .clang_arg("-Iinclude")
78         .header(header_path.display().to_string())
79         .generate()
80         .context("unable to generate bindings for vboot_host.h")?;
81 
82     bindings
83         .write_to_file(gen_file.display().to_string())
84         .context("unable to write bindings to file")?;
85 
86     Ok(())
87 }
88 
main() -> Result<()>89 fn main() -> Result<()> {
90     if pkg_config::Config::new().probe("vboot_host").is_err() {
91         // Fallback to generate bindings even if the library is not installed.
92         println!("cargo:rustc-link-lib=dylib=vboot_host");
93         println!("cargo:rustc-link-lib=dylib=dl");
94     }
95     generate_crossystem_bindings()?;
96     generate_vboot_host_binding()
97 }
98