Now build SimpleITK into static libs and use (auto)cxx.
This commit is contained in:
148
build.rs
148
build.rs
@@ -1,61 +1,99 @@
|
||||
use cmake::Config;
|
||||
use git2::Repository;
|
||||
use std::ffi::OsStr;
|
||||
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() {
|
||||
if std::env::var("DOCS_RS").is_err() {
|
||||
let out_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR is undefined"));
|
||||
let mut target_dir = out_dir.clone();
|
||||
while target_dir.file_name() != Some(OsStr::new("target")) {
|
||||
if !target_dir.pop() {
|
||||
panic!("Could not find target directory");
|
||||
}
|
||||
}
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
if env::var("DOCS_RS").is_err() & !cfg!(feature = "sitk_no_build") {
|
||||
let sitk_dir = PathBuf::from("SimpleITK");
|
||||
|
||||
let sitk_dir = if let Some(d) = target_dir.parent() {
|
||||
d.join("sitk").to_path_buf()
|
||||
} else {
|
||||
target_dir.join("sitk")
|
||||
};
|
||||
if !sitk_dir.exists() {
|
||||
Repository::clone("https://github.com/SimpleITK/SimpleITK.git", &sitk_dir)
|
||||
.expect("unable to clone sitk");
|
||||
}
|
||||
|
||||
let sitk_build_dir = sitk_dir.join("build");
|
||||
if !sitk_build_dir.exists() {
|
||||
println!("cargo::warning=Simple ITK; this will take a long time...");
|
||||
Config::new(sitk_dir.join("SuperBuild"))
|
||||
.out_dir(&sitk_dir)
|
||||
.no_build_target(true)
|
||||
.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();
|
||||
}
|
||||
println!(
|
||||
"cargo::rustc-env=CMAKE_INSTALL_PREFIX={}",
|
||||
out_dir.display()
|
||||
);
|
||||
let path = Config::new("cpp")
|
||||
.very_verbose(true)
|
||||
.define("Elastix_DIR", sitk_build_dir.join("Elastix-build"))
|
||||
.define("ITK_DIR", sitk_build_dir.join("ITK-build"))
|
||||
.define("SimpleITK_DIR", sitk_build_dir.join("SimpleITK-build"))
|
||||
.define("CMAKE_INSTALL_PREFIX", out_dir)
|
||||
// use cmake to compile the SimpleITK C++ code
|
||||
let dst = cmake::Config::new(sitk_dir.join("SuperBuild"))
|
||||
.no_build_target(true)
|
||||
.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();
|
||||
println!("cargo::rustc-link-arg=-Wl,-rpath,{}", path.display());
|
||||
println!("cargo::rustc-link-search={}", path.join("build").display());
|
||||
println!("cargo::rustc-link-lib=dylib=sitk_adapter");
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
println!("cargo::rerun-if-changed=cpp");
|
||||
|
||||
// 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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user