use std::env;
use std::path::{Path, PathBuf};
fn configure(mut cc: &mut cc::Build) {
println!("cargo:rerun-if-changed=minimap2/*.c");
cc.include("minimap2");
cc.opt_level(2);
#[cfg(feature = "sse2only")]
sse2only(&mut cc);
#[cfg(feature = "simde")]
simde(&mut cc);
cc.include("minimap2/");
let files: Vec<_> = std::fs::read_dir("minimap2")
.unwrap()
.map(|f| f.unwrap().path())
.collect();
assert!(files.len() != 0, "No files found in minimap2 directory -- Did you forget to clone the submodule? git submodule init --recursive");
for file in files {
if file.file_name().unwrap() == "main.c" || file.file_name().unwrap() == "example.c" {
continue;
}
if file.file_name().unwrap().to_str().unwrap().contains("neon") {
continue;
}
if file.file_name().unwrap().to_str().unwrap().contains("ksw") {
continue;
}
if let Some(x) = file.extension() {
if x == "c" {
cc.file(file);
}
}
}
cc.file("minimap2/ksw2_ll_sse.c");
#[cfg(not(feature = "noopt"))]
target_specific(&mut cc);
}
fn target_specific(cc: &mut cc::Build) {
let target = env::var("TARGET").unwrap();
if target.contains("aarch64") | target.contains("arm") {
cc.include("minimap2/sse2neon/");
cc.file("minimap2/ksw2_extz2_sse.c");
cc.file("minimap2/ksw2_extd2_sse.c");
cc.file("minimap2/ksw2_exts2_sse.c");
cc.flag("-DKSW_SSE2_ONLY");
cc.flag("-D_FILE_OFFSET_BITS=64");
cc.flag("-fsigned-char");
cc.flag("-Isse2neon");
cc.flag("-D__SSE2__");
} else if target.contains("x86_64") {
#[cfg(all(
target_feature = "sse4.1",
not(feature = "simde"),
not(feature = "sse2only")
))]
cc.flag("-msse4.1");
if target.contains("aarch64") {
cc.include("minimap2/sse2neon/");
cc.file("minimap2/ksw2_extz2_neon.c");
cc.file("minimap2/ksw2_extd2_neon.c");
cc.file("minimap2/ksw2_exts2_neon.c");
cc.flag("-D_FILE_OFFSET_BITS=64");
cc.flag("-fsigned-char");
cc.flag("-Isse2neon");
cc.flag("-D__SSE2__");
}
#[cfg(all(not(target_feature = "sse4.1"), target_feature = "sse2",))]
{
cc.flag("-msse2");
}
#[cfg(all(not(target_feature = "sse4.1"), target_feature = "sse2"))]
cc.flag("-DKSW_SSE2_ONLY");
#[cfg(all(not(target_feature = "sse4.1"), target_feature = "sse2",))]
cc.flag("-mno-sse4.1");
cc.file("minimap2/ksw2_extz2_sse.c");
cc.file("minimap2/ksw2_extd2_sse.c");
cc.file("minimap2/ksw2_exts2_sse.c");
}
}
#[cfg(feature = "simde")]
fn simde(cc: &mut cc::Build) {
cc.include("minimap2/lib/simde");
cc.flag("-DSIMDE_ENABLE_NATIVE_ALIASES");
cc.flag("-DUSE_SIMDE");
cc.flag("-std=c99");
}
fn compile() {
let mut cc = cc::Build::new();
cc.warnings(false);
cc.flag_if_supported("-Wno-unused-result");
let out_path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let _host = env::var("HOST").unwrap();
let _target = env::var("TARGET").unwrap();
println!("cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR");
println!("cargo:rustc-link-lib=m");
println!("cargo:rustc-link-lib=z");
if !env::var("TARGET").unwrap().contains("android") {
println!("cargo:rustc-link-lib=pthread");
cc.flag("-lpthread");
}
if env::var("CARGO_CFG_TARGET_OS").unwrap() == "android" {
android();
}
cc.flag("-lm");
cc.flag("-lz");
let mut cc = cc::Build::new();
cc.flag_if_supported("-Wno-unused-result");
cc.warnings(false);
cc.flag("-Wc++-compat");
cc.out_dir(&out_path);
configure(&mut cc);
cc.flag("-DHAVE_KALLOC");
#[cfg(feature = "static")]
cc.static_flag(true);
if let Some(include) = std::env::var_os("DEP_Z_INCLUDE") {
cc.include(include.clone());
if let Some(lib) = std::env::var_os("DEP_Z_ROOT") {
let lib = lib.to_str().unwrap();
println!("cargo:rustc-link-search=native={}", lib);
println!("cargo:rustc-link-lib=static=z");
}
}
if let Ok(lib) = pkg_config::find_library("zlib") {
for path in &lib.include_paths {
cc.include(path);
}
}
cc.compile("libminimap");
}
#[cfg(feature = "sse2only")]
fn sse2only(cc: &mut cc::Build) {
#[cfg(all(target_feature = "sse2", not(target_feature = "sse4.1")))]
cc.flag("-DKSW_SSE2_ONLY");
#[cfg(all(target_feature = "sse2", not(target_feature = "sse4.1")))]
cc.flag("-mno-sse4.1");
let target = env::var("TARGET").unwrap_or_default();
if target.contains("x86_64") {
#[cfg(all(
not(target_feature = "sse4.1"),
target_feature = "sse2",
not(target_arch = "aarch64")
))]
{
cc.flag("-msse2");
}
}
}
#[cfg(feature = "bindgen")]
fn gen_bindings() {
let out_path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut bindgen = bindgen::Builder::default()
.derive_debug(true)
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.rustfmt_bindings(true);
let mut bindgen = bindgen.header("minimap2.h");
bindgen
.generate_cstr(true)
.generate()
.expect("Couldn't write bindings!")
.write_to_file(out_path.join("bindings.rs"))
.expect("Unable to create bindings");
}
#[cfg(not(feature = "bindgen"))]
fn gen_bindings() {}
fn android() {
println!("cargo:rustc-link-lib=z");
if let Ok(sysroot) = env::var("CROSS_SYSROOT") {
let path = PathBuf::from(sysroot).join("usr/lib");
let path = path.join(&env::var("TARGET").unwrap());
println!("cargo:rustc-link-search=native={}", path.display());
let path = path.join("libz.so");
println!("cargo:rustc-link-search=native={}", path.display());
println!("cargo:rustc-link-lib=static=z");
}
if let Ok(output_path) = env::var("CARGO_NDK_OUTPUT_PATH") {
let sysroot_libs_path =
PathBuf::from(env::var_os("CARGO_NDK_SYSROOT_LIBS_PATH").unwrap());
let lib_path = sysroot_libs_path.join("libz.so");
std::fs::copy(
lib_path,
Path::new(&output_path)
.join(&env::var("CARGO_NDK_ANDROID_TARGET").unwrap())
.join("libz.so"),
)
.unwrap();
}
}
fn main() {
compile();
gen_bindings();
}