Skip to content

Commit 3fc5c85

Browse files
committed
Extend checked_find_package with VERSION_MIN and VERSION_MAX (#1303)
Upon reading cmake docs mre carefully, it's clear that when you pass a version to find_package (which does much of the heavy lifting inside checked_find_package), it DOESN'T MEAN you want that version or later. It means you want to find a version that is "compatible" with the named version. The meaning of "compatible" is up to the package. Some packages define it as being >= the requested version. Others define it as being the same major release, or same major AND minor release, or exact. But generally speaking, we only care about the minimum version (e.g., "I want FooBar 8.0 or later"). And it's not guaranteed that is what the package's compatibility will do. In fact, FooBar may be using compatibility mode "SameMajorVersion", which will make our find of FooBar succeed for 8.0, 8.1, 8.2, but if a user encounters FooBar 9.0, our build will reject it, even though it's probably fine. So I augmented our checked_find_package wrapper to take optional VERSION_MIN to give the real minimum version, when that's the semantic we really want (in which case we would omit the ordinary version number used for the compatibility check and let VERSION_MIN do all the work). There's also an optional (and usually omitted) VERSION_MAX that you can use if you are sure that we must be less than a certain version (the max is exclusive, you must be <, not <=, whereas the min is inclusive >=). Signed-off-by: Larry Gritz <[email protected]>
1 parent 62d1428 commit 3fc5c85

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

src/cmake/checked_find_package.cmake

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ set (OPTIONAL_DEPS "" CACHE STRING
99
"Additional dependencies to consider optional (semicolon-separated list, or ALL)")
1010

1111

12-
# checked_find_package(pkgname ..) is a wrapper for find_package, with the
12+
# checked_find_package(Pkgname ...) is a wrapper for find_package, with the
1313
# following extra features:
14-
# * If either `USE_pkgname` or the all-uppercase `USE_PKGNAME` (or
15-
# `ENABLE_pkgname` or `ENABLE_PKGNAME`) exists as either a CMake or
14+
# * If either `USE_Pkgname` or the all-uppercase `USE_PKGNAME` (or
15+
# `ENABLE_Pkgname` or `ENABLE_PKGNAME`) exists as either a CMake or
1616
# environment variable, is nonempty by contains a non-true/nonzero
1717
# value, do not search for or use the package. The optional ENABLE <var>
1818
# arguments allow you to override the name of the enabling variable. In
1919
# other words, support for the dependency is presumed to be ON, unless
2020
# turned off explicitly from one of these sources.
2121
# * Print a message if the package is enabled but not found. This is based
22-
# on ${pkgname}_FOUND or $PKGNNAME_FOUND.
22+
# on ${Pkgname}_FOUND or $PKGNAME_FOUND.
2323
# * Optional DEFINITIONS <string> are passed to add_definitions if the
2424
# package is found.
2525
# * Optional PRINT <list> is a list of variables that will be printed
@@ -30,6 +30,14 @@ set (OPTIONAL_DEPS "" CACHE STRING
3030
# present package is only needed because it's a dependency, and
3131
# therefore if <downstream> is disabled, we don't bother with this
3232
# package either.
33+
# * Optional VERSION_MIN and VERSION_MAX, if supplied, give minimum and
34+
# maximum versions that will be accepted. The min is inclusive, the max
35+
# is exclusive (i.e., check for min <= version < max). Note that this is
36+
# not the same as providing a version number to find_package, which
37+
# checks compatibility, not minimum. Sometimes we really do just want to
38+
# say a minimum or a range. (N.B. When our minimum CMake >= 3.19, the
39+
# built-in way to do this is with version ranges passed to
40+
# find_package.)
3341
# * Optional RECOMMEND_MIN, if supplied, gives a minimum recommended
3442
# version, accepting but warning if it is below this number (even
3543
# if above the true minimum version accepted). The warning message
@@ -43,7 +51,7 @@ macro (checked_find_package pkgname)
4351
# noValueKeywords:
4452
"REQUIRED"
4553
# singleValueKeywords:
46-
"ENABLE;ISDEPOF;RECOMMEND_MIN;RECOMMEND_MIN_REASON"
54+
"ENABLE;ISDEPOF;VERSION_MIN;VERSION_MAX;RECOMMEND_MIN;RECOMMEND_MIN_REASON"
4755
# multiValueKeywords:
4856
"DEFINITIONS;PRINT;DEPS"
4957
# argsToParse:
@@ -79,6 +87,18 @@ macro (checked_find_package pkgname)
7987
endif ()
8088
if (_enable OR _pkg_REQUIRED)
8189
find_package (${pkgname} ${_pkg_UNPARSED_ARGUMENTS})
90+
if ((${pkgname}_FOUND OR ${pkgname_upper}_FOUND)
91+
AND ${pkgname}_VERSION
92+
AND (_pkg_VERSION_MIN OR _pkg_VERSION_MAX))
93+
if ((_pkg_VERSION_MIN AND ${pkgname}_VERSION VERSION_LESS _pkg_VERSION_MIN)
94+
OR (_pkg_VERSION_MAX AND ${pkgname}_VERSION VERSION_GREATER _pkg_VERSION_MAX))
95+
message (STATUS "${ColorRed}${pkgname} ${${pkgname}_VERSION} is outside the required range ${_pkg_VERSION_MIN}...${_pkg_VERSION_MAX} ${ColorReset}")
96+
unset (${pkgname}_FOUND)
97+
unset (${pkgname}_VERSION)
98+
unset (${pkgname_upper}_FOUND)
99+
unset (${pkgname_upper}_VERSION)
100+
endif ()
101+
endif ()
82102
if (${pkgname}_FOUND OR ${pkgname_upper}_FOUND)
83103
foreach (_vervar ${pkgname_upper}_VERSION ${pkgname}_VERSION_STRING
84104
${pkgname_upper}_VERSION_STRING)

src/cmake/externalpackages.cmake

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ else ()
5757
# to set the expected variables printed below. So until that's fixed
5858
# force FindBoost.cmake to use the original brute force path.
5959
set (Boost_NO_BOOST_CMAKE ON)
60-
checked_find_package (Boost 1.55 REQUIRED
60+
checked_find_package (Boost REQUIRED
61+
VERSION_MIN 1.55
6162
COMPONENTS ${Boost_COMPONENTS}
63+
RECOMMEND_MIN 1.66
64+
RECOMMEND_MIN_REASON "Boost 1.66 is the oldest version our CI tests against"
6265
PRINT Boost_INCLUDE_DIRS Boost_LIBRARIES
6366
)
6467
endif ()
@@ -79,8 +82,13 @@ link_directories ("${Boost_LIBRARY_DIRS}")
7982
checked_find_package (ZLIB REQUIRED) # Needed by several packages
8083

8184
# IlmBase & OpenEXR
82-
checked_find_package (OpenEXR 2.0 REQUIRED
83-
PRINT IMATH_INCLUDES)
85+
checked_find_package (OpenEXR REQUIRED
86+
VERSION_MIN 2.0
87+
RECOMMEND_MIN 2.2
88+
RECOMMEND_MIN_REASON
89+
"OpenEXR 2.2 is the oldest version our CI tests against, and the minimum that supports DWA compression"
90+
PRINT IMATH_INCLUDES
91+
)
8492
if (CMAKE_COMPILER_IS_CLANG AND OPENEXR_VERSION VERSION_LESS 2.3)
8593
# clang C++ >= 11 doesn't like 'register' keyword in old exr headers
8694
add_compile_options (-Wno-deprecated-register)
@@ -93,18 +101,21 @@ endif ()
93101
# OpenImageIO
94102
set (OIIO_LIBNAME_SUFFIX "" CACHE STRING
95103
"Optional name appended to OIIO libraries that are built")
96-
checked_find_package (OpenImageIO 2.0 REQUIRED
104+
checked_find_package (OpenImageIO REQUIRED
105+
VERSION_MIN 2.0
97106
PRINT OIIOTOOL_BIN)
98107
if (OPENIMAGEIO_FOUND)
99108
include_directories ("${OPENIMAGEIO_INCLUDES}")
100109
endif ()
101110

102111

103-
checked_find_package (pugixml 1.8 REQUIRED)
112+
checked_find_package (pugixml REQUIRED
113+
VERSION_MIN 1.8)
104114

105115

106116
# LLVM library setup
107-
checked_find_package (LLVM 7.0 REQUIRED
117+
checked_find_package (LLVM REQUIRED
118+
VERSION_MIN 7.0
108119
PRINT LLVM_SYSTEM_LIBRARIES CLANG_LIBRARIES)
109120
# ensure include directory is added (in case of non-standard locations
110121
include_directories (BEFORE SYSTEM "${LLVM_INCLUDES}")
@@ -169,7 +180,8 @@ if (USE_CUDA OR USE_OPTIX)
169180
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
170181
endif ()
171182

172-
checked_find_package (CUDA 8.0 REQUIRED
183+
checked_find_package (CUDA REQUIRED
184+
VERSION_MIN 8.0
173185
PRINT CUDA_INCLUDES)
174186
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
175187
include_directories (BEFORE "${CUDA_INCLUDES}")
@@ -202,7 +214,8 @@ if (USE_CUDA OR USE_OPTIX)
202214

203215
# OptiX setup
204216
if (USE_OPTIX)
205-
checked_find_package (OptiX 5.1 REQUIRED)
217+
checked_find_package (OptiX REQUIRED
218+
VERSION_MIN 5.1)
206219
include_directories (BEFORE "${OPTIX_INCLUDES}")
207220
if (NOT USE_LLVM_BITCODE OR NOT USE_FAST_MATH)
208221
message (FATAL_ERROR "Enabling OptiX requires USE_LLVM_BITCODE=1 and USE_FAST_MATH=1")

0 commit comments

Comments
 (0)