use std::env;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
fn main() -> Result<()> {
if env::var("DOCS_RS").is_ok() {
return Ok(());
}
find_jvm()?;
let found = if cfg!(feature = "vendored") {
false
} else {
find_libhdfs()?
};
if !found {
build_libhdfs()?;
}
Ok(())
}
fn find_jvm() -> Result<()> {
let jvm_path = java_locator::locate_jvm_dyn_library()?;
println!("cargo:rustc-link-lib=jvm");
println!("cargo:rustc-link-search=native={jvm_path}");
if cfg!(windows) {
if let Ok(jvm_lib_path) = java_locator::locate_file("jvm.lib") {
println!("cargo:rustc-link-search=native={jvm_lib_path}");
}
}
Ok(())
}
fn find_libhdfs() -> Result<bool> {
println!("cargo:rerun-if-env-changed=HDFS_LIB_DIR");
println!("cargo:rerun-if-env-changed=HDFS_STATIC");
println!("cargo:rerun-if-env-changed=HADOOP_HOME");
let lib_dir = if let Ok(lib_dir) = env::var("HDFS_LIB_DIR") {
lib_dir
} else if let Ok(hadoop_home) = env::var("HADOOP_HOME") {
format!("{hadoop_home}/lib/native")
} else {
return Ok(false);
};
println!("cargo:rustc-link-search=native={lib_dir}");
let mode = match env::var_os("HDFS_STATIC") {
Some(_) => "static",
None => "dylib",
};
println!("cargo:rustc-link-lib={mode}=hdfs");
Ok(true)
}
fn build_libhdfs() -> Result<()> {
let java_home = java_locator::locate_java_home()?;
println!("cargo:rustc-link-lib=static=hdfs");
let mut builder = cc::Build::new();
builder.warnings(false);
builder.static_flag(true);
builder.static_crt(true);
builder.flag_if_supported("-w");
builder.flag_if_supported("-std=c++17");
if cfg!(windows) {
builder.flag("-O2");
builder.flag("/W4");
builder.flag("/wd4100");
builder.flag("/wd4127");
builder.flag("-D_CRT_NONSTDC_NO_DEPRECATE");
builder.flag("-D_CRT_SECURE_NO_WARNINGS");
builder.flag("-DWIN32_LEAN_AND_MEAN");
} else {
builder.flag("-fvisibility=hidden");
builder.flag("-fcommon");
}
builder.include(format!("{java_home}/include"));
if cfg!(target_os = "linux") {
builder.include(format!("{java_home}/include/linux"));
}
if cfg!(target_os = "macos") {
builder.include(format!("{java_home}/include/darwin"));
}
if cfg!(target_os = "windows") {
builder.include(format!("{java_home}/include/win32"));
}
let mut version = "hdfs_2_2";
if cfg!(feature = "hdfs_2_3") {
version = "hdfs_2_3"
}
if cfg!(feature = "hdfs_2_4") {
version = "hdfs_2_4"
}
if cfg!(feature = "hdfs_2_5") {
version = "hdfs_2_5"
}
if cfg!(target_os = "windows") {
version = "hdfs_2_6"
}
if cfg!(feature = "hdfs_2_6") {
version = "hdfs_2_6"
}
if cfg!(feature = "hdfs_2_7") {
version = "hdfs_2_7"
}
if cfg!(feature = "hdfs_2_8") {
version = "hdfs_2_8"
}
if cfg!(feature = "hdfs_2_9") {
version = "hdfs_2_9"
}
if cfg!(feature = "hdfs_2_10") {
version = "hdfs_2_10"
}
if cfg!(feature = "hdfs_3_0") {
version = "hdfs_3_0"
}
if cfg!(feature = "hdfs_3_1") {
version = "hdfs_3_1"
}
if cfg!(feature = "hdfs_3_2") {
version = "hdfs_3_2"
}
if cfg!(feature = "hdfs_3_3") {
version = "hdfs_3_3"
}
builder.include("libhdfs");
builder.include(format!("libhdfs/{version}"));
builder.file(format!("libhdfs/{version}/exception.c"));
builder.file(format!("libhdfs/{version}/jni_helper.c"));
builder.file(format!("libhdfs/{version}/hdfs.c"));
if cfg!(feature = "hdfs_2_6") || cfg!(target_os = "windows") {
builder.include(format!("libhdfs/{version}/os"));
if cfg!(target_os = "windows") {
builder.include(format!("libhdfs/{version}/os/windows"));
builder.file(format!("libhdfs/{version}/os/windows/mutexes.c"));
builder.file(format!("libhdfs/{version}/os/windows/thread.c"));
builder.file(format!(
"libhdfs/{version}/os/windows/thread_local_storage.c"
));
} else {
builder.include(format!("libhdfs/{version}/os/posix"));
builder.file(format!("libhdfs/{version}/os/posix/mutexes.c"));
builder.file(format!("libhdfs/{version}/os/posix/thread.c"));
builder.file(format!("libhdfs/{version}/os/posix/thread_local_storage.c"));
}
}
if cfg!(feature = "hdfs_2_6") && !cfg!(feature = "hdfs_3_3") {
builder.include(format!("libhdfs/{version}/common"));
builder.file(format!("libhdfs/{version}/common/htable.c"));
}
if cfg!(feature = "hdfs_2_8") {
builder.include(format!("libhdfs/{version}/include"));
}
if cfg!(feature = "hdfs_3_3") {
builder.file(format!("libhdfs/{version}/jclasses.c"));
if cfg!(target_os = "windows") {
builder.include("libdirent/include");
}
}
builder.compile("hdfs");
Ok(())
}