extern crate bindgen;
use std::env;
use std::fs;
use std::path::PathBuf;
#[cfg(windows)]
use vcpkg;
#[cfg(windows)]
fn find_tesseract_system_lib() -> Vec<String> {
println!("cargo:rerun-if-env-changed=TESSERACT_INCLUDE_PATHS");
println!("cargo:rerun-if-env-changed=TESSERACT_LINK_PATHS");
println!("cargo:rerun-if-env-changed=TESSERACT_LINK_LIBS");
let vcpkg = || {
let lib = vcpkg::Config::new().find_package("tesseract").unwrap();
vec![lib
.include_paths
.iter()
.map(|x| x.to_string_lossy())
.collect::<String>()]
};
let include_paths = env::var("TESSERACT_INCLUDE_PATHS").ok();
let include_paths = include_paths.as_deref().map(|x| x.split(','));
let link_paths = env::var("TESSERACT_LINK_PATHS").ok();
let link_paths = link_paths.as_deref().map(|x| x.split(','));
let link_libs = env::var("TESSERACT_LINK_LIBS").ok();
let link_libs = link_libs.as_deref().map(|x| x.split(','));
if let (Some(include_paths), Some(link_paths), Some(link_libs)) =
(include_paths, link_paths, link_libs)
{
for link_path in link_paths {
println!("cargo:rustc-link-search={}", link_path)
}
for link_lib in link_libs {
println!("cargo:rustc-link-lib={}", link_lib)
}
include_paths.map(|x| x.to_string()).collect::<Vec<_>>()
} else {
vcpkg()
}
}
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "freebsd"))]
fn find_tesseract_system_lib() -> Vec<String> {
let pk = pkg_config::Config::new()
.atleast_version("4.1")
.probe("tesseract")
.unwrap();
println!("cargo:rustc-link-search=native={:?}", pk.link_paths[0]);
println!("cargo:rustc-link-lib=tesseract");
let mut include_paths = pk.include_paths.clone();
include_paths
.iter_mut()
.map(|x| {
if !x.ends_with("include") {
x.pop();
}
x
})
.map(|x| x.to_string_lossy())
.map(|x| x.to_string())
.collect::<Vec<String>>()
}
#[cfg(all(
not(windows),
not(target_os = "macos"),
not(target_os = "linux"),
not(target_os = "freebsd")
))]
fn find_tesseract_system_lib() -> Vec<String> {
println!("cargo:rustc-link-lib=tesseract");
vec![]
}
fn capi_bindings(clang_extra_include: &[String]) -> bindgen::Bindings {
let mut capi_bindings = bindgen::Builder::default()
.header("wrapper_capi.h")
.allowlist_function("^Tess.*")
.blocklist_type("Boxa")
.blocklist_type("Pix")
.blocklist_type("Pixa")
.blocklist_type("_IO_FILE")
.blocklist_type("_IO_codecvt")
.blocklist_type("_IO_marker")
.blocklist_type("_IO_wide_data");
for inc in clang_extra_include {
capi_bindings = capi_bindings.clang_arg(format!("-I{}", *inc));
}
capi_bindings
.generate()
.expect("Unable to generate capi bindings")
}
#[cfg(not(target_os = "macos"))]
fn public_types_bindings(clang_extra_include: &[String]) -> String {
let mut public_types_bindings = bindgen::Builder::default()
.header("wrapper_public_types.hpp")
.rustified_enum("tesseract::OcrEngineMode")
.rustified_enum("tesseract::Orientation")
.rustified_enum("tesseract::PageIteratorLevel")
.rustified_enum("tesseract::PageSegMode")
.rustified_enum("tesseract::ParagraphJustification")
.rustified_enum("tesseract::PolyBlockType")
.rustified_enum("tesseract::TextlineOrder")
.rustified_enum("tesseract::WritingDirection")
.blocklist_item("^kPolyBlockNames")
.blocklist_item("^tesseract::kPolyBlockNames");
for inc in clang_extra_include {
public_types_bindings = public_types_bindings.clang_arg(format!("-I{}", *inc));
}
public_types_bindings
.generate()
.expect("Unable to generate public types bindings")
.to_string()
.replace("tesseract_", "")
}
#[cfg(target_os = "macos")]
fn public_types_bindings(_clang_extra_include: &[String]) -> &'static str {
include_str!("src/public_types_bindings_mac.rs")
}
fn main() {
#[cfg(target_os = "windows")]
println!("cargo:rustc-link-lib=User32");
#[cfg(target_os = "windows")]
println!("cargo:rustc-link-lib=Crypt32");
#[cfg(target_os = "windows")]
println!("cargo:rustc-link-lib=Advapi32");
let clang_extra_include = find_tesseract_system_lib();
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
capi_bindings(&clang_extra_include)
.write_to_file(out_path.join("capi_bindings.rs"))
.expect("Couldn't write capi bindings!");
fs::write(
out_path.join("public_types_bindings.rs"),
public_types_bindings(&clang_extra_include),
)
.expect("Couldn't write public types bindings!");
}