// // Copyright (C) 2024 Automated Design Corp.. All Rights Reserved. // Created Date: 2024-08-12 06:45:34 // ----- // Last Modified: 2024-08-12 11:17:20 // ----- // // extern crate bindgen; use std::env; use std::path::PathBuf; fn main() { // Determine the target architecture let target = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); // Determine if we're linking dynamically based on the `dynamic` feature flag //let is_dynamic = env::var("CARGO_FEATURE_DYNAMIC").is_ok(); let is_dynamic = true; // Tell cargo to invalidate the built crate whenever the wrapper changes println!("cargo:rerun-if-changed=wrapper.h"); // Set the library search path based on the target architecture let lib_dir = match target.as_str() { "x86_64" => "./external/yapi/binaries/windows/64bit", "x86" => "./external/yapi/binaries/windows/32bit", _ => panic!("Unsupported target architecture: {}", target), }; let lib_path = PathBuf::from(&lib_dir) .canonicalize() .expect("Unable to canonicalize the header directory"); let lib_dir_str = lib_path .as_os_str() .to_str() .unwrap() .replace("\\", "/") .splitn(2, ':') .nth(1) .unwrap_or("") .to_string(); println!("cargo:rustc-link-search=native={}", lib_dir_str); if !is_dynamic { // Linking against the static library println!("cargo:rustc-link-lib=static=yapi-static"); } else { // Linking against the dynamic library println!("cargo:rustc-link-lib=dylib=yapi"); } // Tell cargo to invalidate the built crate whenever the wrapper changes println!("cargo:rerun-if-changed=wrapper.h"); // Get the path to the header files let header_dir = PathBuf::from("./external/yapi/sources") .canonicalize() .expect("Unable to canonicalize the header directory"); // Path to the `yapi` directory let yapi_include_path = header_dir.join("yapi"); // Convert the path to a string, replace backslashes with forward slashes, // and remove everything before and including the first ':' let header_dir_str = header_dir .as_os_str() .to_str() .unwrap() .replace("\\", "/") .splitn(2, ':') .nth(1) .unwrap_or("") .to_string(); let yapi_include_path_str = yapi_include_path .as_os_str() .to_str() .unwrap() .replace("\\", "/") .splitn(2, ':') .nth(1) .unwrap_or("") .to_string(); println!("Header directory: {}", header_dir_str); println!("yapi include path: {}", yapi_include_path_str); // Generate bindings using bindgen let bindings = bindgen::Builder::default() .header("wrapper.h") // Add lines to ignore certain Rust linter warnings .raw_line("#[allow(non_upper_case_globals)]") .raw_line("#[allow(non_camel_case_types)]") .raw_line("#[allow(non_snake_case)]") // Add include dir search paths .clang_arg(format!("-I{}", header_dir_str)) //.clang_arg(format!("-I{} -I{}", header_dir_str, yapi_include_path_str)) // Put clang into C++ mode. .clang_arg("-x") .clang_arg("c++") .clang_arg("-std=c++14") // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Finish the builder and generate the bindings. .generate() .expect("Unable to generate bindings"); // Write the bindings to the $OUT_DIR/bindings.rs file let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); }