Skip to content

Commit

Permalink
Add support use of installed OpenCASCADE
Browse files Browse the repository at this point in the history
This commit uses cmake to find installed OpenCASCADE libraries in system.
If it found it will be used if it version fits to requirements.
Otherwise the builtin one will be used.
The `builtin` feature may be enabled to force use builtin OpenCASCADE.
  • Loading branch information
DSchroer authored and katyo committed Jul 23, 2023
1 parent 159c0e0 commit e297b8f
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 29 deletions.
7 changes: 5 additions & 2 deletions crates/opencascade-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ repository = "https://github.com/bschwind/opencascade-rs"
cxx = "1"

[build-dependencies]
cmake = "0.1"
cxx-build = "1"
occt-sys = { path = "../occt-sys" }
cmake = "0.1"
occt-sys = { path = "../occt-sys", optional = true }

[features]
builtin = ["occt-sys"]
12 changes: 12 additions & 0 deletions crates/opencascade-sys/OCCT_PKG/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
project (OpenCASCADEPackageConfig)
find_package (OpenCASCADE REQUIRED)

file (WRITE ${CMAKE_BINARY_DIR}/occ_info.txt
"VERSION_MAJOR=${OpenCASCADE_MAJOR_VERSION}\n"
"VERSION_MINOR=${OpenCASCADE_MINOR_VERSION}\n"
"INCLUDE_DIR=${OpenCASCADE_INCLUDE_DIR}\n"
"LIBRARY_DIR=${OpenCASCADE_LIBRARY_DIR}\n"
"BUILD_SHARED_LIBS=${OpenCASCADE_BUILD_SHARED_LIBS}\n")

install (FILES ${CMAKE_BINARY_DIR}/occ_info.txt TYPE DATA)
126 changes: 99 additions & 27 deletions crates/opencascade-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@
use occt_sys::{occt_include_path, occt_lib_path};
const OCCT_VERSION: (u8, u8) = (7, 2);

const OCCT_LIBS: &[&str] = &[
"TKMath",
"TKernel",
"TKFeat",
"TKGeomBase",
"TKG2d",
"TKG3d",
"TKTopAlgo",
"TKGeomAlgo",
"TKGeomBase",
"TKBRep",
"TKPrim",
"TKSTEP",
"TKSTEPAttr",
"TKSTEPBase",
"TKSTEP209",
"TKSTL",
"TKMesh",
"TKShHealing",
"TKFillet",
"TKBool",
"TKBO",
"TKOffset",
"TKV3d",
"TKXSBase",
];

