fn main() {
if std::env::var("CARGO_FEATURE_USE_CPP").is_ok() {
build_cpp();
}
}
fn build_cpp() {
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let out_dir = std::env::var("OUT_DIR").unwrap();
let cpp_src = format!("{}/cloudini-cpp/cloudini_lib", manifest_dir);
let build_dir = format!("{}/cloudini_cpp_build", out_dir);
println!("cargo:rerun-if-changed={}/src/cloudini.cpp", cpp_src);
println!("cargo:rerun-if-changed={}/src/field_encoder.cpp", cpp_src);
println!("cargo:rerun-if-changed={}/src/field_decoder.cpp", cpp_src);
println!("cargo:rerun-if-changed={}/src/cloudini_c.cpp", cpp_src);
println!(
"cargo:rerun-if-changed={}/include/cloudini_lib/cloudini_c.h",
cpp_src
);
let cmake_cache = std::path::PathBuf::from(&build_dir).join("CMakeCache.txt");
if cmake_cache.exists() {
let content = std::fs::read_to_string(&cmake_cache).unwrap_or_default();
if !content.contains(&cpp_src) {
std::fs::remove_dir_all(&build_dir).ok();
}
}
std::fs::create_dir_all(&build_dir).expect("failed to create cmake build dir");
let status = std::process::Command::new("cmake")
.arg("-S")
.arg(&cpp_src)
.arg("-B")
.arg(&build_dir)
.arg("-DCMAKE_BUILD_TYPE=Release")
.arg("-DCLOUDINI_BUILD_BENCHMARKS=OFF")
.arg("-DCLOUDINI_BUILD_TOOLS=OFF")
.arg("-DBUILD_TESTING=OFF")
.arg("-DCLOUDINI_FORCE_VENDORED_DEPS=ON")
.status()
.expect("cmake not found — install cmake to use the `use_cpp` feature");
assert!(status.success(), "cmake configure step failed");
let ncpus = std::thread::available_parallelism()
.map(|n| n.get().to_string())
.unwrap_or_else(|_| "4".to_string());
let status = std::process::Command::new("cmake")
.arg("--build")
.arg(&build_dir)
.arg("--config")
.arg("Release")
.arg("--parallel")
.arg(&ncpus)
.status()
.expect("cmake --build failed");
assert!(status.success(), "cmake build step failed");
fn link_lib(build_dir: &str, lib_name: &str) {
let pattern = format!("lib{}.a", lib_name);
let output = std::process::Command::new("find")
.arg(build_dir)
.arg("-name")
.arg(&pattern)
.output()
.expect("find command failed");
let found = String::from_utf8(output.stdout).unwrap();
for path_str in found.lines() {
let path = std::path::Path::new(path_str.trim());
if let Some(dir) = path.parent() {
println!("cargo:rustc-link-search=native={}", dir.display());
}
}
println!("cargo:rustc-link-lib=static={}", lib_name);
}
link_lib(&build_dir, "cloudini_lib");
link_lib(&build_dir, "lz4_static");
link_lib(&build_dir, "libzstd_static");
let target = std::env::var("TARGET").unwrap_or_default();
if target.contains("apple") {
println!("cargo:rustc-link-lib=c++");
} else {
println!("cargo:rustc-link-lib=stdc++");
}
}