2
0

build.rs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. extern crate cbindgen;
  2. extern crate cc;
  3. use std::{env, fs, fs::DirEntry, path::Path};
  4. // include src/header directories that don't start with '_'
  5. fn include_dir(d: &DirEntry) -> bool {
  6. d.metadata().map(|m| m.is_dir()).unwrap_or(false)
  7. && d.path()
  8. .iter()
  9. .nth(2)
  10. .map_or(false, |c| c.to_str().map_or(false, |x| !x.starts_with("_")))
  11. }
  12. fn generate_bindings(cbindgen_config_path: &Path) {
  13. let relative_path = cbindgen_config_path
  14. .strip_prefix("src/header")
  15. .ok()
  16. .and_then(|p| p.parent())
  17. .and_then(|p| p.to_str())
  18. .unwrap()
  19. .replace("_", "/");
  20. let header_path = Path::new("target/include")
  21. .join(&relative_path)
  22. .with_extension("h");
  23. let mod_path = cbindgen_config_path.with_file_name("mod.rs");
  24. let config = cbindgen::Config::from_file(cbindgen_config_path).unwrap();
  25. cbindgen::Builder::new()
  26. .with_config(config)
  27. .with_src(mod_path)
  28. .generate()
  29. .expect("Unable to generate bindings")
  30. .write_to_file(header_path);
  31. }
  32. fn main() {
  33. let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
  34. // Generate C includes
  35. // - based on contents of src/header/**
  36. // - headers written to target/include
  37. fs::read_dir(&Path::new("src/header"))
  38. .unwrap()
  39. .into_iter()
  40. .filter_map(Result::ok)
  41. .filter(|d| include_dir(d))
  42. .map(|d| d.path().as_path().join("cbindgen.toml"))
  43. .filter(|p| p.exists())
  44. .for_each(|p| {
  45. println!("cargo:rerun-if-changed={:?}", p.parent().unwrap());
  46. println!("cargo:rerun-if-changed={:?}", p);
  47. println!("cargo:rerun-if-changed={:?}", p.with_file_name("mod.rs"));
  48. generate_bindings(&p);
  49. });
  50. let mut c = cc::Build::new();
  51. c.flag("-nostdinc")
  52. .flag("-nostdlib")
  53. .include(&format!("{}/include", crate_dir))
  54. .include(&format!("{}/target/include", crate_dir))
  55. .include(&format!("{}/pthreads-emb", crate_dir))
  56. .flag("-fno-stack-protector")
  57. .flag("-Wno-expansion-to-defined")
  58. .files(
  59. fs::read_dir("src/c")
  60. .expect("src/c directory missing")
  61. .map(|res| res.expect("read_dir error").path()),
  62. );
  63. #[cfg(target_os = "dragonos")]
  64. {
  65. // for dragonos only
  66. c.define("HAVE_MMAP", "0");
  67. }
  68. c.compile("relibc_c");
  69. println!("cargo:rustc-link-lib=static=relibc_c");
  70. }