Enable static linking, libczi is now a submodule.
This commit is contained in:
209
build.rs
209
build.rs
@@ -1,90 +1,171 @@
|
||||
use anyhow::Result;
|
||||
extern crate bindgen;
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
use std::env;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{Read, Seek, Write};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
use bindgen::callbacks::ItemInfo;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
use regex::Regex;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
if env::var("DOCS_RS").is_err() {
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR")?).canonicalize()?;
|
||||
let libczi_dir = out_dir.join("libczirw");
|
||||
let rep = if !libczi_dir.exists() {
|
||||
git2::Repository::clone("https://github.com/ZEISS/libczi.git", &libczi_dir)
|
||||
.expect("unable to clone libczirw")
|
||||
} else {
|
||||
git2::Repository::open(&libczi_dir)?
|
||||
};
|
||||
let (object, _) = rep.revparse_ext("494ac62f853de6ab86458f167fd85a03ee6d4f7e")?;
|
||||
rep.checkout_tree(&object, None)?;
|
||||
let libczi_dir = PathBuf::from("libczi");
|
||||
let libczi_src = libczi_dir.join("Src/libCZI");
|
||||
let libcziapi_inc = libczi_dir.join("Src/libCZIAPI/inc");
|
||||
let libcziapi_src = libczi_dir.join("Src/libCZIAPI/src");
|
||||
let libcziapi_h = libcziapi_inc.join("libCZIApi.h");
|
||||
|
||||
let dst = cmake::Config::new(&libczi_dir)
|
||||
.cxxflag("-fms-extensions")
|
||||
.define("LIBCZI_BUILD_UNITTESTS", "OFF")
|
||||
.define("LIBCZI_BUILD_CZICMD", "OFF")
|
||||
.define("LIBCZI_BUILD_DYNLIB", "OFF")
|
||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_EIGEN3", "OFF")
|
||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_ZSTD", "OFF")
|
||||
.define("LIBCZI_BUILD_CURL_BASED_STREAM", "OFF")
|
||||
.define("LIBCZI_BUILD_PREFER_EXTERNAL_PACKAGE_LIBCURL", "OFF")
|
||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_LIBCURL", "OFF")
|
||||
.define("LIBCZI_BUILD_AZURESDK_BASED_STREAM", "OFF")
|
||||
.define("LIBCZI_BUILD_PREFER_EXTERNALPACKAGE_RAPIDJSON", "OFF")
|
||||
.define("LIBCZI_BUILD_LIBCZIAPI", "ON")
|
||||
.build();
|
||||
|
||||
// let libcziapi_inc = libczi_dir.join("Src/libCZIAPI/inc");
|
||||
// let libczi_src = libczi_dir.join("Src/libCZI");
|
||||
// let libcziapi_src = libczi_dir.join("Src/libCZIAPI/src");
|
||||
// let libczi_h = libcziapi_inc.join("libCZIApi.h");
|
||||
|
||||
let import_export = libczi_dir.join("Src/libCZIAPI/inc/importexport.h");
|
||||
{
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open(&import_export)
|
||||
.expect("Could not open file");
|
||||
|
||||
let mut data = String::new();
|
||||
file.read_to_string(&mut data).expect("Could not read file");
|
||||
let data = data.replace(" __declspec(dllexport)", "");
|
||||
let bytes = data.as_bytes();
|
||||
(&file).rewind().expect("Could not rewind");
|
||||
(&file).write_all(bytes).expect("Could not write file");
|
||||
file.set_len(bytes.len() as u64)
|
||||
.expect("Could not truncate");
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
let bindings = {
|
||||
let mut libcziapi_a = out_dir.join("build/Src/libCZIAPI/liblibCZIAPIStatic.a");
|
||||
if !libcziapi_a.exists() {
|
||||
libcziapi_a = out_dir.join("build/Src/libCZIAPI/liblibCZIAPIStatic.lib");
|
||||
}
|
||||
bindgen::Builder::default().parse_callbacks(Box::new(DeMangler::new(libcziapi_a)?))
|
||||
};
|
||||
|
||||
// let bindings = bindgen::Builder::default()
|
||||
// .clang_args([
|
||||
// "-x",
|
||||
// "c++",
|
||||
// "-std=c++14",
|
||||
// "-I",
|
||||
// libcziapi_inc
|
||||
// .to_str()
|
||||
// .ok_or(Error::msg("cannot into string"))?,
|
||||
// "-I",
|
||||
// libcziapi_src
|
||||
// .to_str()
|
||||
// .ok_or(Error::msg("cannot into string"))?,
|
||||
// "-I",
|
||||
// libczi_src
|
||||
// .to_str()
|
||||
// .ok_or(Error::msg("cannot into string"))?,
|
||||
// ])
|
||||
// .header(libczi_h.to_str().ok_or(Error::msg("cannot into string"))?)
|
||||
// .generate()
|
||||
// .expect("Unable to generate bindings");
|
||||
//
|
||||
// bindings
|
||||
// .write_to_file(out_dir.join("lib_czi_api.rs"))
|
||||
// .expect("Couldn't write bindings!");
|
||||
#[cfg(feature = "dynamic")]
|
||||
let bindings = bindgen::Builder::default();
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
dst.join("build/Src/libCZIAPI").display()
|
||||
);
|
||||
println!("cargo:rustc-link-lib=libCZIAPI");
|
||||
let bindings = bindings
|
||||
.merge_extern_blocks(true)
|
||||
.clang_args([
|
||||
"-fms-extensions",
|
||||
"-x",
|
||||
"c++",
|
||||
"-std=c++14",
|
||||
"-I",
|
||||
libcziapi_inc
|
||||
.to_str()
|
||||
.ok_or(Error::msg("cannot into string"))?,
|
||||
"-I",
|
||||
libcziapi_src
|
||||
.to_str()
|
||||
.ok_or(Error::msg("cannot into string"))?,
|
||||
"-I",
|
||||
libczi_src
|
||||
.to_str()
|
||||
.ok_or(Error::msg("cannot into string"))?,
|
||||
])
|
||||
.header(
|
||||
libcziapi_h
|
||||
.to_str()
|
||||
.ok_or(Error::msg("cannot into string"))?,
|
||||
)
|
||||
.generate()?;
|
||||
|
||||
bindings.write_to_file(out_dir.join("lib_czi_api.rs"))?;
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
{
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
dst.join("build/Src/libCZIAPI").display()
|
||||
);
|
||||
println!("cargo:rustc-link-lib=static=libCZIAPIStatic");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
dst.join("build/Src/libCZI").display()
|
||||
);
|
||||
let profile = env::var("PROFILE")?;
|
||||
match profile.as_str() {
|
||||
"debug" => println!("cargo:rustc-link-lib=static=libCZIStaticd"),
|
||||
"release" => println!("cargo:rustc-link-lib=static=libCZIStatic"),
|
||||
_ => return Err(Error::msg(format!("unsupported profile: {}", profile))),
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
dst.join("lib").display()
|
||||
);
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
dst.join("lib64").display()
|
||||
);
|
||||
println!("cargo:rustc-link-lib=static=zstd");
|
||||
}
|
||||
|
||||
#[cfg(feature = "dynamic")]
|
||||
{
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
dst.join("build/Src/libCZIAPI").display()
|
||||
);
|
||||
println!("cargo:rustc-link-lib=libCZIAPI");
|
||||
}
|
||||
}
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
#[derive(Debug)]
|
||||
struct DeMangler {
|
||||
map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
impl DeMangler {
|
||||
fn new(a_file: PathBuf) -> Result<Self> {
|
||||
let cmd = std::process::Command::new("nm").arg(&a_file).output()?;
|
||||
let pat = Regex::new(r"^[\da-f]*\s[A-Z]\s(.*_Z(\d+)(libCZI_.*))$")?;
|
||||
let mut map = HashMap::new();
|
||||
for line in std::str::from_utf8(&cmd.stdout)?.lines() {
|
||||
if let Some(caps) = pat.captures(line.trim()) {
|
||||
if let (Some(symbol), Some(n), Some(name)) = (caps.get(1), caps.get(2), caps.get(3))
|
||||
{
|
||||
let n: usize = n.as_str().parse()?;
|
||||
let name = name.as_str();
|
||||
let demangled = name[..n].to_string();
|
||||
let mangled = symbol.as_str().to_string();
|
||||
if let Some(existing_mangled) = map.get(&demangled) {
|
||||
if existing_mangled != &mangled {
|
||||
return Err(Error::msg(format!(
|
||||
"conflicting mangled symbols for {} in {}: {}, {}",
|
||||
demangled,
|
||||
a_file.to_str().unwrap(),
|
||||
existing_mangled,
|
||||
mangled
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
map.insert(demangled, mangled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Self { map })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "dynamic"))]
|
||||
impl bindgen::callbacks::ParseCallbacks for DeMangler {
|
||||
fn generated_link_name_override(&self, item_info: ItemInfo<'_>) -> Option<String> {
|
||||
self.map.get(item_info.name).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user