Files
sitk-registration-sys/build.rs
2025-09-12 18:48:37 +02:00

101 lines
4.2 KiB
Rust

use std::env;
use std::error::Error;
use std::fs;
use std::io::{Read, Write};
use std::path::PathBuf;
use std::process::Command;
fn main() -> Result<(), Box<dyn Error>> {
if env::var("DOCS_RS").is_err() & !cfg!(feature = "sitk_no_build") {
let sitk_dir = PathBuf::from("SimpleITK");
// use cmake to compile the SimpleITK C++ code
let dst = cmake::Config::new(sitk_dir.join("SuperBuild"))
.no_build_target(true)
.define("ITK_SKIP_PATH_LENGTH_CHECKS", "ON")
.define("BUILD_EXAMPLES", "OFF")
.define("BUILD_TESTING", "OFF")
.define("WRAP_CSHARP", "OFF")
.define("WRAP_JAVA", "OFF")
.define("WRAP_LUA", "OFF")
.define("WRAP_R", "OFF")
.define("WRAP_RUBY", "OFF")
.define("WRAP_TCL", "OFF")
.define("WRAP_PYTHON", "OFF")
.define("WRAP_DEFAULT", "OFF")
.define("SimpleITK_USE_ELASTIX", "ON")
.build();
// there does not seem to be any way to tell cargo to group libraries together
// when linking, so we group all objects together in three big static libraries
let merged_lib = cmake::Config::new("merged_lib")
.out_dir(dst.join("merged_lib"))
.no_build_target(true)
.build();
let mut b = autocxx_build::Builder::new(
"src/lib.rs",
["cxx", dst.join("include/SimpleITK-3.0").to_str().unwrap()],
)
.extra_clang_args(&["-std=c++17"])
.build()?;
b.flag("-std=c++17").compile("sitk_autocxx");
cc::Build::new()
.include(dst.join("include/SimpleITK-3.0"))
.file("cxx/ffi_extra.cxx")
.compile("sitk_ffi_extra");
let cxx_file = dst.join("autocxx-build-dir/rs/autocxx-ffi-default-gen.rs");
let mut cxx = String::new();
let _ = fs::File::open(&cxx_file)?.read_to_string(&mut cxx)?;
let ra = regex::Regex::new(r"\s*(#|\s(fn|use|mod|pub|struct|enum)\s)\s*")?;
let rb = regex::Regex::new(r"\s(;)\s")?;
let pointer = regex::Regex::new(r"pub type pointer = root\s+::\s+pointer;")?;
let cpp_string = regex::Regex::new(r"pub mod simple \{")?;
let rb_tree = regex::Regex::new(
r"pub type _Rb_tree_insert_return_type = root :: std :: _Node_insert_return < _Iterator , _NodeHandle >;",
)?;
{
let mut f = fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(&cxx_file)?;
write!(
f,
"#[allow(unused_imports)]\n#[allow(unsafe_op_in_unsafe_fn)]\n#[allow(clippy::missing_safety_doc)]\n"
)?;
let cxx = ra.replace_all(&cxx, "\n$1");
let cxx = rb.replace_all(&cxx, "$1\n");
let cxx = pointer.replace_all(&cxx, r"// $0");
let cxx = rb_tree.replace_all(&cxx, r"// $0");
let cxx =
cpp_string.replace_all(&cxx, "pub mod simple {\nuse crate::ffi::ToCppString;");
write!(f, "{}", cxx)?;
}
fs::copy(dst.join(&cxx_file), "src/autocxx-ffi-default-gen_unfmt.rs")?;
Command::new("rustfmt").arg(&cxx_file).status()?;
fs::copy(dst.join(&cxx_file), "src/autocxx-ffi-default-gen.rs")?;
println!("cargo:warning=merged_lib={}", merged_lib.join("build").display());
println!("cargo:rustc-link-search={}", merged_lib.join("build").display());
println!("cargo:rustc-link-lib=static=sitk_ffi_extra");
println!("cargo:rustc-link-lib=static=sitk");
println!("cargo:rustc-link-lib=static=elastix");
println!("cargo:rustc-link-lib=static=itk");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=cxx/ffi_extra.h");
println!("cargo:rerun-if-changed=cxx/ffi_extra.cxx");
} else {
let dst = PathBuf::from(env::var("OUT_DIR")?);
fs::create_dir_all(dst.join("autocxx-build-dir/rs"))?;
fs::copy(
"src/autocxx-ffi-default-gen.rs",
dst.join("autocxx-build-dir/rs/autocxx-ffi-default-gen.rs"),
)?;
}
Ok(())
}