12253ef60SGraham MacDonald extern crate cbindgen;
279d05d7eSJeremy Soller extern crate cc;
379d05d7eSJeremy Soller
42253ef60SGraham MacDonald use std::{env, fs, fs::DirEntry, path::Path};
52253ef60SGraham MacDonald
62253ef60SGraham MacDonald // include src/header directories that don't start with '_'
include_dir(d: &DirEntry) -> bool72253ef60SGraham MacDonald fn include_dir(d: &DirEntry) -> bool {
82253ef60SGraham MacDonald d.metadata().map(|m| m.is_dir()).unwrap_or(false)
92253ef60SGraham MacDonald && d.path()
102253ef60SGraham MacDonald .iter()
112253ef60SGraham MacDonald .nth(2)
122253ef60SGraham MacDonald .map_or(false, |c| c.to_str().map_or(false, |x| !x.starts_with("_")))
132253ef60SGraham MacDonald }
142253ef60SGraham MacDonald
generate_bindings(cbindgen_config_path: &Path)152253ef60SGraham MacDonald fn generate_bindings(cbindgen_config_path: &Path) {
162253ef60SGraham MacDonald let relative_path = cbindgen_config_path
172253ef60SGraham MacDonald .strip_prefix("src/header")
182253ef60SGraham MacDonald .ok()
192253ef60SGraham MacDonald .and_then(|p| p.parent())
202253ef60SGraham MacDonald .and_then(|p| p.to_str())
212253ef60SGraham MacDonald .unwrap()
222253ef60SGraham MacDonald .replace("_", "/");
232253ef60SGraham MacDonald let header_path = Path::new("target/include")
242253ef60SGraham MacDonald .join(&relative_path)
252253ef60SGraham MacDonald .with_extension("h");
262253ef60SGraham MacDonald let mod_path = cbindgen_config_path.with_file_name("mod.rs");
272253ef60SGraham MacDonald let config = cbindgen::Config::from_file(cbindgen_config_path).unwrap();
282253ef60SGraham MacDonald cbindgen::Builder::new()
292253ef60SGraham MacDonald .with_config(config)
302253ef60SGraham MacDonald .with_src(mod_path)
312253ef60SGraham MacDonald .generate()
322253ef60SGraham MacDonald .expect("Unable to generate bindings")
332253ef60SGraham MacDonald .write_to_file(header_path);
342253ef60SGraham MacDonald }
3579d05d7eSJeremy Soller
main()3679d05d7eSJeremy Soller fn main() {
37277b9abcSJeremy Soller let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
38277b9abcSJeremy Soller
392253ef60SGraham MacDonald // Generate C includes
402253ef60SGraham MacDonald // - based on contents of src/header/**
412253ef60SGraham MacDonald // - headers written to target/include
422253ef60SGraham MacDonald fs::read_dir(&Path::new("src/header"))
432253ef60SGraham MacDonald .unwrap()
442253ef60SGraham MacDonald .into_iter()
452253ef60SGraham MacDonald .filter_map(Result::ok)
462253ef60SGraham MacDonald .filter(|d| include_dir(d))
472253ef60SGraham MacDonald .map(|d| d.path().as_path().join("cbindgen.toml"))
482253ef60SGraham MacDonald .filter(|p| p.exists())
492253ef60SGraham MacDonald .for_each(|p| {
502253ef60SGraham MacDonald println!("cargo:rerun-if-changed={:?}", p.parent().unwrap());
512253ef60SGraham MacDonald println!("cargo:rerun-if-changed={:?}", p);
522253ef60SGraham MacDonald println!("cargo:rerun-if-changed={:?}", p.with_file_name("mod.rs"));
532253ef60SGraham MacDonald generate_bindings(&p);
542253ef60SGraham MacDonald });
552253ef60SGraham MacDonald
56*be35961dSlogin let mut c = cc::Build::new();
57*be35961dSlogin c.flag("-nostdinc")
58277b9abcSJeremy Soller .flag("-nostdlib")
597f702720SjD91mZM2 .include(&format!("{}/include", crate_dir))
601c168218SJeremy Soller .include(&format!("{}/target/include", crate_dir))
61a28e9ae3SJeremy Soller .include(&format!("{}/pthreads-emb", crate_dir))
62277b9abcSJeremy Soller .flag("-fno-stack-protector")
63c911faccSJeremy Soller .flag("-Wno-expansion-to-defined")
64b8c50c7cSjD91mZM2 .files(
65b8c50c7cSjD91mZM2 fs::read_dir("src/c")
667f702720SjD91mZM2 .expect("src/c directory missing")
67b8c50c7cSjD91mZM2 .map(|res| res.expect("read_dir error").path()),
68*be35961dSlogin );
69*be35961dSlogin
70*be35961dSlogin #[cfg(target_os = "dragonos")]
71*be35961dSlogin {
72*be35961dSlogin // for dragonos only
73*be35961dSlogin c.define("HAVE_MMAP", "0");
74*be35961dSlogin }
75*be35961dSlogin
76*be35961dSlogin c.compile("relibc_c");
7779d05d7eSJeremy Soller
7879d05d7eSJeremy Soller println!("cargo:rustc-link-lib=static=relibc_c");
7979d05d7eSJeremy Soller }
80