const LIB_NOT_FOUND_TIPS: &str = "The library is not found in system path! Please download and install ic4 sdk in your computer! Link: https://www.theimagingsource.com/zh-hans-cn/support/download/icimagingcontrol4win-1.1.0.2833/";
#[cfg(target_arch = "x86")]
const DLL_FILE_NAME: &str = "tisgrabber.dll";
#[cfg(target_arch = "x86_64")]
const DLL_FILE_NAME: &str = "tisgrabber_x64.dll";
#[cfg(target_arch = "x86")]
const LIB_NAME: &str = "tisgrabber";
#[cfg(target_arch = "x86_64")]
const LIB_NAME: &str = "tisgrabber_x64";
use std::env;
#[allow(unused)]
use std::io::Write;
use std::path::{Path, PathBuf};
use once_cell::sync::Lazy;
#[allow(unused)]
static MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR");
#[allow(unused)]
static OUT_DIR: Lazy<PathBuf> = Lazy::new(|| {
let path = env::var_os("OUT_DIR").expect("The OUT_DIR environment variable is not set");
PathBuf::from(path)
});
#[allow(unused)]
const BINDGEN_RS_FILE_HEADER_OLD: &str = "/*
* 注意:不要修改此文件。
* 此文件由bindgen生成,转换自特定的一个或多个C++头文件。详见build.rs文件。
*/
#![allow(unused)]
#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
";
#[cfg(feature = "buildtime-bindgen")]
const BINDGEN_RS_FILE_HEADER: &str = "";
fn main() {
let path_ori = std::env::var_os("Path").unwrap();
let paths = std::env::split_paths(&path_ori);
let lib_root = paths
.into_iter()
.find(|path| path.join(DLL_FILE_NAME).is_file())
.map(|path| path.join("..").join(".."))
.expect(LIB_NOT_FOUND_TIPS);
#[cfg(feature = "buildtime-bindgen")]
lib_bindgen(&lib_root);
lib_link(&lib_root);
}
#[cfg(feature = "buildtime-bindgen")]
fn lib_bindgen(lib_root: &Path) {
let ic4_include_dir = lib_root.join("include");
let current_dir = std::env::current_dir().unwrap();
let ic4_header_paths = [current_dir.join("wrapper.hpp")].into_iter();
let bindings = ic4_header_paths.fold(bindgen::Builder::default(), |builder, path| {
let path_str = path.to_string_lossy();
builder.header(path_str.as_ref())
});
#[rustfmt::skip]
let bindings = bindings
.use_core()
.size_t_is_usize(true)
.default_macro_constant_type(bindgen::MacroTypeVariation::Signed)
.fit_macro_constants(true)
.respect_cxx_access_specs(true)
.default_enum_style(bindgen::EnumVariation::Rust {
non_exhaustive: false,
})
.default_alias_style(bindgen::AliasVariation::NewTypeDeref)
.generate_block(true)
.generate_cstr(true)
.c_naming(false)
;
let bindings = bindings
.derive_default(true)
.derive_partialeq(true)
.derive_eq(true);
let bindings = bindings.clang_args(["-I", ic4_include_dir.to_string_lossy().as_ref()]);
let bindings = bindings.clang_arg("-std=c++17");
let bindings = bindings
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings");
let target_rs_file_path = Path::new(MANIFEST_DIR).join("bindings").join("bindings.rs");
let mut writer = std::io::BufWriter::new(std::fs::File::create(target_rs_file_path).unwrap());
writer
.write_all(
BINDGEN_RS_FILE_HEADER
.bytes()
.collect::<Vec<u8>>()
.as_slice(),
)
.unwrap();
bindings
.write(Box::new(&mut writer))
.expect("Couldn't write bindings!");
}
fn lib_link(lib_root: &Path) {
#[cfg(target_arch = "x86")]
let ic4_lib_dir = lib_root.join("bin").join("win32");
#[cfg(target_arch = "x86_64")]
let ic4_lib_dir = lib_root.join("bin").join("x64");
println!("cargo:rustc-link-search={}", ic4_lib_dir.to_string_lossy());
{
let lib_name = LIB_NAME;
println!(
"cargo:rerun-if-changed={}",
ic4_lib_dir
.join(format!("{}.lib", lib_name))
.to_string_lossy()
);
println!("cargo:rustc-link-lib={}", lib_name);
}
}
#[allow(unused)]
fn find_all_files(root: &Path) -> Result<Vec<PathBuf>, std::io::Error> {
let mut iter = vec![];
for child in root.read_dir()? {
let child_path = child?.path();
if child_path.is_file() {
iter.extend([child_path]);
} else if child_path.is_dir() {
iter.extend(find_all_files(child_path.as_path())?.into_iter());
}
}
Ok(iter)
}