fn main() {
let target = std::env::var("TARGET").expect("No TARGET environment variable defined");
let is_windows = target.to_lowercase().contains("windows");
let is_windows_gnu = target.to_lowercase().contains("windows-gnu");

println!("cargo:rustc-link-search=native={}", occt_lib_path().to_str().unwrap());
println!("cargo:rustc-link-lib=static=TKMath");
println!("cargo:rustc-link-lib=static=TKernel");
println!("cargo:rustc-link-lib=static=TKFeat");
println!("cargo:rustc-link-lib=static=TKGeomBase");
println!("cargo:rustc-link-lib=static=TKG2d");
println!("cargo:rustc-link-lib=static=TKG3d");
println!("cargo:rustc-link-lib=static=TKTopAlgo");
println!("cargo:rustc-link-lib=static=TKGeomAlgo");
println!("cargo:rustc-link-lib=static=TKGeomBase");
println!("cargo:rustc-link-lib=static=TKBRep");
println!("cargo:rustc-link-lib=static=TKPrim");
println!("cargo:rustc-link-lib=static=TKSTEP");
println!("cargo:rustc-link-lib=static=TKSTEPAttr");
println!("cargo:rustc-link-lib=static=TKSTEPBase");
println!("cargo:rustc-link-lib=static=TKSTEP209");
println!("cargo:rustc-link-lib=static=TKSTL");
println!("cargo:rustc-link-lib=static=TKMesh");
println!("cargo:rustc-link-lib=static=TKShHealing");
println!("cargo:rustc-link-lib=static=TKFillet");
println!("cargo:rustc-link-lib=static=TKBool");
println!("cargo:rustc-link-lib=static=TKBO");
println!("cargo:rustc-link-lib=static=TKOffset");
println!("cargo:rustc-link-lib=static=TKV3d");
println!("cargo:rustc-link-lib=static=TKXSBase");
let occt_config = OcctConfig::default();

println!("cargo:rustc-link-search=native={}", occt_config.library_dir.to_str().unwrap());

let lib_type = if occt_config.is_dynamic { "dylib" } else { "static" };
for lib in OCCT_LIBS {
println!("cargo:rustc-link-lib={lib_type}={lib}");
}

if is_windows {
println!("cargo:rustc-link-lib=dylib=user32");
Expand All @@ -45,7 +55,7 @@ fn main() {
.cpp(true)
.flag_if_supported("-std=c++11")
.define("_USE_MATH_DEFINES", "TRUE")
.include(occt_include_path())
.include(occt_config.include_dir)
.include("include")
.compile("wrapper");

Expand All @@ -54,3 +64,65 @@ fn main() {
println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=include/wrapper.hxx");
}

struct OcctConfig {
include_dir: std::path::PathBuf,
library_dir: std::path::PathBuf,
is_dynamic: bool,
}

impl Default for OcctConfig {
#[cfg(feature = "builtin")]
fn default() -> Self {
let include_dir = occt_sys::occt_include_path();
let library_dir = occt_sys::occt_lib_path();

Self { include_dir, library_dir, is_dynamic: false }
}

#[cfg(not(feature = "builtin"))]
fn default() -> Self {
let dst = std::panic::catch_unwind(|| cmake::Config::new("OCCT_PKG").build())
.expect("Pre-installed OpenCASCADE library not found! You can use `builtin` feature if you do not want install OCCT libraries system-wide.");
let cfg = std::fs::read_to_string(dst.join("share").join("occ_info.txt"))
.expect("Something went wrong when detecting pre-installed OpenCASCADE library!");

let mut version_major: Option<u8> = None;
let mut version_minor: Option<u8> = None;
let mut include_dir: Option<std::path::PathBuf> = None;
let mut library_dir: Option<std::path::PathBuf> = None;
let mut is_dynamic: bool = false;

for line in cfg.lines() {
if let Some((var, val)) = line.split_once("=") {
match var {
"VERSION_MAJOR" => version_major = val.parse().ok(),
"VERSION_MINOR" => version_minor = val.parse().ok(),
"INCLUDE_DIR" => include_dir = val.parse().ok(),
"LIBRARY_DIR" => library_dir = val.parse().ok(),
"BUILD_SHARED_LIBS" => is_dynamic = val == "ON",
_ => (),
}
}
}

if let (Some(version_major), Some(version_minor), Some(include_dir), Some(library_dir)) =
(version_major, version_minor, include_dir, library_dir)
{
if version_major != OCCT_VERSION.0 {
panic!("Pre-installed OpenCASCADE library found but major version is not the same (found {}.x but {}.x required)! Please provide required version or use `builtin` feature.", version_major, OCCT_VERSION.0);
}

if version_minor < OCCT_VERSION.1 {
panic!(
"Pre-installed OpenCASCADE library found but minor version is lower than required ({}.{} < {}.{})! Please provide required version or use `builtin` feature.",
version_major, version_minor, OCCT_VERSION.0, OCCT_VERSION.1
);
}

Self { include_dir, library_dir, is_dynamic }
} else {
panic!("Pre-installed OpenCASCADE library found but something went wrong!");
}
}
}
3 changes: 3 additions & 0 deletions crates/opencascade/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ cxx = "1"
opencascade-sys = { version = "0.1", path = "../opencascade-sys" }
glam = { version = "0.23", features = ["bytemuck"] }
thiserror = "1"

[features]
builtin = ["opencascade-sys/builtin"]

0 comments on commit e297b8f

Please sign in to comment.