76 lines
3.2 KiB
Rust
76 lines
3.2 KiB
Rust
//! builds the engine archives and generates FFI bindings for femm-sys.
|
|
|
|
use std::env;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
|
|
fn main() {
|
|
let manifest = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
|
let repo_root = manifest.parent().unwrap().parent().unwrap().to_path_buf();
|
|
let ffi_dir = repo_root.join("ffi");
|
|
let build_dir = repo_root.join("build").join("ffi");
|
|
|
|
// re-run on changes to any FFI header, build script, or solver source dir.
|
|
println!("cargo:rerun-if-changed={}", ffi_dir.display());
|
|
println!("cargo:rerun-if-changed={}", repo_root.join("scripts/macos/build_ffi.sh").display());
|
|
println!("cargo:rerun-if-changed={}", repo_root.join("scripts/windows/build_ffi.ps1").display());
|
|
println!("cargo:rerun-if-changed={}", repo_root.join("scripts/windows/_toolchain.ps1").display());
|
|
for engine in ["fkn", "belasolv", "csolv", "hsolv", "liblua", "compat"] {
|
|
println!("cargo:rerun-if-changed={}", repo_root.join(engine).display());
|
|
}
|
|
|
|
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
|
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
|
|
let status = match target_os.as_str() {
|
|
"macos" => Command::new("bash")
|
|
.arg(repo_root.join("scripts/macos/build_ffi.sh"))
|
|
.status()
|
|
.expect("failed to invoke bash for engine build script"),
|
|
"windows" => {
|
|
let script = repo_root.join("scripts/windows/build_ffi.ps1");
|
|
Command::new("pwsh")
|
|
.args([
|
|
"-NoProfile",
|
|
"-ExecutionPolicy",
|
|
"Bypass",
|
|
"-File",
|
|
])
|
|
.arg(&script)
|
|
.status()
|
|
.expect("failed to invoke pwsh for engine build script")
|
|
}
|
|
other => panic!("femm-sys: no engine build script wired up for target_os={other}"),
|
|
};
|
|
if !status.success() {
|
|
panic!("engine build script exited with {status}");
|
|
}
|
|
|
|
println!("cargo:rustc-link-search=native={}", build_dir.display());
|
|
for lib in ["femm_mag", "femm_elec", "femm_heat", "femm_curr"] {
|
|
println!("cargo:rustc-link-lib=static={lib}");
|
|
}
|
|
match (target_os.as_str(), target_env.as_str()) {
|
|
("macos", _) => println!("cargo:rustc-link-lib=dylib=c++"),
|
|
("windows", "gnu") => println!("cargo:rustc-link-lib=dylib=stdc++"),
|
|
("windows", "gnullvm") => println!("cargo:rustc-link-lib=dylib=c++"),
|
|
("windows", "msvc") => { /* MSVC links the C++ runtime automatically */ }
|
|
_ => println!("cargo:rustc-link-lib=dylib=stdc++"),
|
|
}
|
|
|
|
let bindings = bindgen::Builder::default()
|
|
.header(manifest.join("wrapper.h").to_str().unwrap())
|
|
.clang_arg(format!("-I{}", ffi_dir.display()))
|
|
.allowlist_function("femm_.*")
|
|
.allowlist_type("Femm.*")
|
|
.allowlist_var("FEMM_.*")
|
|
.derive_default(true)
|
|
.derive_copy(true)
|
|
.derive_debug(true)
|
|
.layout_tests(false)
|
|
.generate()
|
|
.expect("bindgen failed to generate FFI bindings");
|
|
|
|
let out = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs");
|
|
bindings.write_to_file(&out).expect("failed to write bindings.rs");
|
|
}
|