1 use std::{path::PathBuf, str::FromStr}; 2 3 use crate::{bindgen::arch::current_bindgenarch, utils::cargo_handler::CargoHandler}; 4 5 mod arch; 6 7 /// 生成 C->Rust bindings 8 pub fn generate_bindings() { 9 let wrapper_h = PathBuf::from_str("src/include/bindings/wrapper.h") 10 .expect("Failed to parse 'wrapper.h' path"); 11 CargoHandler::emit_rerun_if_files_changed(&[wrapper_h.clone()]); 12 13 let out_path = PathBuf::from(String::from("src/include/bindings/")); 14 15 // The bindgen::Builder is the main entry point 16 // to bindgen, and lets you build up options for 17 // the resulting bindings. 18 19 let builder = bindgen::Builder::default() 20 .clang_arg("-I./src") 21 .clang_arg("-I./src/include") 22 // The input header we would like to generate 23 // bindings for. 24 .header(wrapper_h.to_str().unwrap()) 25 .blocklist_file("src/include/bindings/bindings.h") 26 .clang_arg("-v") 27 // 使用core,并将c语言的类型改为core::ffi,而不是使用std库。 28 .use_core() 29 .ctypes_prefix("::core::ffi") 30 .generate_inline_functions(true) 31 .raw_line("#![allow(dead_code)]") 32 .raw_line("#![allow(non_upper_case_globals)]") 33 .raw_line("#![allow(non_camel_case_types)]") 34 // Tell cargo to invalidate the built crate whenever any of the 35 // included header files changed. 36 .parse_callbacks(Box::new(bindgen::CargoCallbacks)); 37 38 // 处理架构相关的绑定 39 let builder = current_bindgenarch().generate_bindings(builder); 40 41 // Finish the builder and generate the bindings. 42 let bindings = builder 43 .generate() 44 // Unwrap the Result and panic on failure. 45 .expect("Unable to generate bindings"); 46 47 bindings 48 .write_to_file(out_path.join("bindings.rs")) 49 .expect("Couldn't write bindings!"); 50 } 51