use std::path::Path;
fn main() {
if std::env::var_os("CARGO_FEATURE_DYNAMIC").is_some() {
println!("cargo:rustc-link-lib=klu");
} else {
let src_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("vendor");
build_suitesparse_config(&src_dir);
for long in [true, false] {
build_amd(&src_dir, long);
build_colamd(&src_dir, long);
build_btf(&src_dir, long);
build_amd(&src_dir, long);
build_klu_common(&src_dir, long);
for complex in [true, false] {
build_klu(&src_dir, long, complex);
}
}
}
}
fn build_suitesparse_config(src_dir: &Path) {
cc::Build::new()
.file(
src_dir
.join("SuiteSparse_config")
.join("SuiteSparse_config.c"),
)
.compile("suitesparseconfig");
}
fn setup_suitesparse_builder(long: bool, src_dir: &Path) -> cc::Build {
let mut builder = cc::Build::new();
if long {
builder.define("DLONG", None);
}
builder.include(src_dir.join("SuiteSparse_config"));
builder
}
fn build_amd(src_dir: &Path, long: bool) {
let mut builder = setup_suitesparse_builder(long, src_dir);
let dir = src_dir.join("AMD");
let amd_src_dir = dir.join("Source");
builder.include(dir.join("Include"));
let amd_objects = [
"amd_1",
"amd_2",
"amd_aat",
"amd_control",
"amd_defaults",
"amd_dump",
"amd_global",
"amd_info",
"amd_order",
"amd_post_tree",
"amd_postorder",
"amd_preprocess",
"amd_valid",
];
for obj in amd_objects.iter() {
builder.file(&amd_src_dir.join(format!("{obj}.c")));
}
builder.compile(if long { "amdl" } else { "amd" });
}
fn build_colamd(src_dir: &Path, long: bool) {
let mut builder = setup_suitesparse_builder(long, src_dir);
let dir = src_dir.join("COLAMD");
let src = dir.join("Source").join("colamd.c");
builder.include(dir.join("Include")).file(src);
builder.compile(if long { "colamdl" } else { "colamd" });
}
fn build_btf(src_dir: &Path, long: bool) {
let mut builder = setup_suitesparse_builder(long, src_dir);
let dir = src_dir.join("BTF");
let btf_src_dir = dir.join("Source");
builder.include(dir.join("Include"));
let btf_objects = ["btf_maxtrans", "btf_order", "btf_strongcomp"];
for obj in btf_objects.iter() {
builder.file(&btf_src_dir.join(format!("{}.c", obj)));
}
builder.compile(if long { "btfl" } else { "btf" });
}
fn build_klu_common(src_dir: &Path, long: bool) {
let klu_src = src_dir.join("KLU").join("Source");
let mut builder = setup_suitesparse_builder(long, src_dir);
let objects = [
"_analyze",
"_analyze_given",
"_defaults",
"_memory",
"_free_symbolic",
];
for obj in &objects {
builder.file(klu_src.join(format!("klu{}.c", obj)));
}
builder
.include(src_dir.join("KLU").join("Include"))
.include(src_dir.join("AMD").join("Include"))
.include(src_dir.join("COLAMD").join("Include"))
.include(src_dir.join("BTF").join("Include"))
.include(src_dir.join("SuiteSparse_config"))
.compile(if long { "klul_common" } else { "klu_common" });
}
fn build_klu(src_dir: &Path, long: bool, complex: bool) {
let klu_src = src_dir.join("KLU").join("Source");
let mut builder = setup_suitesparse_builder(long, src_dir);
let mut name = "klu".to_string();
if long {
builder.define("DLONG", None);
name.push('l');
}
if complex {
builder.define("COMPLEX", None);
name.push('z');
}
let objects = [
"",
"_diagnostics",
"_dump",
"_factor",
"_free_numeric",
"_kernel",
"_refactor",
"_scale",
"_solve",
"_sort",
"_tsolve",
];
for obj in &objects {
builder.file(klu_src.join(format!("klu{}.c", obj)));
}
builder
.include(src_dir.join("KLU").join("Include"))
.include(src_dir.join("AMD").join("Include"))
.include(src_dir.join("COLAMD").join("Include"))
.include(src_dir.join("BTF").join("Include"))
.include(src_dir.join("SuiteSparse_config"))
.compile(&name);
}