use std::path::PathBuf;
use std::process;
use wolfram_app_discovery::WolframApp;
fn main() {
if std::env::var("DOCS_RS").is_ok() {
return;
}
let app = WolframApp::try_default().expect("unable to locate WolframApp");
let static_lib = &app
.wstp_static_library_path()
.expect("unable to get WSTP static library path");
link_wstp_statically(&static_lib);
println!("cargo:rustc-link-lib=dylib=c++");
if cfg!(target_os = "macos") {
println!("cargo:rustc-link-lib=framework=Foundation");
}
let wolfram_version = app
.wolfram_version()
.expect("unable to get Wolfram Language vesion number");
let system_id =
wolfram_app_discovery::system_id_from_target(&std::env::var("TARGET").unwrap())
.expect("unable to get System ID for target system");
let bindings_path = PathBuf::from("generated")
.join(&wolfram_version.to_string())
.join(system_id)
.join("WSTP_bindings.rs");
println!("cargo:rerun-if-changed={}", bindings_path.display());
let absolute_bindings_path =
PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()).join(&bindings_path);
if !absolute_bindings_path.is_file() {
println!(
"
==== ERROR: wstp-sys =====
Rust bindings for Wolfram WSTP for target configuration:
WolframVersion: {}
SystemID: {}
have not been pre-generated.
See wstp-sys/generated/ for a listing of currently available targets.
=========================================
",
wolfram_version, system_id
);
panic!("<See printed error>");
}
println!(
"cargo:rustc-env=CRATE_WSTP_SYS_BINDINGS={}",
bindings_path.display()
);
}
fn link_wstp_statically(lib: &PathBuf) {
let mut lib = lib.clone();
if cfg!(all(target_os = "macos", target_arch = "x86_64")) {
lib = lipo_native_library(&lib);
}
link_library_file(lib);
}
fn lipo_native_library(wstp_lib: &PathBuf) -> PathBuf {
let wstp_lib = wstp_lib.to_str()
.expect("could not convert WSTP archive path to str");
let is_universal_binary = {
let stdout = process::Command::new("file")
.args(&[wstp_lib])
.output()
.expect("failed to run `file` system utility").stdout;
let stdout = String::from_utf8(stdout).unwrap();
stdout.contains("Mach-O universal binary")
};
if !is_universal_binary {
return PathBuf::from(wstp_lib);
}
let output_lib = std::env::temp_dir().join("libWSTP-x86-64.a");
let output_lib = output_lib.to_str()
.expect("could not convert WSTP archive path to str");
let output = process::Command::new("lipo")
.args(&[wstp_lib, "-thin", "x86_64", "-output", output_lib])
.output()
.expect("failed to invoke macOS `lipo` command");
if !output.status.success() {
panic!("unable to lipo WSTP library: {:#?}", output);
}
PathBuf::from(output_lib)
}
fn link_library_file(libfile: PathBuf) {
let search_dir = libfile.parent().unwrap().display().to_string();
let libname = libfile
.file_stem()
.unwrap()
.to_str()
.unwrap()
.trim_start_matches("lib");
println!("cargo:rustc-link-search={}", search_dir);
println!("cargo:rustc-link-lib=static={}", libname);
}