use std::env;
use std::path::{Path, PathBuf};
fn generate_bindings<'a>(include_paths: impl Iterator<Item = &'a Path>) {
let builder = include_paths.fold(bindgen::Builder::default(), |builder, path| {
builder.clang_arg(format!("-I{}", path.to_string_lossy()))
});
let c_bindings = builder
.header("wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
c_bindings
.write_to_file(out_path.join("c_bindings.rs"))
.expect("Couldn't write bindings!");
}
#[cfg(feature = "build")]
fn build() -> bool {
use cmake::Config;
let mut dst = Config::new("HiGHS");
if cfg!(feature = "ninja") {
dst.generator("Ninja");
}
if cfg!(feature = "highs_release") {
dst.profile("Release");
}
let dst = dst
.define("FAST_BUILD", "ON")
.define("BUILD_SHARED_LIBS", "OFF")
.define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreadedDLL")
.define("CMAKE_INTERPROCEDURAL_OPTIMIZATION", "FALSE")
.build();
let include_path = dst.join("include").join("highs");
generate_bindings(Some(include_path.as_path()).into_iter());
println!("cargo:rustc-link-search=native={}/lib", dst.display());
println!("cargo:rustc-link-search=native={}/lib64", dst.display());
println!("cargo:rustc-link-lib=static=highs");
if cfg!(feature = "libz") {
println!("cargo:rustc-link-lib=z");
}
let target = env::var("TARGET").unwrap();
let apple = target.contains("apple");
let linux = target.contains("linux");
if apple {
println!("cargo:rustc-link-lib=dylib=c++");
} else if linux {
println!("cargo:rustc-link-lib=dylib=stdc++");
}
println!("cargo:rerun-if-changed=HiGHS/src/interfaces/highs_c_api.h");
true
}
#[cfg(not(feature = "build"))]
fn build() -> bool {
false
}
#[cfg(feature = "discover")]
fn discover() -> bool {
let lib = match pkg_config::Config::new()
.atleast_version("1.5.0")
.probe("highs")
{
Ok(lib) => lib,
Err(_e) => return false,
};
generate_bindings(lib.include_paths.iter().map(|p| p.as_path()));
true
}
#[cfg(not(feature = "discover"))]
fn discover() -> bool {
false
}
fn main() {
if cfg!(all(
any(
feature = "highs_release",
feature = "libz",
feature = "ninja"
),
not(feature = "build")
)) {
panic!("You have enabled features that control how HiGHS is built, but have not enabled the 'build' feature.\n\
Thus, your features will never have any effect. Please enable the 'build' feature on highs-sys if you want to build HiGHS or disable the 'libz', 'ninja' and 'highs_release' features.");
}
if !discover() && !build() {
panic!("Could neither discover nor build HiGHS");
}
}