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