-
Notifications
You must be signed in to change notification settings - Fork 620
/
OpenEXRSetup.cmake
363 lines (318 loc) · 14.9 KB
/
OpenEXRSetup.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
include(GNUInstallDirs)
if(NOT "${CMAKE_PROJECT_NAME}" STREQUAL "${PROJECT_NAME}")
set(OPENEXR_IS_SUBPROJECT ON)
message(STATUS "OpenEXR is configuring as a cmake subproject")
endif()
########################
## Target configuration
# What C++ standard to compile for
# VFX Platform 21 is c++17, so 21, 22, 23, 24 gives us 4+ years of 17
set(tmp 17)
if(CMAKE_CXX_STANDARD GREATER tmp)
set(tmp ${CMAKE_CXX_STANDARD})
endif()
set(OPENEXR_CXX_STANDARD "${tmp}" CACHE STRING "C++ standard to compile against")
set(tmp)
message(STATUS "Building against C++ Standard: ${OPENEXR_CXX_STANDARD}")
set(OPENEXR_NAMESPACE_CUSTOM "0" CACHE STRING "Whether the namespace has been customized (so external users know)")
set(OPENEXR_INTERNAL_IMF_NAMESPACE "Imf_${OPENEXR_VERSION_API}" CACHE STRING "Real namespace for OpenEXR that will end up in compiled symbols")
set(OPENEXR_IMF_NAMESPACE "Imf" CACHE STRING "Public namespace alias for OpenEXR")
set(OPENEXR_PACKAGE_NAME "OpenEXR ${OPENEXR_VERSION}${OPENEXR_VERSION_RELEASE_TYPE}" CACHE STRING "Public string / label for displaying package")
# Namespace-related settings, allows one to customize the
# namespace generated, and to version the namespaces
set(ILMTHREAD_NAMESPACE_CUSTOM "0" CACHE STRING "Whether the namespace has been customized (so external users know)")
set(ILMTHREAD_INTERNAL_NAMESPACE "IlmThread_${OPENEXR_VERSION_API}" CACHE STRING "Real namespace for IlmThread that will end up in compiled symbols")
set(ILMTHREAD_NAMESPACE "IlmThread" CACHE STRING "Public namespace alias for IlmThread")
set(IEX_NAMESPACE_CUSTOM "0" CACHE STRING "Whether the namespace has been customized (so external users know)")
set(IEX_INTERNAL_NAMESPACE "Iex_${OPENEXR_VERSION_API}" CACHE STRING "Real namespace for Iex that will end up in compiled symbols")
set(IEX_NAMESPACE "Iex" CACHE STRING "Public namespace alias for Iex")
# Whether to generate and install a pkg-config file OpenEXR.pc
option(OPENEXR_INSTALL_PKG_CONFIG "Install OpenEXR.pc file" ON)
# Whether to enable threading. This can be disabled, although thread pool and tasks
# are still used, just processed immediately
option(OPENEXR_ENABLE_THREADING "Enables threaded processing of requests" ON)
option(OPENEXR_USE_DEFAULT_VISIBILITY "Makes the compile use default visibility (by default compiles tidy, hidden-by-default)" OFF)
# This is primarily for the auto array that enables a stack
# object (if you enable this) that contains member to avoid double allocations
option(OPENEXR_ENABLE_LARGE_STACK "Enables code to take advantage of large stack support" OFF)
########################
## Build related options
option(OPENEXR_INSTALL "Install OpenEXR libraries/binaries/bindings" ON)
# Whether to build & install the main libraries
option(OPENEXR_BUILD_LIBS "Enables building of main libraries" ON)
# Whether to build the various command line utility programs
option(OPENEXR_BUILD_TOOLS "Enables building of utility programs" ON)
option(OPENEXR_INSTALL_TOOLS "Install OpenEXR tools" ON)
option(OPENEXR_BUILD_EXAMPLES "Build and install OpenEXR examples" ON)
option(OPENEXR_BUILD_PYTHON "Build python bindings" OFF)
option(OPENEXR_TEST_LIBRARIES "Run library tests" ON)
option(OPENEXR_TEST_TOOLS "Run tool tests" ON)
option(OPENEXR_TEST_PYTHON "Run python binding tests" ON)
# This is a variable here for use in controlling where include files are
# installed. Care must be taken when changing this, as many things
# probably assume this is OpenEXR
set(OPENEXR_OUTPUT_SUBDIR OpenEXR CACHE STRING "Destination sub-folder of the include path for install")
# This does not seem to be available as a per-target property,
# but is pretty harmless to set globally
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Suffix for debug configuration libraries
# (if you should choose to install those)
set(CMAKE_DEBUG_POSTFIX "_d" CACHE STRING "Suffix for debug builds")
if(NOT OPENEXR_IS_SUBPROJECT)
# Usual cmake option to build shared libraries or not, only overridden if OpenEXR is a top level project,
# in general this setting should be explicitly configured by the end user
option(BUILD_SHARED_LIBS "Build shared library" ON)
endif()
# Suffix to append to root name, this helps with version management
# but can be turned off if you don't care, or otherwise customized
set(OPENEXR_LIB_SUFFIX "-${OPENEXR_VERSION_API}" CACHE STRING "string added to the end of all the libraries")
# when building both dynamic and static, the additional string to
# add to the library name, such that to get static linkage, you
# would use -lOpenEXR_static (or target_link_libraries(xxx OpenEXR::OpenEXR_static))
set(OPENEXR_STATIC_LIB_SUFFIX "_static" CACHE STRING "When building both static and shared, name to append to static library (in addition to normal suffix)")
# rpath related setup
# make sure we force an rpath to the rpath we're compiling
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# adds the automatically determined parts of the rpath
# which point to directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
if(APPLE)
set(CMAKE_MACOSX_RPATH ON)
endif()
# if the user sets an install rpath
# then just use that, or otherwise set one for them
if(NOT CMAKE_INSTALL_RPATH)
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
if("${CMAKE_SYSTEM}" MATCHES "Linux")
get_filename_component(tmpSysPath "${CMAKE_INSTALL_FULL_LIBDIR}" NAME)
if(NOT tmpSysPath)
set(tmpSysPath "lib")
endif()
set(CMAKE_INSTALL_RPATH "\\\$ORIGIN/../${tmpSysPath};${CMAKE_INSTALL_FULL_LIBDIR}")
set(tmpSysPath)
elseif(APPLE)
set(CMAKE_INSTALL_RPATH "@loader_path/../lib;@executable_path/../lib;${CMAKE_INSTALL_FULL_LIBDIR}")
else()
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}")
endif()
endif()
set(isSystemDir)
endif()
########################
# set a default build type if not set
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# Code check related features
option(OPENEXR_USE_CLANG_TIDY "Check if clang-tidy is available, and enable that" OFF)
if(OPENEXR_USE_CLANG_TIDY)
find_program(OPENEXR_CLANG_TIDY_BIN clang-tidy)
if(OPENEXR_CLANG_TIDY_BIN-NOTFOUND)
message(FATAL_ERROR "clang-tidy processing requested, but no clang-tidy found")
endif()
# TODO: Need to define the list of valid checks and add a file with said list
set(CMAKE_CXX_CLANG_TIDY
${OPENEXR_CLANG_TIDY_BIN};
-header-filter=.;
-checks=*;
)
endif()
if (NOT OPENEXR_BUILD_LIBS)
return()
endif()
###############################
# Dependent libraries
# so we know how to add the thread stuff to the pkg-config package
# which is the only (but good) reason.
if(OPENEXR_ENABLE_THREADING)
if(NOT TARGET Threads::Threads)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
if(NOT Threads_FOUND)
message(FATAL_ERROR "Unable to find a threading library, disable with OPENEXR_ENABLE_THREADING=OFF")
endif()
endif()
endif()
option(OPENEXR_FORCE_INTERNAL_DEFLATE "Force using an internal libdeflate" OFF)
set(OPENEXR_DEFLATE_REPO "https://github.com/ebiggers/libdeflate.git" CACHE STRING "Repo path for libdeflate source")
set(OPENEXR_DEFLATE_TAG "master" CACHE STRING "Tag to use for libdeflate source repo (defaults to primary if empty)")
if(NOT OPENEXR_FORCE_INTERNAL_DEFLATE)
#TODO: ^^ Release should not clone from main, this is a place holder
set(CMAKE_IGNORE_PATH "${CMAKE_CURRENT_BINARY_DIR}/_deps/deflate-src/config;${CMAKE_CURRENT_BINARY_DIR}/_deps/deflate-build/config")
# First try cmake config
find_package(libdeflate CONFIG QUIET)
if(libdeflate_FOUND)
if(TARGET libdeflate::libdeflate_shared)
set(EXR_DEFLATE_LIB libdeflate::libdeflate_shared)
else()
set(EXR_DEFLATE_LIB libdeflate::libdeflate_static)
endif()
set(EXR_DEFLATE_VERSION ${libdeflate_VERSION})
message(STATUS "Using libdeflate from ${libdeflate_DIR}")
else()
# If not found, try pkgconfig
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
include(FindPkgConfig)
pkg_check_modules(deflate IMPORTED_TARGET GLOBAL libdeflate)
if(deflate_FOUND)
set(EXR_DEFLATE_LIB PkgConfig::deflate)
set(EXR_DEFLATE_VERSION ${deflate_VERSION})
message(STATUS "Using libdeflate from ${deflate_LINK_LIBRARIES}")
endif()
endif()
endif()
set(CMAKE_IGNORE_PATH)
endif()
if(EXR_DEFLATE_LIB)
# Using external library
set(EXR_DEFLATE_SOURCES)
set(EXR_DEFLATE_INCLUDE_DIR)
# For OpenEXR.pc.in for static build
set(EXR_DEFLATE_PKGCONFIG_REQUIRES "libdeflate >= ${EXR_DEFLATE_VERSION}")
else()
# Using internal deflate
if(OPENEXR_FORCE_INTERNAL_DEFLATE)
message(STATUS "libdeflate forced internal, installing from ${OPENEXR_DEFLATE_REPO} (${OPENEXR_DEFLATE_TAG})")
else()
message(STATUS "libdeflate was not found, installing from ${OPENEXR_DEFLATE_REPO} (${OPENEXR_DEFLATE_TAG})")
endif()
include(FetchContent)
# Fetch deflate but exclude it from the "all" target.
# This prevents the library from being built.
FetchContent_Declare(Deflate
GIT_REPOSITORY "${OPENEXR_DEFLATE_REPO}"
GIT_TAG "${OPENEXR_DEFLATE_TAG}"
GIT_SHALLOW ON
EXCLUDE_FROM_ALL
)
FetchContent_GetProperties(Deflate)
if(NOT deflate_POPULATED)
if(CMAKE_VERSION VERSION_LESS "3.30")
# CMake 3.30 deprecated this single argument version of
# FetchContent_Populate():
# https://cmake.org/cmake/help/latest/policy/CMP0169.html
# Prior to CMake 3.28, passing the EXCLUDE_FROM_ALL option to
# FetchContent_Declare() does *not* have the desired effect of
# excluding the fetched content from the build when
# FetchContent_MakeAvailable() is called.
# Ideally we could "manually" set the EXCLUDE_FROM_ALL property on the
# deflate SOURCE_DIR and BINARY_DIR, but a bug that was only fixed as of
# CMake 3.20.3 prevents that from properly excluding the directories:
# https://gitlab.kitware.com/cmake/cmake/-/issues/22234
# To support the full range of CMake versions without overly
# complicating the logic here with workarounds, we continue to use
# Populate for CMake versions before 3.30, and switch to MakeAvailable
# for CMake 3.30 and later.
FetchContent_Populate(Deflate)
else()
FetchContent_MakeAvailable(Deflate)
endif()
endif()
# Rather than actually compile something, just embed the sources
# into exrcore. This could in theory cause issues when compiling as
# a static library into another application which also uses
# libdeflate but we switch the export symbol to hidden which should
# hide the symbols when linking...
set(EXR_DEFLATE_SOURCES
lib/arm/cpu_features.c
lib/x86/cpu_features.c
lib/utils.c
lib/deflate_compress.c
lib/deflate_decompress.c
lib/adler32.c
lib/zlib_compress.c
lib/zlib_decompress.c)
# don't need these
# lib/crc32.c
# lib/gzip_compress.c
# lib/gzip_decompress.c
file(READ ${deflate_SOURCE_DIR}/lib/lib_common.h DEFLATE_HIDE)
string(REPLACE "visibility(\"default\")" "visibility(\"hidden\")" DEFLATE_HIDE "${DEFLATE_HIDE}")
string(REPLACE "__declspec(dllexport)" "/**/" DEFLATE_HIDE "${DEFLATE_HIDE}")
file(WRITE ${deflate_SOURCE_DIR}/lib/lib_common.h "${DEFLATE_HIDE}")
# cmake makes fetch content name lowercase for the properties (to deflate)
list(TRANSFORM EXR_DEFLATE_SOURCES PREPEND ${deflate_SOURCE_DIR}/)
set(EXR_DEFLATE_INCLUDE_DIR ${deflate_SOURCE_DIR})
set(EXR_DEFLATE_LIB)
endif()
#######################################
# Find or install Imath
#######################################
option(OPENEXR_FORCE_INTERNAL_IMATH "Force using an internal imath" OFF)
# Check to see if Imath is installed outside of the current build directory.
set(OPENEXR_IMATH_REPO "https://github.com/AcademySoftwareFoundation/Imath.git" CACHE STRING "Repo for auto-build of Imath")
set(OPENEXR_IMATH_TAG "main" CACHE STRING "Tag for auto-build of Imath (branch, tag, or SHA)")
if(NOT OPENEXR_FORCE_INTERNAL_IMATH)
#TODO: ^^ Release should not clone from main, this is a place holder
set(CMAKE_IGNORE_PATH "${CMAKE_CURRENT_BINARY_DIR}/_deps/imath-src/config;${CMAKE_CURRENT_BINARY_DIR}/_deps/imath-build/config")
find_package(Imath 3.1)
set(CMAKE_IGNORE_PATH)
endif()
if(NOT TARGET Imath::Imath AND NOT Imath_FOUND)
if(OPENEXR_FORCE_INTERNAL_IMATH)
message(STATUS "Imath forced internal, installing from ${OPENEXR_IMATH_REPO} (${OPENEXR_IMATH_TAG})")
else()
message(STATUS "Imath was not found, installing from ${OPENEXR_IMATH_REPO} (${OPENEXR_IMATH_TAG})")
endif()
include(FetchContent)
FetchContent_Declare(Imath
GIT_REPOSITORY "${OPENEXR_IMATH_REPO}"
GIT_TAG "${OPENEXR_IMATH_TAG}"
GIT_SHALLOW ON
)
FetchContent_GetProperties(Imath)
if(NOT Imath_POPULATED)
FetchContent_MakeAvailable(Imath)
# Propagate OpenEXR's install setting to Imath
set(IMATH_INSTALL ${OPENEXR_INSTALL})
# Propagate OpenEXR's setting for pkg-config generation to Imath:
# If OpenEXR is generating it, the internal Imath should, too.
set(IMATH_INSTALL_PKG_CONFIG ${OPENEXR_INSTALL_PKG_CONFIG})
endif()
# the install creates this but if we're using the library locally we
# haven't installed the header files yet, so need to extract those
# and make a variable for header only usage
if(NOT TARGET Imath::ImathConfig)
get_target_property(imathinc Imath INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(imathconfinc ImathConfig INTERFACE_INCLUDE_DIRECTORIES)
list(APPEND imathinc ${imathconfinc})
set(IMATH_HEADER_ONLY_INCLUDE_DIRS ${imathinc})
message(STATUS "Imath interface dirs ${IMATH_HEADER_ONLY_INCLUDE_DIRS}")
endif()
else()
message(STATUS "Using Imath from ${Imath_DIR}")
# local build
# add_subdirectory(${IMATH_ROOT} Imath)
# add_subdirectory(${OPENEXR_ROOT} OpenEXR)
if(NOT TARGET Imath::ImathConfig AND TARGET Imath AND TARGET ImathConfig)
get_target_property(imathinc Imath INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(imathconfinc ImathConfig INTERFACE_INCLUDE_DIRECTORIES)
list(APPEND imathinc ${imathconfinc})
set(IMATH_HEADER_ONLY_INCLUDE_DIRS ${imathinc})
message(STATUS "Imath interface dirs ${IMATH_HEADER_ONLY_INCLUDE_DIRS}")
endif()
endif()
###########################################
# Check if we need to emulate vld1q_f32_x2
###########################################
if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
include(CheckCSourceCompiles)
check_c_source_compiles("#include <arm_neon.h>
int main() {
float a[] = {1.0, 1.0};
vld1q_f32_x2(a);
return 0;
}" HAS_VLD1)
if(NOT HAS_VLD1)
set(OPENEXR_MISSING_ARM_VLD1 TRUE)
endif()
endif()