extern crate bindgen;
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::fs::read_dir;
use std::path::PathBuf;
use std::process::Command;
use bindgen::Builder;
fn build_picotcp(prefix: &Path, debug: bool) {
println!("Building picotcp to: {}", prefix.to_string_lossy());
Command::new("make")
.arg("-C").arg("picotcp") .env("PREFIX", prefix.as_os_str())
.env("DEBUG", if debug { "1" } else { "0" })
.status().unwrap();
}
fn generate_bindings(out_file: &mut File, header_path: &Path) {
let header_path = header_path.to_str().expect("Could not decode Path to String");
let mut bindings = Builder::new(header_path);
bindings.builtins();
bindings.forbid_unknown_types();
bindings.convert_macros(true);
let generated_bindings = bindings.generate().expect(&format!("Failed to generate bindings for {}", header_path));
out_file.write(generated_bindings.to_string().as_bytes()).unwrap();
}
fn write_includes(includer_file: &mut File, includer_file_path: &Path, path: &Path) {
let file_name = path.file_name().unwrap().to_str().expect("Could not decode Path to String");
if path.file_name().unwrap() == "arch" {
}
else if path == includer_file_path {
}
else if path.is_dir() {
for path in read_dir(path).unwrap() {
write_includes(includer_file, includer_file_path, path.unwrap().path().as_path());
}
}
else {
assert!(file_name.ends_with(".h"));
includer_file.write(format!("#include \"{}\"\n", path.to_str().unwrap()).as_bytes()).unwrap();
}
}
fn link_picotcp(picotcp_lib_dir: &Path) {
println!("cargo:rustc-link-lib=static=picotcp");
println!("cargo:rustc-link-search=native={}", picotcp_lib_dir.to_str().expect("Could not decode Path to String"));
}
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let debug = env::var("DEBUG").unwrap_or("false".to_owned()) == "true";
let out_dir = Path::new(&out_dir).to_path_buf();
let out_file_path: PathBuf = Path::new("picotcp.rs").to_path_buf();
let picotcp_prefix: PathBuf = { let mut p = out_dir.clone(); p.push("picotcp"); p };
let picotcp_headers_dir: PathBuf = { let mut p = picotcp_prefix.clone(); p.push("include"); p };
let includer_file_path: PathBuf = { let mut p = picotcp_headers_dir.clone(); p.push("picotcp_include_all.h"); p };
let picotcp_lib_dir: PathBuf = { let mut p = picotcp_prefix.clone(); p.push("lib"); p };
let mut out_file = File::create(out_file_path).expect("Failed to open file");
build_picotcp(picotcp_prefix.as_path(), debug);
{
let mut includer_file = File::create(includer_file_path.as_path()).expect("Failed to open file");
write_includes(&mut includer_file, includer_file_path.as_path(), picotcp_headers_dir.as_path());
}
generate_bindings(&mut out_file, includer_file_path.as_path());
link_picotcp(picotcp_lib_dir.as_path());
}