xref: /aosp_15_r20/external/crosvm/crosvm_control/build.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::env;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::fs;
7*bb4ee6a4SAndroid Build Coastguard Worker use std::path::PathBuf;
8*bb4ee6a4SAndroid Build Coastguard Worker 
9*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::bail;
10*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Context;
11*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Result;
12*bb4ee6a4SAndroid Build Coastguard Worker use cbindgen::Config;
13*bb4ee6a4SAndroid Build Coastguard Worker use cbindgen::EnumConfig;
14*bb4ee6a4SAndroid Build Coastguard Worker use cbindgen::Language;
15*bb4ee6a4SAndroid Build Coastguard Worker use cbindgen::RenameRule;
16*bb4ee6a4SAndroid Build Coastguard Worker use tempfile::TempDir;
17*bb4ee6a4SAndroid Build Coastguard Worker 
18*bb4ee6a4SAndroid Build Coastguard Worker static COPYRIGHT_CLAUSE: &str = "// Copyright 2022 The ChromiumOS Authors
19*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
20*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.";
21*bb4ee6a4SAndroid Build Coastguard Worker 
22*bb4ee6a4SAndroid Build Coastguard Worker static AUTOGENERATED_DISCLAIMER: &str =
23*bb4ee6a4SAndroid Build Coastguard Worker     "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */";
24*bb4ee6a4SAndroid Build Coastguard Worker 
25*bb4ee6a4SAndroid Build Coastguard Worker static INCLUDE_GUARD: &str = "CROSVM_CONTROL_H_";
26*bb4ee6a4SAndroid Build Coastguard Worker 
27*bb4ee6a4SAndroid Build Coastguard Worker static CROSVM_CONTROL_HEADER_NAME: &str = "crosvm_control.h";
28*bb4ee6a4SAndroid Build Coastguard Worker 
29*bb4ee6a4SAndroid Build Coastguard Worker static REGISTERED_EVENTS_PROTO_FILENAME: &str = "registered_events.proto";
30*bb4ee6a4SAndroid Build Coastguard Worker static REGISTERED_EVENTS_PROTO_SRC: &str = "../protos/src";
31*bb4ee6a4SAndroid Build Coastguard Worker 
main() -> Result<()>32*bb4ee6a4SAndroid Build Coastguard Worker fn main() -> Result<()> {
33*bb4ee6a4SAndroid Build Coastguard Worker     // Skip building dependencies when generating documents.
34*bb4ee6a4SAndroid Build Coastguard Worker     if std::env::var("CARGO_DOC").is_ok() {
35*bb4ee6a4SAndroid Build Coastguard Worker         return Ok(());
36*bb4ee6a4SAndroid Build Coastguard Worker     }
37*bb4ee6a4SAndroid Build Coastguard Worker 
38*bb4ee6a4SAndroid Build Coastguard Worker     let proto_src =
39*bb4ee6a4SAndroid Build Coastguard Worker         PathBuf::from(REGISTERED_EVENTS_PROTO_SRC).join(REGISTERED_EVENTS_PROTO_FILENAME);
40*bb4ee6a4SAndroid Build Coastguard Worker 
41*bb4ee6a4SAndroid Build Coastguard Worker     if !proto_src.exists() {
42*bb4ee6a4SAndroid Build Coastguard Worker         bail!(
43*bb4ee6a4SAndroid Build Coastguard Worker             "can't find {} in {}, won't be able to export for users",
44*bb4ee6a4SAndroid Build Coastguard Worker             REGISTERED_EVENTS_PROTO_FILENAME,
45*bb4ee6a4SAndroid Build Coastguard Worker             REGISTERED_EVENTS_PROTO_SRC
46*bb4ee6a4SAndroid Build Coastguard Worker         );
47*bb4ee6a4SAndroid Build Coastguard Worker     }
48*bb4ee6a4SAndroid Build Coastguard Worker 
49*bb4ee6a4SAndroid Build Coastguard Worker     let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
50*bb4ee6a4SAndroid Build Coastguard Worker 
51*bb4ee6a4SAndroid Build Coastguard Worker     let output_dir = PathBuf::from(env::var("OUT_DIR").context("failed to get OUT_DIR")?);
52*bb4ee6a4SAndroid Build Coastguard Worker 
53*bb4ee6a4SAndroid Build Coastguard Worker     let proto_out = output_dir.join(REGISTERED_EVENTS_PROTO_FILENAME);
54*bb4ee6a4SAndroid Build Coastguard Worker 
55*bb4ee6a4SAndroid Build Coastguard Worker     fs::copy(proto_src, proto_out).context("couldn't copy proto to OUT_DIR")?;
56*bb4ee6a4SAndroid Build Coastguard Worker 
57*bb4ee6a4SAndroid Build Coastguard Worker     let output_file = output_dir
58*bb4ee6a4SAndroid Build Coastguard Worker         .join(CROSVM_CONTROL_HEADER_NAME)
59*bb4ee6a4SAndroid Build Coastguard Worker         .display()
60*bb4ee6a4SAndroid Build Coastguard Worker         .to_string();
61*bb4ee6a4SAndroid Build Coastguard Worker 
62*bb4ee6a4SAndroid Build Coastguard Worker     let config = Config {
63*bb4ee6a4SAndroid Build Coastguard Worker         language: Language::C,
64*bb4ee6a4SAndroid Build Coastguard Worker         cpp_compat: true,
65*bb4ee6a4SAndroid Build Coastguard Worker         header: Some(String::from(COPYRIGHT_CLAUSE)),
66*bb4ee6a4SAndroid Build Coastguard Worker         include_guard: Some(String::from(INCLUDE_GUARD)),
67*bb4ee6a4SAndroid Build Coastguard Worker         autogen_warning: Some(String::from(AUTOGENERATED_DISCLAIMER)),
68*bb4ee6a4SAndroid Build Coastguard Worker         include_version: true,
69*bb4ee6a4SAndroid Build Coastguard Worker         enumeration: EnumConfig {
70*bb4ee6a4SAndroid Build Coastguard Worker             rename_variants: RenameRule::ScreamingSnakeCase,
71*bb4ee6a4SAndroid Build Coastguard Worker             ..Default::default()
72*bb4ee6a4SAndroid Build Coastguard Worker         },
73*bb4ee6a4SAndroid Build Coastguard Worker         ..Default::default()
74*bb4ee6a4SAndroid Build Coastguard Worker     };
75*bb4ee6a4SAndroid Build Coastguard Worker 
76*bb4ee6a4SAndroid Build Coastguard Worker     cbindgen::Builder::new()
77*bb4ee6a4SAndroid Build Coastguard Worker         .with_crate(crate_dir)
78*bb4ee6a4SAndroid Build Coastguard Worker         .with_config(config)
79*bb4ee6a4SAndroid Build Coastguard Worker         .with_parse_deps(true)
80*bb4ee6a4SAndroid Build Coastguard Worker         .with_parse_include(&["swap"])
81*bb4ee6a4SAndroid Build Coastguard Worker         .generate()
82*bb4ee6a4SAndroid Build Coastguard Worker         .context("Unable to generate bindings")?
83*bb4ee6a4SAndroid Build Coastguard Worker         .write_to_file(output_file);
84*bb4ee6a4SAndroid Build Coastguard Worker 
85*bb4ee6a4SAndroid Build Coastguard Worker     // Do not perform the compilation check on Windows since GCC might not be installed.
86*bb4ee6a4SAndroid Build Coastguard Worker     if std::env::var("CARGO_CFG_WINDOWS").is_ok() {
87*bb4ee6a4SAndroid Build Coastguard Worker         return Ok(());
88*bb4ee6a4SAndroid Build Coastguard Worker     }
89*bb4ee6a4SAndroid Build Coastguard Worker 
90*bb4ee6a4SAndroid Build Coastguard Worker     // Do a quick compile test of the generated header to ensure it is valid
91*bb4ee6a4SAndroid Build Coastguard Worker     let temp_dir = TempDir::new()?;
92*bb4ee6a4SAndroid Build Coastguard Worker     let test_file = temp_dir
93*bb4ee6a4SAndroid Build Coastguard Worker         .path()
94*bb4ee6a4SAndroid Build Coastguard Worker         .join("crosvm_control_test.c")
95*bb4ee6a4SAndroid Build Coastguard Worker         .display()
96*bb4ee6a4SAndroid Build Coastguard Worker         .to_string();
97*bb4ee6a4SAndroid Build Coastguard Worker 
98*bb4ee6a4SAndroid Build Coastguard Worker     fs::write(
99*bb4ee6a4SAndroid Build Coastguard Worker         &test_file,
100*bb4ee6a4SAndroid Build Coastguard Worker         format!("{}{}{}", "#include \"", CROSVM_CONTROL_HEADER_NAME, "\""),
101*bb4ee6a4SAndroid Build Coastguard Worker     )
102*bb4ee6a4SAndroid Build Coastguard Worker     .context("Failed to write crosvm_control test C file")?;
103*bb4ee6a4SAndroid Build Coastguard Worker 
104*bb4ee6a4SAndroid Build Coastguard Worker     cc::Build::new()
105*bb4ee6a4SAndroid Build Coastguard Worker         .include(output_dir)
106*bb4ee6a4SAndroid Build Coastguard Worker         .file(test_file)
107*bb4ee6a4SAndroid Build Coastguard Worker         .compile("crosvm_control_test");
108*bb4ee6a4SAndroid Build Coastguard Worker 
109*bb4ee6a4SAndroid Build Coastguard Worker     // The above outputs cargo:rerun-if-env-changed directives, so we need to explicitly tell cargo
110*bb4ee6a4SAndroid Build Coastguard Worker     // to rerun this script if anything in src/ is changed.
111*bb4ee6a4SAndroid Build Coastguard Worker     println!("cargo:rerun-if-changed=src");
112*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
113*bb4ee6a4SAndroid Build Coastguard Worker }
114