xref: /relibc/build.rs (revision be35961d82cd98f2a2e61c4f1869271b9f4af571)
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