1# Copyright Contributors to the OpenVDB Project 2# SPDX-License-Identifier: MPL-2.0 3# 4#[=======================================================================[.rst: 5 6FindOpenEXR 7----------- 8 9Find OpenEXR include dirs and libraries 10 11Use this module by invoking find_package with the form:: 12 13 find_package(OpenEXR 14 [version] [EXACT] # Minimum or EXACT version 15 [REQUIRED] # Fail with error if OpenEXR is not found 16 [COMPONENTS <libs>...] # OpenEXR libraries by their canonical name 17 # e.g. "IlmImf" for "libIlmImf" 18 ) 19 20IMPORTED Targets 21^^^^^^^^^^^^^^^^ 22 23``OpenEXR::IlmImf`` 24 The IlmImf library target. 25``OpenEXR::IlmImfUtil`` 26 The IlmImfUtil library target. 27 28Result Variables 29^^^^^^^^^^^^^^^^ 30 31This will define the following variables: 32 33``OpenEXR_FOUND`` 34 True if the system has the OpenEXR library. 35``OpenEXR_VERSION`` 36 The version of the OpenEXR library which was found. 37``OpenEXR_INCLUDE_DIRS`` 38 Include directories needed to use OpenEXR. 39``OpenEXR_RELEASE_LIBRARIES`` 40 Libraries needed to link to the release version of OpenEXR. 41``OpenEXR_RELEASE_LIBRARY_DIRS`` 42 OpenEXR release library directories. 43``OpenEXR_DEBUG_LIBRARIES`` 44 Libraries needed to link to the debug version of OpenEXR. 45``OpenEXR_DEBUG_LIBRARY_DIRS`` 46 OpenEXR debug library directories. 47``OpenEXR_DEFINITIONS`` 48 Definitions to use when compiling code that uses OpenEXR. 49``OpenEXR_{COMPONENT}_FOUND`` 50 True if the system has the named OpenEXR component. 51 52Deprecated - use [RELEASE|DEBUG] variants: 53 54``OpenEXR_LIBRARIES`` 55 Libraries needed to link to OpenEXR. 56``OpenEXR_LIBRARY_DIRS`` 57 OpenEXR library directories. 58 59Cache Variables 60^^^^^^^^^^^^^^^ 61 62The following cache variables may also be set: 63 64``OpenEXR_INCLUDE_DIR`` 65 The directory containing ``OpenEXR/config-auto.h``. 66``OpenEXR_{COMPONENT}_LIBRARY`` 67 Individual component libraries for OpenEXR. may include target_link_libraries() debug/optimized keywords. 68``OpenEXR_{COMPONENT}_LIBRARY_RELEASE`` 69 Individual component libraries for OpenEXR release 70``OpenEXR_{COMPONENT}_LIBRARY_DEBUG`` 71 Individual component libraries for OpenEXR debug 72 73Hints 74^^^^^ 75 76Instead of explicitly setting the cache variables, the following variables 77may be provided to tell this module where to look. 78 79``OpenEXR_ROOT`` 80 Preferred installation prefix. 81``OPENEXR_INCLUDEDIR`` 82 Preferred include directory e.g. <prefix>/include 83``OPENEXR_LIBRARYDIR`` 84 Preferred library directory e.g. <prefix>/lib 85``OPENEXR_DEBUG_SUFFIX`` 86 Suffix of the debug version of openexr libs. Defaults to "_d". 87``SYSTEM_LIBRARY_PATHS`` 88 Global list of library paths intended to be searched by and find_xxx call 89``OPENEXR_USE_STATIC_LIBS`` 90 Only search for static openexr libraries 91``DISABLE_CMAKE_SEARCH_PATHS`` 92 Disable CMakes default search paths for find_xxx calls in this module 93 94#]=======================================================================] 95 96cmake_minimum_required(VERSION 3.15) 97include(GNUInstallDirs) 98 99 100mark_as_advanced( 101 OpenEXR_INCLUDE_DIR 102 OpenEXR_LIBRARY 103) 104 105set(_FIND_OPENEXR_ADDITIONAL_OPTIONS "") 106if(DISABLE_CMAKE_SEARCH_PATHS) 107 set(_FIND_OPENEXR_ADDITIONAL_OPTIONS NO_DEFAULT_PATH) 108endif() 109 110 111# Set _OPENEXR_ROOT based on a user provided root var. Xxx_ROOT and ENV{Xxx_ROOT} 112# are prioritised over the legacy capitalized XXX_ROOT variables for matching 113# CMake 3.12 behaviour 114# @todo deprecate -D and ENV OPENEXR_ROOT from CMake 3.12 115if(OpenEXR_ROOT) 116 set(_OPENEXR_ROOT ${OpenEXR_ROOT}) 117elseif(DEFINED ENV{OpenEXR_ROOT}) 118 set(_OPENEXR_ROOT $ENV{OpenEXR_ROOT}) 119elseif(OPENEXR_ROOT) 120 set(_OPENEXR_ROOT ${OPENEXR_ROOT}) 121elseif(DEFINED ENV{OPENEXR_ROOT}) 122 set(_OPENEXR_ROOT $ENV{OPENEXR_ROOT}) 123endif() 124 125# Additionally try and use pkconfig to find OpenEXR 126if(USE_PKGCONFIG) 127 if(NOT DEFINED PKG_CONFIG_FOUND) 128 find_package(PkgConfig) 129 endif() 130 pkg_check_modules(PC_OpenEXR QUIET OpenEXR) 131endif() 132 133# ------------------------------------------------------------------------ 134# Search for OpenEXR include DIR 135# ------------------------------------------------------------------------ 136 137set(_OPENEXR_INCLUDE_SEARCH_DIRS "") 138list(APPEND _OPENEXR_INCLUDE_SEARCH_DIRS 139 ${OPENEXR_INCLUDEDIR} 140 ${_OPENEXR_ROOT} 141 ${PC_OpenEXR_INCLUDEDIR} 142 ${SYSTEM_LIBRARY_PATHS} 143) 144 145# Look for a standard OpenEXR header file. 146find_path(OpenEXR_INCLUDE_DIR OpenEXRConfig.h 147 ${_FIND_OPENEXR_ADDITIONAL_OPTIONS} 148 PATHS ${_OPENEXR_INCLUDE_SEARCH_DIRS} 149 PATH_SUFFIXES ${CMAKE_INSTALL_INCLUDEDIR}/OpenEXR include/OpenEXR OpenEXR 150) 151 152if(EXISTS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h") 153 # Get the EXR version information from the config header 154 file(STRINGS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h" 155 _openexr_version_major_string REGEX "#define OPENEXR_VERSION_MAJOR " 156 ) 157 string(REGEX REPLACE "#define OPENEXR_VERSION_MAJOR" "" 158 _openexr_version_major_string "${_openexr_version_major_string}" 159 ) 160 string(STRIP "${_openexr_version_major_string}" OpenEXR_VERSION_MAJOR) 161 162 file(STRINGS "${OpenEXR_INCLUDE_DIR}/OpenEXRConfig.h" 163 _openexr_version_minor_string REGEX "#define OPENEXR_VERSION_MINOR " 164 ) 165 string(REGEX REPLACE "#define OPENEXR_VERSION_MINOR" "" 166 _openexr_version_minor_string "${_openexr_version_minor_string}" 167 ) 168 string(STRIP "${_openexr_version_minor_string}" OpenEXR_VERSION_MINOR) 169 170 unset(_openexr_version_major_string) 171 unset(_openexr_version_minor_string) 172 173 set(OpenEXR_VERSION ${OpenEXR_VERSION_MAJOR}.${OpenEXR_VERSION_MINOR}) 174endif() 175 176if(${OpenEXR_VERSION} VERSION_GREATER_EQUAL 3.0) 177 set(_OPENEXR_COMPONENT_LIST OpenEXR OpenEXRUtil Iex IlmThread) 178else() 179 set(_OPENEXR_COMPONENT_LIST IlmImf IlmImfUtil) 180endif() 181 182if(OpenEXR_FIND_COMPONENTS) 183 set(OPENEXR_COMPONENTS_PROVIDED TRUE) 184 set(_IGNORED_COMPONENTS "") 185 foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS}) 186 if(NOT ${COMPONENT} IN_LIST _OPENEXR_COMPONENT_LIST) 187 list(APPEND _IGNORED_COMPONENTS ${COMPONENT}) 188 endif() 189 endforeach() 190 191 if(_IGNORED_COMPONENTS) 192 message(STATUS "Ignoring unknown components of OpenEXR:") 193 foreach(COMPONENT ${_IGNORED_COMPONENTS}) 194 message(STATUS " ${COMPONENT}") 195 endforeach() 196 list(REMOVE_ITEM OpenEXR_FIND_COMPONENTS ${_IGNORED_COMPONENTS}) 197 endif() 198else() 199 set(OPENEXR_COMPONENTS_PROVIDED FALSE) 200 set(OpenEXR_FIND_COMPONENTS ${_OPENEXR_COMPONENT_LIST}) 201endif() 202 203 204# ------------------------------------------------------------------------ 205# Search for OPENEXR lib DIR 206# ------------------------------------------------------------------------ 207 208if(NOT DEFINED OPENEXR_DEBUG_SUFFIX) 209 set(OPENEXR_DEBUG_SUFFIX _d) 210endif() 211 212set(_OPENEXR_LIBRARYDIR_SEARCH_DIRS "") 213 214# Append to _OPENEXR_LIBRARYDIR_SEARCH_DIRS in priority order 215 216list(APPEND _OPENEXR_LIBRARYDIR_SEARCH_DIRS 217 ${OPENEXR_LIBRARYDIR} 218 ${_OPENEXR_ROOT} 219 ${PC_OpenEXR_LIBDIR} 220 ${SYSTEM_LIBRARY_PATHS} 221) 222 223set(OpenEXR_LIB_COMPONENTS "") 224list(APPEND OPENEXR_BUILD_TYPES RELEASE DEBUG) 225 226foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS}) 227 foreach(BUILD_TYPE ${OPENEXR_BUILD_TYPES}) 228 229 set(_TMP_SUFFIX "") 230 if(BUILD_TYPE STREQUAL DEBUG) 231 set(_TMP_SUFFIX ${OPENEXR_DEBUG_SUFFIX}) 232 endif() 233 234 set(_OpenEXR_Version_Suffix "-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}") 235 set(_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) 236 237 if(WIN32) 238 if(OPENEXR_USE_STATIC_LIBS) 239 set(CMAKE_FIND_LIBRARY_SUFFIXES "${_TMP_SUFFIX}.lib") 240 endif() 241 list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.lib") 242 else() 243 if(OPENEXR_USE_STATIC_LIBS) 244 set(CMAKE_FIND_LIBRARY_SUFFIXES "${_TMP_SUFFIX}.a") 245 else() 246 if(APPLE) 247 list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.dylib") 248 else() 249 list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.so") 250 endif() 251 endif() 252 list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}${_TMP_SUFFIX}.a") 253 endif() 254 255 # Find the lib 256 find_library(OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE} ${COMPONENT} 257 ${_FIND_OPENEXR_ADDITIONAL_OPTIONS} 258 PATHS ${_OPENEXR_LIBRARYDIR_SEARCH_DIRS} 259 PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib 260 ) 261 262 if(EXISTS ${OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE}}) 263 list(APPEND OpenEXR_LIB_COMPONENTS ${OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE}}) 264 list(APPEND OpenEXR_LIB_COMPONENTS_${BUILD_TYPE} ${OpenEXR_${COMPONENT}_LIBRARY_${BUILD_TYPE}}) 265 endif() 266 267 # Reset library suffix 268 set(CMAKE_FIND_LIBRARY_SUFFIXES ${_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) 269 unset(_OPENEXR_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) 270 unset(_OpenEXR_Version_Suffix) 271 unset(_TMP_SUFFIX) 272 endforeach() 273 274 if(OpenEXR_${COMPONENT}_LIBRARY_DEBUG AND OpenEXR_${COMPONENT}_LIBRARY_RELEASE) 275 # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for 276 # single-config generators, set optimized and debug libraries 277 get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 278 if(_isMultiConfig OR CMAKE_BUILD_TYPE) 279 set(OpenEXR_${COMPONENT}_LIBRARY optimized ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} debug ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}) 280 else() 281 # For single-config generators where CMAKE_BUILD_TYPE has no value, 282 # just use the release libraries 283 set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}) 284 endif() 285 # FIXME: This probably should be set for both cases 286 set(OpenEXR_${COMPONENT}_LIBRARIES optimized ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} debug ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}) 287 endif() 288 289 # if only the release version was found, set the debug variable also to the release version 290 if(OpenEXR_${COMPONENT}_LIBRARY_RELEASE AND NOT OpenEXR_${COMPONENT}_LIBRARY_DEBUG) 291 set(OpenEXR_${COMPONENT}_LIBRARY_DEBUG ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}) 292 set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}) 293 set(OpenEXR_${COMPONENT}_LIBRARIES ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}) 294 endif() 295 296 # if only the debug version was found, set the release variable also to the debug version 297 if(OpenEXR_${COMPONENT}_LIBRARY_DEBUG AND NOT OpenEXR_${COMPONENT}_LIBRARY_RELEASE) 298 set(OpenEXR_${COMPONENT}_LIBRARY_RELEASE ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}) 299 set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}) 300 set(OpenEXR_${COMPONENT}_LIBRARIES ${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}) 301 endif() 302 303 # If the debug & release library ends up being the same, omit the keywords 304 if("${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}" STREQUAL "${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}") 305 set(OpenEXR_${COMPONENT}_LIBRARY ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} ) 306 set(OpenEXR_${COMPONENT}_LIBRARIES ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} ) 307 endif() 308 309 if(OpenEXR_${COMPONENT}_LIBRARY) 310 set(OpenEXR_${COMPONENT}_FOUND TRUE) 311 else() 312 set(OpenEXR_${COMPONENT}_FOUND FALSE) 313 endif() 314endforeach() 315 316# ------------------------------------------------------------------------ 317# Cache and set OPENEXR_FOUND 318# ------------------------------------------------------------------------ 319 320include(FindPackageHandleStandardArgs) 321find_package_handle_standard_args(OpenEXR 322 FOUND_VAR OpenEXR_FOUND 323 REQUIRED_VARS 324 OpenEXR_INCLUDE_DIR 325 OpenEXR_LIB_COMPONENTS 326 VERSION_VAR OpenEXR_VERSION 327 HANDLE_COMPONENTS 328) 329 330if(NOT OpenEXR_FOUND) 331 if(OpenEXR_FIND_REQUIRED) 332 message(FATAL_ERROR "Unable to find OpenEXR") 333 endif() 334 return() 335endif() 336 337# Partition release/debug lib vars 338 339set(OpenEXR_RELEASE_LIBRARIES "") 340set(OpenEXR_RELEASE_LIBRARY_DIRS "") 341set(OpenEXR_DEBUG_LIBRARIES "") 342set(OpenEXR_DEBUG_LIBRARY_DIRS "") 343foreach(LIB ${OpenEXR_LIB_COMPONENTS_RELEASE}) 344 get_filename_component(_EXR_LIBDIR ${LIB} DIRECTORY) 345 list(APPEND OpenEXR_RELEASE_LIBRARIES ${LIB}) 346 list(APPEND OpenEXR_RELEASE_LIBRARY_DIRS ${_EXR_LIBDIR}) 347endforeach() 348 349foreach(LIB ${OpenEXR_LIB_COMPONENTS_DEBUG}) 350 get_filename_component(_EXR_LIBDIR ${LIB} DIRECTORY) 351 list(APPEND OpenEXR_DEBUG_LIBRARIES ${LIB}) 352 list(APPEND OpenEXR_DEBUG_LIBRARY_DIRS ${_EXR_LIBDIR}) 353endforeach() 354 355list(REMOVE_DUPLICATES OpenEXR_RELEASE_LIBRARY_DIRS) 356list(REMOVE_DUPLICATES OpenEXR_DEBUG_LIBRARY_DIRS) 357 358set(OpenEXR_LIBRARIES ${OpenEXR_RELEASE_LIBRARIES}) 359set(OpenEXR_LIBRARY_DIRS ${OpenEXR_RELEASE_LIBRARY_DIRS}) 360 361# We have to add both include and include/OpenEXR to the include 362# path in case OpenEXR and IlmBase are installed separately. 363# 364# Make sure we get the absolute path to avoid issues where 365# /usr/include/OpenEXR/../ is picked up and passed to gcc from cmake 366# which won't correctly compute /usr/include as an implicit system 367# dir if the path is relative: 368# 369# https://github.com/AcademySoftwareFoundation/openvdb/issues/632 370# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129 371 372set(_OpenEXR_Parent_Dir "") 373get_filename_component(_OpenEXR_Parent_Dir 374 ${OpenEXR_INCLUDE_DIR}/../ ABSOLUTE) 375 376set(OpenEXR_INCLUDE_DIRS) 377list(APPEND OpenEXR_INCLUDE_DIRS 378 ${_OpenEXR_Parent_Dir} 379 ${OpenEXR_INCLUDE_DIR} 380) 381unset(_OpenEXR_Parent_Dir) 382 383# Configure imported target 384 385foreach(COMPONENT ${OpenEXR_FIND_COMPONENTS}) 386 # Configure lib type. If XXX_USE_STATIC_LIBS, we always assume a static 387 # lib is in use. If win32, we can't mark the import .libs as shared, so 388 # these are always marked as UNKNOWN. Otherwise, infer from extension. 389 set(OpenEXR_${COMPONENT}_LIB_TYPE UNKNOWN) 390 if(OPENEXR_USE_STATIC_LIBS) 391 set(OpenEXR_${COMPONENT}_LIB_TYPE STATIC) 392 elseif(UNIX) 393 get_filename_component(_OpenEXR_${COMPONENT}_EXT ${OpenEXR_${COMPONENT}_LIBRARY_RELEASE} EXT) 394 if(${_OpenEXR_${COMPONENT}_EXT} STREQUAL ".a") 395 set(OpenEXR_${COMPONENT}_LIB_TYPE STATIC) 396 elseif(${_OpenEXR_${COMPONENT}_EXT} STREQUAL ".so" OR 397 ${_OpenEXR_${COMPONENT}_EXT} STREQUAL ".dylib") 398 set(OpenEXR_${COMPONENT}_LIB_TYPE SHARED) 399 endif() 400 endif() 401 402 set(OpenEXR_${COMPONENT}_DEFINITIONS) 403 404 # Add the OPENEXR_DLL define if the library is not static on WIN32 405 if(WIN32) 406 if(NOT OpenEXR_${COMPONENT}_LIB_TYPE STREQUAL STATIC) 407 list(APPEND OpenEXR_${COMPONENT}_DEFINITIONS OPENEXR_DLL) 408 endif() 409 endif() 410 411 if(NOT TARGET OpenEXR::${COMPONENT}) 412 add_library(OpenEXR::${COMPONENT} ${OpenEXR_${COMPONENT}_LIB_TYPE} IMPORTED) 413 set_target_properties(OpenEXR::${COMPONENT} PROPERTIES 414 INTERFACE_COMPILE_OPTIONS "${PC_OpenEXR_CFLAGS_OTHER}" 415 INTERFACE_COMPILE_DEFINITIONS "${OpenEXR_${COMPONENT}_DEFINITIONS}" 416 INTERFACE_INCLUDE_DIRECTORIES "${OpenEXR_INCLUDE_DIRS}") 417 418 # Standard location 419 set_target_properties(OpenEXR::${COMPONENT} PROPERTIES 420 IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" 421 IMPORTED_LOCATION "${OpenEXR_${COMPONENT}_LIBRARY}") 422 423 # Release location 424 if(EXISTS "${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}") 425 set_property(TARGET OpenEXR::${COMPONENT} APPEND PROPERTY 426 IMPORTED_CONFIGURATIONS RELEASE) 427 set_target_properties(OpenEXR::${COMPONENT} PROPERTIES 428 IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" 429 IMPORTED_LOCATION_RELEASE "${OpenEXR_${COMPONENT}_LIBRARY_RELEASE}") 430 endif() 431 432 # Debug location 433 if(EXISTS "${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}") 434 set_property(TARGET OpenEXR::${COMPONENT} APPEND PROPERTY 435 IMPORTED_CONFIGURATIONS DEBUG) 436 set_target_properties(OpenEXR::${COMPONENT} PROPERTIES 437 IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" 438 IMPORTED_LOCATION_DEBUG "${OpenEXR_${COMPONENT}_LIBRARY_DEBUG}") 439 endif() 440 endif() 441endforeach() 442 443