1 extern crate bindgen; 2 extern crate cc; 3 // use ::std::env; 4 5 use std::path::PathBuf; 6 7 use cc::Build; 8 9 fn main() { 10 // Tell cargo to look for shared libraries in the specified directory 11 println!("cargo:rustc-link-search=src"); 12 println!("cargo:rerun-if-changed=src/include/bindings/wrapper.h"); 13 14 generate_bindings(); 15 CFilesBuilder::build(); 16 } 17 18 fn generate_bindings() { 19 // let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); 20 let out_path = PathBuf::from(String::from("src/include/bindings/")); 21 22 // The bindgen::Builder is the main entry point 23 // to bindgen, and lets you build up options for 24 // the resulting bindings. 25 { 26 let bindings = bindgen::Builder::default() 27 .clang_arg("-I./src") 28 .clang_arg("-I./src/include") 29 .clang_arg("-I./src/arch/x86_64/include") // todo: 当引入多种架构之后,需要修改这里,对于不同的架构编译时,include不同的路径 30 // The input header we would like to generate 31 // bindings for. 32 .header("src/include/bindings/wrapper.h") 33 .blocklist_file("src/include/bindings/bindings.h") 34 .clang_arg("--target=x86_64-none-none") 35 .clang_arg("-v") 36 // 使用core,并将c语言的类型改为core::ffi,而不是使用std库。 37 .use_core() 38 .ctypes_prefix("::core::ffi") 39 .generate_inline_functions(true) 40 .raw_line("#![allow(dead_code)]") 41 .raw_line("#![allow(non_upper_case_globals)]") 42 .raw_line("#![allow(non_camel_case_types)]") 43 // Tell cargo to invalidate the built crate whenever any of the 44 // included header files changed. 45 .parse_callbacks(Box::new(bindgen::CargoCallbacks)) 46 // Finish the builder and generate the bindings. 47 .generate() 48 // Unwrap the Result and panic on failure. 49 .expect("Unable to generate bindings"); 50 51 bindings 52 .write_to_file(out_path.join("bindings.rs")) 53 .expect("Couldn't write bindings!"); 54 } 55 } 56 57 /// 构建项目的c文件 58 struct CFilesBuilder; 59 60 impl CFilesBuilder { 61 fn build() { 62 let mut c = cc::Build::new(); 63 Self::setup_global_flags(&mut c); 64 Self::setup_defines(&mut c); 65 Self::setup_global_include_dir(&mut c); 66 Self::setup_files(&mut c); 67 c.compile("dragonos_kernel_cfiles"); 68 } 69 70 fn setup_global_flags(c: &mut Build) { 71 c.flag("-mcmodel=large") 72 .flag("-fno-builtin") 73 .flag("-nostdlib") 74 .flag("-fno-stack-protector") 75 .flag("-fno-pie") 76 .flag("-Wno-expansion-to-defined") 77 .flag("-Wno-unused-parameter") 78 .flag("-m64") 79 .flag("-O1"); 80 } 81 82 fn setup_defines(c: &mut Build) { 83 if let Ok(k) = std::env::var("EMULATOR") { 84 c.define("EMULATOR", Some(k.as_str())); 85 } else { 86 c.define("EMULATOR", "__NO_EMULATION__"); 87 } 88 89 { 90 #[cfg(target_arch = "x86_64")] 91 c.define("__x86_64__", None); 92 } 93 94 c.define("PIC", "_INTR_APIC_"); 95 } 96 97 fn setup_global_include_dir(c: &mut Build) { 98 c.include("src/include"); 99 c.include("src"); 100 c.include("."); 101 102 #[cfg(target_arch = "x86_64")] 103 c.include("src/arch/x86_64/include"); 104 } 105 106 /// 设置需要编译的文件 107 fn setup_files(c: &mut Build) { 108 c.file("src/arch/x86_64/driver/hpet.c"); 109 } 110 } 111