use cc::Build;
use std::env;
use std::fs::{copy, create_dir_all, File};
use std::io::{BufRead, BufReader, Write};
use std::path::PathBuf;
use std::process::Command;
use walkdir::WalkDir;
const VERSION: &str = "20230824";
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=LIBESEDB_MAXIMUM_NUMBER_OF_LEAF_PAGES");
if env::var("DOCS_RS").is_ok() {
println!(
"cargo:warning=docs.rs build, skipping C source build because of manual bindings."
);
return;
}
let mut c = Build::new();
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let src_dir = out_dir.join(format!("libesedb-{VERSION}"));
for ent in WalkDir::new(format!("libesedb-{VERSION}")) {
let ent = ent.unwrap();
if ent.file_type().is_dir() {
create_dir_all(out_dir.join(ent.path())).unwrap();
} else if ent.file_type().is_file() {
copy(ent.path(), out_dir.join(ent.path())).unwrap();
let name = ent.file_name().to_str().unwrap();
if name.ends_with(".c") {
let parent_name = ent
.path()
.parent()
.unwrap()
.file_name()
.unwrap()
.to_str()
.unwrap();
if name == "libesedb_page_tree.c" {
let max_leaf_pages = env::var("LIBESEDB_MAXIMUM_NUMBER_OF_LEAF_PAGES")
.unwrap_or(String::from("32 * 1024"));
println!("cargo:warning=LIBESEDB_MAXIMUM_NUMBER_OF_LEAF_PAGES set to ({max_leaf_pages})");
let mut page_tree = File::create(out_dir.join(ent.path())).unwrap();
for line in BufReader::new(File::open(ent.path()).unwrap()).lines() {
let line = line.unwrap();
writeln!(page_tree, "{line}").unwrap();
if line.starts_with("#include \"esedb_page_values.h\"") {
writeln!(page_tree).unwrap();
writeln!(page_tree, "#undef LIBESEDB_MAXIMUM_NUMBER_OF_LEAF_PAGES")
.unwrap();
writeln!(page_tree, "#define LIBESEDB_MAXIMUM_NUMBER_OF_LEAF_PAGES ({max_leaf_pages})").unwrap();
}
}
c.file(ent.path());
} else if parent_name.starts_with("lib") {
c.file(ent.path());
}
}
}
}
c.include(src_dir.join("include"));
c.include(src_dir.join("common"));
c.include(src_dir.join("libbfio"));
c.include(src_dir.join("libcdata"));
c.include(src_dir.join("libcerror"));
c.include(src_dir.join("libcfile"));
c.include(src_dir.join("libclocale"));
c.include(src_dir.join("libcnotify"));
c.include(src_dir.join("libcpath"));
c.include(src_dir.join("libcsplit"));
c.include(src_dir.join("libcthreads"));
c.include(src_dir.join("libesedb"));
c.include(src_dir.join("libfcache"));
c.include(src_dir.join("libfdata"));
c.include(src_dir.join("libfdatetime"));
c.include(src_dir.join("libfguid"));
c.include(src_dir.join("libfmapi"));
c.include(src_dir.join("libfvalue"));
c.include(src_dir.join("libfwnt"));
c.include(src_dir.join("libmapidb"));
c.include(src_dir.join("libuna"));
if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "windows" {
c.define("HAVE_LOCAL_LIBBFIO", "1");
c.define("HAVE_LOCAL_LIBCDATA", "1");
c.define("HAVE_LOCAL_LIBCERROR", "1");
c.define("HAVE_LOCAL_LIBCFILE", "1");
c.define("HAVE_LOCAL_LIBCLOCALE", "1");
c.define("HAVE_LOCAL_LIBCNOTIFY", "1");
c.define("HAVE_LOCAL_LIBCPATH", "1");
c.define("HAVE_LOCAL_LIBCSPLIT", "1");
c.define("HAVE_LOCAL_LIBCTHREADS", "1");
c.define("HAVE_LOCAL_LIBFCACHE", "1");
c.define("HAVE_LOCAL_LIBFDATA", "1");
c.define("HAVE_LOCAL_LIBFDATETIME", "1");
c.define("HAVE_LOCAL_LIBFGUID", "1");
c.define("HAVE_LOCAL_LIBFMAPI", "1");
c.define("HAVE_LOCAL_LIBFVALUE", "1");
c.define("HAVE_LOCAL_LIBFWNT", "1");
c.define("HAVE_LOCAL_LIBMAPIDB", "1");
c.define("HAVE_LOCAL_LIBUNA", "1");
} else if env::var("CARGO_CFG_TARGET_FAMILY").unwrap() == "unix" {
c.define("HAVE_CONFIG_H", None);
c.define("LOCALEDIR", "\"/usr/share/locale\"");
Command::new("chmod")
.arg("+x")
.arg(src_dir.join("configure"))
.status()
.unwrap();
Command::new(src_dir.join("configure"))
.current_dir(src_dir)
.env("CC", c.get_compiler().cc_env())
.env("CFLAGS", c.get_compiler().cflags_env())
.status()
.unwrap();
}
c.compile("esedb");
}