use std::env;
use std::path::PathBuf;
fn main() {
let vec_flags = &get_build_flags();
build_hdfs_lib(vec_flags);
build_minidfs_lib(vec_flags);
build_ffi(vec_flags);
}
fn build_ffi(flags: &[String]) {
let (header, output) = ("c_src/wrapper.h", "hdfs-native.rs");
println!("cargo:rerun-if-changed={}", header);
println!("cargo:rerun-if-changed={}", get_hdfs_file_path("hdfs.h"));
println!(
"cargo:rerun-if-changed={}",
get_minidfs_file_path("native_mini_dfs.h")
);
println!("cargo:rustc-link-lib=jvm");
let bindings = bindgen::Builder::default()
.header(header)
.allowlist_function("nmd.*")
.allowlist_function("hdfs.*")
.allowlist_function("hadoop.*")
.clang_args(flags)
.rustified_enum("tObjectKind")
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join(output))
.expect("Couldn't write bindings!");
}
fn build_hdfs_lib(flags: &[String]) {
println!("cargo:rerun-if-changed={}", get_hdfs_file_path("hdfs.c"));
let mut builder = cc::Build::new();
builder
.include(get_hdfs_source_dir())
.include(format!("{}/os/posix", get_hdfs_source_dir()));
builder
.file(get_hdfs_file_path("exception.c"))
.file(get_hdfs_file_path("htable.c"))
.file(get_hdfs_file_path("jni_helper.c"))
.file(get_hdfs_file_os_path("mutexes.c"))
.file(get_hdfs_file_os_path("thread_local_storage.c"))
.file(get_hdfs_file_path("hdfs.c"));
for flag in flags {
builder.flag(flag);
}
builder.warnings(false);
builder.compile("hdfs");
}
fn build_minidfs_lib(flags: &[String]) {
println!(
"cargo:rerun-if-changed={}",
get_minidfs_file_path("native_mini_dfs.c")
);
let mut builder = cc::Build::new();
builder
.include(get_hdfs_source_dir())
.include(format!("{}/os/posix", get_hdfs_source_dir()));
builder.file(get_minidfs_file_path("native_mini_dfs.c"));
for flag in flags {
builder.flag(flag.as_str());
}
builder.compile("minidfs");
}
fn get_build_flags() -> Vec<String> {
let mut result = vec![];
result.extend(get_java_dependency());
result.push(String::from("-Wno-incompatible-pointer-types"));
result
}
fn get_java_dependency() -> Vec<String> {
let mut result = vec![];
match env::var("JAVA_HOME") {
Ok(val) => {
result.push(format!("-I{}/include", val));
if cfg!(target_os = "linux") {
result.push(format!("-I{}/include/linux", val));
println!(
"cargo:rustc-link-search=native={}/jre/lib/amd64/server",
val
);
println!("cargo:rustc-link-search=native={}/lib/server", val)
} else if cfg!(target_os = "macos") {
result.push(format!("-I{}/include/darwin", val));
println!("cargo:rustc-link-search=native={}/jre/lib/server", val);
println!("cargo:rustc-link-search=native={}/lib/server", val);
}
println!("cargo:rustc-link-lib=jvm");
}
Err(e) => {
panic!("JAVA_HOME shell environment must be set: {}", e);
}
}
result
}
fn get_hdfs_file_path(filename: &'static str) -> String {
format!("{}/{}", get_hdfs_source_dir(), filename)
}
fn get_hdfs_file_os_path(filename: &'static str) -> String {
format!("{}/os/posix/{}", get_hdfs_source_dir(), filename)
}
fn get_hdfs_source_dir() -> &'static str {
"c_src/libhdfs"
}
fn get_minidfs_file_path(filename: &'static str) -> String {
format!("{}/{}", "c_src/libminidfs", filename)
}