Files
IfcOpenShell/cmake/FindOpenCASCADE.cmake
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

227 lines
8.6 KiB
CMake
Raw Normal View History

#
# Input variables:
# - `OCC_INCLUDE_DIR`
# - `OCC_LIBRARY_DIR`
# If input variables are not specified, try to find OpenCASCADE config.
# Input variables could also be provided as environment variables.
#
# Output variables
# - `OpenCASCADE_LIBRARIES`
#
UNIFY_ENVVARS_AND_CACHE(OCC_INCLUDE_DIR)
UNIFY_ENVVARS_AND_CACHE(OCC_LIBRARY_DIR)
if(OCC_INCLUDE_DIR)
set(OCC_INCLUDE_DIR ${OCC_INCLUDE_DIR} CACHE FILEPATH "Open CASCADE header files")
message(STATUS "Looking for Open CASCADE include files in: ${OCC_INCLUDE_DIR}")
endif()
if(OCC_LIBRARY_DIR)
set(OCC_LIBRARY_DIR ${OCC_LIBRARY_DIR} CACHE FILEPATH "Open CASCADE library files")
message(STATUS "Looking for Open CASCADE library files in: ${OCC_LIBRARY_DIR}")
endif()
if(NOT OCC_INCLUDE_DIR AND NOT OCC_LIBRARY_DIR)
# OCE is not supported for find_package, because it's using a different name (`oce`)
# and also has an odd directory structure (install/lib/oce-0.18/*.cmake).
# find_package creates variables:
# - `OpenCASCADE_INCLUDE_DIR`
# - `OpenCASCADE_LIBRARIES`
2025-11-26 22:53:38 +00:00
# OpenCASCADE may be built with VTK support. Try to find VTK first to avoid
# CMake errors when OpenCASCADE's config references VTK targets.
find_package(VTK QUIET)
mark_as_advanced(VTK_DIR)
2025-11-26 22:53:38 +00:00
find_package(OpenCASCADE CONFIG REQUIRED)
mark_as_advanced(OpenCASCADE_DIR)
2025-11-24 12:08:53 +05:00
message(STATUS "Found OpenCASCADE config: ${OpenCASCADE_DIR}")
if(OpenCASCADE_VERSION VERSION_LESS "7.7.0")
# cmake configs < 7.7.0 were not adding include directories to targets automatically.
2025-12-20 13:27:35 +05:00
set_target_properties(TKernel PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OpenCASCADE_INCLUDE_DIR}")
endif()
if(
OpenCASCADE_VERSION VERSION_LESS "7.9.0"
AND CMAKE_VERSION GREATER_EQUAL "3.24"
AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
)
# Before 7.9.0 targets in OCCT cmake configs are not linked to each other
# leading to missing symbols on Unix. Link them as a single group as a workaround.
# Only needed for gcc, because other compilers (e.g. Apple Clang, MSVC) do rescan automatically.
set(OpenCASCADE_LIBRARIES "$<LINK_GROUP:RESCAN,${OpenCASCADE_LIBRARIES}>")
endif()
if(UNIX AND NOT APPLE)
# Record only the OCCT modules whose symbols are actually referenced.
#
# OpenCASCADE_LIBRARIES is OCCT's *complete* module list, Visualization
# included -- TKV3d, TKOpenGl, TKService. Against a static OCCT that
# costs nothing, because an unreferenced module contributes no objects.
# Against a shared OCCT every entry becomes a hard DT_NEEDED, and
# libTKV3d pulls libGL.so.1 + libEGL.so.1, so `import ifcopenshell`
# dies on any headless machine with
# ImportError: libEGL.so.1: cannot open shared object file
# even though IfcOpenShell never opens a window. Measured on a full
# 67-module link: 67 DT_NEEDED entries without the flag, 3 with it,
# and TKV3d/TKOpenGl gone in the second case.
#
# Goes before the LINK_GROUP above rather than inside it, and is a
# no-op for a static OCCT (--as-needed only governs shared libraries),
# so this is safe for both link types.
#
# Deliberately NOT closed with -Wl,--no-as-needed. CMake emits the
# imported targets' INTERFACE_LINK_LIBRARIES -- which is where OCCT
# lists libGL/libEGL -- *after* this item, so a closing bracket
# switches the flag back off just before the libraries it was added to
# exclude. Measured: with the bracket closed the plug-ins dropped from
# 47 DT_NEEDED libTK entries to 14 and lost TKV3d, yet still carried a
# direct libEGL.so.1 and failed to import on a headless server; with it
# left open the same 14 remain and libGL/libEGL are gone.
#
# The cost is that --as-needed stays in effect for whatever follows on
# the link line. That is the default on Debian/Ubuntu so it is
# well-trodden, but it does mean a library needed only for
# static-initialiser side effects could be dropped -- the thing to
# suspect first if a serialiser stops registering itself.
set(OpenCASCADE_LIBRARIES "-Wl,--as-needed" "${OpenCASCADE_LIBRARIES}")
endif()
if(OpenCASCADE_VERSION VERSION_LESS "7.9.0" AND WIN32)
# Bug in OCCT cmake configs < 7.9.0 - missing linked library.
list(APPEND OpenCASCADE_LIBRARIES WSOCK32.lib)
endif()
return()
endif()
# No specific paths specified, try to find package.
if(OCC_INCLUDE_DIR AND OCC_LIBRARY_DIR)
message(
STATUS
"Using provided OCC_INCLUDE_DIR ('${OCC_INCLUDE_DIR}') "
"and OCC_LIBRARY_DIR ('${OCC_LIBRARY_DIR}')."
)
# Parse OCC_VERSION_STRING.
2025-12-20 13:27:35 +05:00
file(STRINGS ${OCC_INCLUDE_DIR}/Standard_Version.hxx OCC_MAJOR REGEX "#define OCC_VERSION_MAJOR.*")
string(REGEX MATCH "[0-9]+" OCC_MAJOR ${OCC_MAJOR})
2025-12-20 13:27:35 +05:00
file(STRINGS ${OCC_INCLUDE_DIR}/Standard_Version.hxx OCC_MINOR REGEX "#define OCC_VERSION_MINOR.*")
string(REGEX MATCH "[0-9]+" OCC_MINOR ${OCC_MINOR})
2025-12-20 13:27:35 +05:00
file(STRINGS ${OCC_INCLUDE_DIR}/Standard_Version.hxx OCC_MAINT REGEX "#define OCC_VERSION_MAINTENANCE.*")
string(REGEX MATCH "[0-9]+" OCC_MAINT ${OCC_MAINT})
set(OCC_VERSION_STRING "${OCC_MAJOR}.${OCC_MINOR}.${OCC_MAINT}")
else()
message(
FATAL_ERROR
"Couldn't find Open CASCADE installation. "
"Either both OCC_INCLUDE_DIR ('${OCC_INCLUDE_DIR}') and OCC_LIBRARY_DIR ('${OCC_LIBRARY_DIR}') "
"must be specified or OpenCASCADE package should be discoverable. "
"If you're using OCE, then providing a package is not available "
"and you need to provide OCE_INCLUDE_DIR and OCE_LIBRARY_DIR directly."
)
endif()
2025-12-20 13:27:35 +05:00
set(OpenCASCADE_LIBRARIES
TKernel
TKMath
TKBRep
TKGeomBase
TKGeomAlgo
TKG3d
TKG2d
TKShHealing
TKTopAlgo
TKMesh
TKPrim
TKBool
TKBO
TKFillet
TKXSBase
TKOffset
TKHLR
# @todo investigate the exact conditions when this is necessary
TKBin
)
if(OCC_VERSION_STRING VERSION_LESS 7.8.0)
2025-12-20 13:27:35 +05:00
list(
APPEND OpenCASCADE_LIBRARIES
TKIGES
TKSTEPBase
TKSTEPAttr
TKSTEP209
TKSTEP
)
else(OCC_VERSION_STRING VERSION_LESS 7.8.0)
list(APPEND OpenCASCADE_LIBRARIES TKDESTEP TKDEIGES)
endif(OCC_VERSION_STRING VERSION_LESS 7.8.0)
find_library(libTKernel NAMES TKernel TKerneld PATHS ${OCC_LIBRARY_DIR} NO_DEFAULT_PATH)
if(libTKernel)
message(STATUS "Required Open Cascade Library files found")
else()
2025-12-20 13:27:35 +05:00
message(FATAL_ERROR "Unable to find Open Cascade library files in OCC_LIBRARY_DIR ('${OCC_LIBRARY_DIR}'), aborting")
endif()
if(MSVC)
add_definitions(-DHAVE_NO_DLL)
add_debug_variants(OpenCASCADE_LIBRARIES "${OpenCASCADE_LIBRARIES}" d)
endif()
if(WIN32)
# OCC might require linking to Winsock depending on the version and build configuration
list(APPEND OpenCASCADE_LIBRARIES ws2_32.lib)
endif()
# Make sure cross-referenced symbols between static OCC libraries get
# resolved. Also add thread and rt libraries.
get_filename_component(libTKernelExt ${libTKernel} EXT)
if("${libTKernelExt}" STREQUAL ".a")
set(OCCT_STATIC ON)
endif()
if(OCCT_STATIC)
find_package(Threads)
if(WASM_BUILD)
set(OpenCASCADE_LIBRARIES ${OpenCASCADE_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
else()
# OpenCASCADE_LIBRARIES repeated N times below in order to fix cyclic dependencies
# tfk: --start-group ... --end-group didn't work on the apple linker when last tested
if(APPLE)
2025-12-20 13:27:35 +05:00
set(OpenCASCADE_LIBRARIES
${OpenCASCADE_LIBRARIES}
${OpenCASCADE_LIBRARIES}
${OpenCASCADE_LIBRARIES}
${OpenCASCADE_LIBRARIES}
${OpenCASCADE_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
else()
2025-12-20 13:27:35 +05:00
set(OpenCASCADE_LIBRARIES
-Wl,--start-group
${OpenCASCADE_LIBRARIES}
-Wl,--end-group
${CMAKE_THREAD_LIBS_INIT}
)
endif()
endif()
if(NOT APPLE AND NOT WIN32)
set(OpenCASCADE_LIBRARIES ${OpenCASCADE_LIBRARIES} "rt")
endif()
if(NOT WIN32)
set(OpenCASCADE_LIBRARIES ${OpenCASCADE_LIBRARIES} "dl")
endif()
endif()
add_library(OpenCASCADE_INTERFACE INTERFACE)
target_include_directories(OpenCASCADE_INTERFACE INTERFACE "${OCC_INCLUDE_DIR}")
target_link_libraries(OpenCASCADE_INTERFACE INTERFACE ${OpenCASCADE_LIBRARIES})
target_link_directories(OpenCASCADE_INTERFACE INTERFACE "${OCC_LIBRARY_DIR}")
set(OpenCASCADE_LIBRARIES OpenCASCADE_INTERFACE)
2025-12-20 13:27:35 +05:00
install(TARGETS OpenCASCADE_INTERFACE EXPORT ${IFCOPENSHELL_EXPORT_TARGETS})