//! The following environment variables affect the build: //! //! * `UPDATE_IN3_BINDINGS`: setting indicates that the pre-generated `in3.rs` should be //! updated with the output bindgen //! use std::env; use std::fs::copy; use std::path::PathBuf; use std::vec::Vec; use bindgen; use cmake::Config; const IN3_DIR: &'static str = "in3-core"; const BINDINGS_FILE: &'static str = "in3.rs"; /// Search for header in search paths fn find_in3_header(header_search_paths: &Vec, name: &str) -> Option { for search_path in header_search_paths.iter() { let potential_file = search_path.join(name); if potential_file.is_file() { return Some(potential_file); } } None } /// Gets environment variable value. Panics if variable is not set. fn env_var(var: &str) -> String { env::var(var).expect(&format!("Environment variable {} is not set", var)) } /// Create bindings using bindgen fn write_bindgen_bindings( header_search_paths: &Vec, update_pregenerated_bindings: bool, pregenerated_bindgen_header: PathBuf, out_bindings_path: PathBuf, ) { let builder = bindgen::Builder::default() .rust_target(bindgen::RustTarget::Stable_1_28) .size_t_is_usize(true) .use_core() .ctypes_prefix("libc") .header( find_in3_header(header_search_paths, "in3.rs.h") .expect("Could not find header") .to_str() .unwrap(), // unlikely to have non-UTF8 path ) .disable_name_namespacing() .prepend_enum_name(false) .generate_comments(false) .impl_debug(true) .constified_enum_module("in3_ret_t") .rustified_enum(".*"); let bindings = builder.generate().expect("Unable to generate bindings"); bindings .write_to_file(&out_bindings_path) .expect("Unable to write bindings"); if update_pregenerated_bindings { copy(out_bindings_path, pregenerated_bindgen_header) .expect("Unable to update in3 bindings"); } } fn main() { let mut header_search_paths: Vec = Vec::new(); header_search_paths.push([IN3_DIR, "c", "include"].iter().collect()); let dst = Config::new(IN3_DIR) .profile("MinSizeRel") .define("TRANSPORTS", "OFF") .define("USE_CURL", "OFF") .define("CMD", "OFF") .define("PLGN_CLIENT_DATA", "ON") .define("RECORDER", "ON") .define("MULTISIG", "ON") .define("ZKSYNC", "ON") .build_target("in3_bundle") .build(); println!("cargo:rustc-link-search=native={}/build/lib", dst.display()); println!("cargo:rustc-link-lib=static=in3"); let pregenerated_bindgen_header: PathBuf = [ env_var("CARGO_MANIFEST_DIR"), "pre_generated".into(), BINDINGS_FILE.into(), ] .iter() .collect(); let out_bindings_path = PathBuf::from(env_var("OUT_DIR")).join(BINDINGS_FILE); write_bindgen_bindings( &header_search_paths, env::var("UPDATE_IN3_BINDINGS").is_ok(), pregenerated_bindgen_header, out_bindings_path, ); }