use std::path::{Path, PathBuf};
use std::{env, fs};
fn main() {
println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=open_wbo_wrapper/library.cpp");
println!("cargo:rerun-if-changed=open_wbo_wrapper/include/library.h");
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let lib_name = format!("_{os}_{arch}_open_wbo");
let lib_file_name = format!("lib{lib_name}.a");
let open_wbo_path = std::path::Path::new("open_wbo/");
let out_dir = env::var("OUT_DIR").expect("$OUT_DIR is not set");
let operating_path = PathBuf::from(&out_dir);
let lib_path = operating_path.join(lib_file_name);
if !lib_path.exists() {
build_open_wbo(open_wbo_path, &lib_path, &operating_path.join("logicng-open-wbo-src"), &os, &arch);
}
println!("cargo:rustc-link-search={}", out_dir);
println!("cargo:rustc-link-lib=static={lib_name}");
if os == "linux" {
println!("cargo:rustc-link-lib=gmpxx");
println!("cargo:rustc-link-lib=gmp");
}
let mut build = cxx_build::bridge("src/lib.rs");
build
.include(open_wbo_path.join("include/"))
.flag("-w") .file("open_wbo_wrapper/library.cpp");
if os == "macos" && arch == "aarch64" {
build.include("/opt/homebrew/include");
}
if build.get_compiler().is_like_clang() || build.get_compiler().is_like_gnu() {
build.flag("-std=c++11");
} else {
build.flag("/std:c++14"); };
build.compile("open_wbo_wrapper");
}
fn build_open_wbo(open_wbo_path: &std::path::Path, lib_path: &std::path::Path, operating_path: &std::path::Path, os: &str, arch: &str) {
let open_wbo_src_path = open_wbo_path.join("logicng-open-wbo");
if !open_wbo_src_path.exists() {
panic!("Cannot build OpenWBO, because the source code is missing.")
}
copy_src(&open_wbo_src_path, operating_path);
let mut make = std::process::Command::new("make");
if os == "macos" && arch == "aarch64" {
make.env("CPATH", "/opt/homebrew/include");
}
make.current_dir(operating_path).arg("libr");
if let Err(e) = make.status() {
panic!("Building OpenWBO failed with: {}", e);
}
let lib_src_path = operating_path.join("lib_release.a");
if let Err(e) = std::fs::copy(lib_src_path, lib_path) {
panic!("Building OpenWBO failed with: {}", e);
}
if let Err(e) = fs::remove_dir_all(operating_path) {
panic!("Building OpenWBO failed with: {}", e)
}
}
fn copy_src(src: &Path, dst: &Path) {
fs::create_dir_all(dst).expect("Couldn't create root directory");
for entry in fs::read_dir(src).expect("Couldn't read directory") {
let entry = entry.expect("Couldn't read file");
let ty = entry.file_type().expect("Couldn't access filetype");
if ty.is_dir() {
copy_src(&entry.path(), &dst.join(entry.file_name()));
} else {
fs::copy(entry.path(), dst.join(entry.file_name())).expect("Couldn't copy file");
}
}
}