1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use cbindgen::ItemType::*;
16 use std::vec;
17 
18 const C_CONFIG: &str = "cbindgen_configs/c_config.toml";
19 const C_OUTPUT_HEADER_FILE: &str = "include/c/np_c_ffi.h";
20 
21 const CPP_CONFIG: &str = "cbindgen_configs/cpp_config.toml";
22 const CPP_INCLUDE_DIR_BASE: &str = "include/cpp/";
23 const CPP_PUBLIC_HEADER_FILE: &str = "np_cpp_ffi_types.h";
24 const CPP_INTERNAL_HEADER_FILE: &str = "np_cpp_ffi_functions.h";
25 
main()26 fn main() {
27     let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
28 
29     let config_file = format!("{crate_dir}/{C_CONFIG}");
30     let config = cbindgen::Config::from_file(config_file).expect("Config file should exist");
31     generate_c_header(&crate_dir, config);
32 
33     let config_file = format!("{crate_dir}/{CPP_CONFIG}");
34     let config = cbindgen::Config::from_file(config_file).expect("Config file should exist");
35     generate_private_cpp_header(&crate_dir, config.clone());
36     generate_public_cpp_header(&crate_dir, config);
37 }
38 
generate_c_header(crate_dir: &String, config: cbindgen::Config)39 fn generate_c_header(crate_dir: &String, config: cbindgen::Config) {
40     let output_header_file = format!("{crate_dir}/{C_OUTPUT_HEADER_FILE}");
41     generate_header(&output_header_file, crate_dir, config);
42 }
43 
generate_private_cpp_header(crate_dir: &String, mut config: cbindgen::Config)44 fn generate_private_cpp_header(crate_dir: &String, mut config: cbindgen::Config) {
45     config.export.item_types.append(&mut vec![Functions]);
46     config.includes.push(CPP_PUBLIC_HEADER_FILE.to_string());
47     let output_header_file =
48         format!("{crate_dir}/{CPP_INCLUDE_DIR_BASE}/{CPP_INTERNAL_HEADER_FILE}");
49     generate_header(&output_header_file, crate_dir, config);
50 }
51 
generate_public_cpp_header(crate_dir: &String, mut config: cbindgen::Config)52 fn generate_public_cpp_header(crate_dir: &String, mut config: cbindgen::Config) {
53     config.export.item_types.append(&mut vec![Enums, Structs]);
54     let output_header_file = format!("{crate_dir}/{CPP_INCLUDE_DIR_BASE}/{CPP_PUBLIC_HEADER_FILE}");
55     generate_header(&output_header_file, crate_dir, config);
56 }
57 
generate_header(output_file: &String, crate_dir: &String, config: cbindgen::Config)58 fn generate_header(output_file: &String, crate_dir: &String, config: cbindgen::Config) {
59     let _ = cbindgen::generate_with_config(crate_dir, config)
60         .map_err(|e| println!("cargo:warning=ERROR: {e}"))
61         .expect("c header file generation failed")
62         .write_to_file(output_file);
63 }
64