FindMIRTK.cmake
Go to the documentation of this file.
1 #.rst:
2 # FindMIRTK
3 # ---------
4 #
5 # Find the Medical Image Registration ToolKit (MIRTK).
6 #
7 # This module looks for a MIRTK installation using find_package in CONFIG mode.
8 #
9 # This module does not itself define any :prop_tgt:`IMPORTED` target as these
10 # are defined by the ``MIRTKTargets.cmake`` file included by ``MIRTKConfig.cmake``
11 # if MIRTK has been found. For example, the Common library of the MIRTK is
12 # imported as target ``mirtk::LibCommon``. Similar for other modules.
13 # When a required MIRTK module was not found, the ``MIRTKConfig.cmake`` will
14 # report an error with the names of the required, optional, and missing modules.
15 #
16 # Result variables::
17 #
18 # MIRTK_FOUND - True if headers and required components were found.
19 # MIRTK_<Module>_FOUND - True if requested module was found.
20 # MIRTK_VERSION - Version of found MIRTK libraries.
21 # MIRTK_VERSION_MAJOR - Major version number of found MIRTK libraries.
22 # MIRTK_VERSION_MINOR - Minor version number of found MIRTK libraries.
23 # MIRTK_VERSION_PATCH - Patch number of found MIRTK libraries.
24 # MIRTK_INCLUDE_DIRS - MIRTK include directories.
25 # MIRTK_LIBRARY_DIRS - Link directories for MIRTK libraries.
26 # MIRTK_MODULES - List of official MIRTK modules.
27 # MIRTK_MODULES_ENABLED - List of installed MIRTK modules.
28 # MIRTK_MODULES_FOUND - List of requested and found MIRTK modules.
29 # MIRTK_MODULES_NOTFOUND - List of not found optional MIRTK modules.
30 #
31 # By default, this module reads hints about search paths from variables::
32 #
33 # DEPENDS_MIRTK_DIR - Either installation root or MIRTKConfig.cmake directory.
34 # MIRTK_DIR - Directory containing the MIRTKConfig.cmake file.
35 # MIRTK_ROOT - Root directory of MIRTK installation.
36 #
37 # This module considers the common ``MIRTK_DIR`` and ``MIRTK_ROOT`` CMake or environment
38 # variables to initialize the ``DEPENDS_MIRTK_DIR`` cache entry. The ``DEPENDS_MIRTK_DIR``
39 # is the non-internal cache entry visible in the CMake GUI. It is marked advanced
40 # when the MIRTK was found, and non-advanced otherwise. This variable can be set
41 # to either the installation prefix of MIRTK, i.e., the top-level directory, or the
42 # directory containing the ``MIRTKConfig.cmake`` file. It therefore is a hybrid of
43 # ``MIRTK_ROOT`` and ``MIRTK_DIR`` and replaces these. The common DEPENDS prefix
44 # for cache entries used to set the location of dependencies allows the grouping
45 # of these variables in the CMake GUI. This is a feature of the CMake BASIS
46 # basis_find_package command. As this command is not available without having found
47 # a MIRTK installation before, this module can be used to replicate a subset of
48 # the basis_find_package functionality for finding MIRTK.
49 #
50 # A custom name or prefix for the cache path entry can be set using the variables::
51 #
52 # MIRTK_CACHE_PATH_NAME - Name of user search path cache entry.
53 # MIRTK_CACHE_PATH_PREFIX - Prefix of user search path cache entry prepended to "MIRTK_DIR".
54 # MIRTK_CACHE_PATH_CMAKE - If true, use CMake's default MIRTK_DIR cache entry.
55 #
56 # For example, to use ``MIRTK_DIR`` as cache variable::
57 #
58 # set(MIRTK_CACHE_PATH_CMAKE TRUE)
59 # find_package(MIRTK REQUIRED)
60 #
61 # or::
62 #
63 # set(MIRTK_CACHE_PATH_NAME MIRTK_DIR)
64 # find_package(MIRTK REQUIRED)
65 #
66 # To use ``MIRTK_ROOT`` as cache variable::
67 #
68 # set(MIRTK_CACHE_PATH_NAME MIRTK_ROOT)
69 # find_package(MIRTK REQUIRED)
70 #
71 # To use ``SYSTEM_MIRTK_DIR`` as cache variable::
72 #
73 # set(MIRTK_CACHE_PATH_PREFIX SYSTEM_)
74 # find_package(MIRTK REQUIRED)
75 
76 #=============================================================================
77 # Copyright 2016 Imperial College London
78 # Copyright 2016 Andreas Schuh
79 #
80 # Redistribution and use in source and binary forms, with or without
81 # modification, are permitted provided that the following conditions
82 # are met:
83 #
84 # * Redistributions of source code must retain the above copyright
85 # notice, this list of conditions and the following disclaimer.
86 #
87 # * Redistributions in binary form must reproduce the above copyright
88 # notice, this list of conditions and the following disclaimer in the
89 # documentation and/or other materials provided with the distribution.
90 #
91 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
92 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
93 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
94 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
95 # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
97 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
101 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102 #=============================================================================
103 
104 # Set MIRTKConfig.cmake directory from installation prefix path
105 function (_mirtk_root_to_config_dir OUT IN)
106  if (IN)
107  if (WIN32)
108  set(${OUT} "${IN}/CMake" PARENT_SCOPE)
109  else ()
110  set(${OUT} "${IN}/lib/cmake/mirtk" PARENT_SCOPE)
111  endif ()
112  else ()
113  set(${OUT} "NOTFOUND" PARENT_SCOPE)
114  endif ()
115 endfunction ()
116 
117 # Set installation prefix path from MIRTKConfig.cmake directory
118 function (_mirtk_config_to_root_dir OUT IN)
119  if (IN)
120  if (WIN32)
121  string(REGEX REPLACE "/+CMake/*$" "" _prefix "${IN}")
122  else ()
123  string(REGEX REPLACE "/+lib/+cmake/+mirtk/*$" "" _prefix "${IN}")
124  endif ()
125  else ()
126  set(_prefix "NOTFOUND")
127  endif ()
128  set(${OUT} "${_prefix}" PARENT_SCOPE)
129 endfunction ()
130 
131 # Name of cache variable to use for user hint of MIRTK location
132 if (MIRTK_CACHE_PATH_NAME)
133  set(_cache "${MIRTK_CACHE_PATH_NAME}")
134 elseif (MIRTK_CACHE_PATH_PREFIX)
135  set(_cache "${MIRTK_CACHE_PATH_PREFIX}MIRTK_DIR")
136 elseif (MIRTK_CACHE_PATH_CMAKE)
137  set(_cache MIRTK_DIR)
138 else ()
139  set(_cache DEPENDS_MIRTK_DIR)
140 endif ()
141 
142 # Add cache entry for user hint of MIRTK search location
143 if ("^${_cache}$" STREQUAL "^MIRTK_DIR$")
144 
145  # Use default MIRTK_DIR cache entry used by find_package in CONFIG mode
146  set (MIRTK_DIR "${MIRTK_DIR}" CACHE PATH "Directory containing MIRTKConfig.cmake file.")
147 
148 elseif ("^${_cache}$" STREQUAL "^MIRTK_ROOT$")
149 
150  # Use MIRTK_ROOT as cache entry
151  set (MIRTK_ROOT "${MIRTK_ROOT}" CACHE PATH "Installation prefix/root directory of MIRTK.")
152 
153  # Set MIRTK_ROOT from -DMIRTK_DIR=<path> and mark the latter as INTERNAL
154  if (MIRTK_DIR AND (NOT DEFINED _MIRTK_DIR OR (DEFINED _MIRTK_DIR AND NOT "^${MIRTK_DIR}$" STREQUAL "^${_MIRTK_DIR}$")))
155  _mirtk_config_to_root_dir(_prefix "${MIRTK_DIR}")
156  set_property(CACHE MIRTK_ROOT PROPERTY VALUE "${_prefix}")
157  endif ()
158  get_property(_cached CACHE MIRTK_DIR PROPERTY TYPE SET)
159  if (_cached)
160  set_property(CACHE MIRTK_DIR PROPERTY TYPE INTERNAL)
161  endif ()
162 
163  # Set MIRTK_ROOT from environment variable
164  #
165  # Note that the MIRTK_DIR environment variable is used by CMake's find_package
166  # as installation prefix search path rather than the location of the MIRTKConfig.cmake!
167  # The MIRTK_DIR environment variable is thus equivalent to the MIRTK_ROOT CMake variable.
168  if (NOT MIRTK_ROOT)
169  foreach (_dir IN ITEMS "$ENV{MIRTK_ROOT}" "$ENV{MIRTK_DIR}")
170  if (_dir)
171  set_property(CACHE ${_cache} PROPERTY VALUE "${_dir}")
172  break()
173  endif ()
174  endforeach ()
175  endif ()
176 
177  # Convert path to CMake style with forward slashes
178  file (TO_CMAKE_PATH "${MIRTK_ROOT}" MIRTK_ROOT)
179 
180  # Set MIRTK_DIR based on MIRTK_ROOT
181  _mirtk_root_to_config_dir(_config_dir "${MIRTK_ROOT}")
182  set(MIRTK_DIR "${_config_dir}" CACHE INTERNAL "Directory containing MIRTKConfig.cmake file." FORCE)
183 
184 else ()
185 
186  # Use more user friendly hybrid DEPENDS_MIRTK_DIR cache variable which allows grouping
187  # of DEPENDS paths or custom named cache entry, but still consider MIRTK_ROOT and
188  # MIRTK_DIR as more common alternatives set in the user shell environment or on the
189  # CMake command line. The DEPENDS_<Package>_DIR is what CMake BASIS uses by default.
190  set (${_cache} "${${_cache}}" CACHE PATH "Installation prefix of MIRTK or directory containing MIRTKConfig.cmake file.")
191 
192  # Override DEPENDS_MIRTK_DIR by alternative search path variable value if these
193  # were specified on the command line using the -D option. Note that these variables
194  # cannot be set in the CMake GUI because their type is changed here to INTERNAL.
195  # This has two reasons, firstly to not have duplicate variables with different
196  # names for the same purpose, and secondly to be able to recognize when their
197  # value is changed using the -D command line option of the cmake command.
198  if (MIRTK_DIR AND (NOT DEFINED _MIRTK_DIR OR (DEFINED _MIRTK_DIR AND NOT "^${MIRTK_DIR}$" STREQUAL "^${_MIRTK_DIR}$")))
199  _mirtk_config_to_root_dir(_prefix "${MIRTK_DIR}")
200  set_property(CACHE ${_cache} PROPERTY VALUE "${_prefix}")
201  endif ()
202  if (MIRTK_ROOT AND (NOT DEFINED _MIRTK_ROOT OR (DEFINED _MIRTK_ROOT AND NOT "^${MIRTK_ROOT}$" STREQUAL "^${_MIRTK_ROOT}$")))
203  set_property(CACHE ${_cache} PROPERTY VALUE "${MIRTK_ROOT}")
204  endif ()
205 
206  # Mark alternatives as internal cache entries
207  foreach (_var IN ITEMS MIRTK_DIR MIRTK_ROOT)
208  get_property(_cached CACHE ${_var} PROPERTY TYPE SET)
209  if (_cached)
210  set_property(CACHE ${_var} PROPERTY TYPE INTERNAL)
211  endif ()
212  endforeach ()
213 
214  # If still not set, use common environment variables to set DEPENDS_MIRTK_DIR
215  if (NOT ${_cache})
216  foreach (_dir IN ITEMS "$ENV{MIRTK_DIR}" "$ENV{MIRTK_ROOT}")
217  if (_dir)
218  set_property(CACHE ${_cache} PROPERTY VALUE "${_dir}")
219  break()
220  endif ()
221  endforeach ()
222  endif ()
223 
224  # Convert path to CMake style with forward slashes
225  file (TO_CMAKE_PATH "${${_cache}}" ${_cache})
226 
227  # Circumvent issue with CMake's find_package() interpreting these variables
228  # relative to the current binary directory instead of the top-level directory
229  if (${_cache} AND NOT IS_ABSOLUTE "${${_cache}}")
230  set (${_cache} "${CMAKE_BINARY_DIR}/${${_cache}}")
231  endif ()
232 
233  # Allow DEPENDS_MIRTK_DIR to be set to either the root directory...
234  if (${_cache})
235  list (INSERT CMAKE_PREFIX_PATH 0 "${${_cache}}")
236  endif ()
237  # ...or the directory containing the MIRTKConfig.cmake file
238  set(MIRTK_DIR "${${_cache}}" CACHE INTERNAL "Directory containing MIRTKConfig.cmake file." FORCE)
239 endif ()
240 
241 # Look for MIRTK installation
242 if (NOT MIRTK_FIND_QUIETLY)
243  set(_msg "Looking for MIRTK")
244  if (MIRTK_FIND_VERSION)
245  set(_msg "${_msg} ${MIRTK_FIND_VERSION}")
246  endif ()
247  if (MIRTK_FIND_COMPONENTS)
248  set(_msg "${_msg} [${MIRTK_FIND_COMPONENTS}]")
249  endif ()
250  message(STATUS "${_msg}...")
251 endif ()
252 
253 set(_argv)
254 if (MIRTK_FIND_VERSION)
255  list(APPEND _argv ${MIRTK_FIND_VERSION})
256 endif ()
257 if (MIRTK_FIND_VERSION_EXACT)
258  list(APPEND _argv EXACT)
259 endif ()
260 set(_comps)
261 set(_comps_opt)
262 foreach (_comp IN LISTS MIRTK_FIND_COMPONENTS)
263  if (MIRTK_FIND_REQUIRED_${_component})
264  list(APPEND _comps ${_component})
265  else ()
266  list(APPEND _comps_opt ${_component})
267  endif ()
268 endforeach ()
269 if (_comps)
270  list(APPEND _argv COMPONENTS ${_comps})
271 endif ()
272 if (_comps_opt)
273  list(APPEND _argv OPTIONAL_COMPONENTS ${_comps_opt})
274 endif ()
275 
276 find_package(MIRTK ${_argv} CONFIG QUIET)
277 
278 if (NOT MIRTK_FIND_QUIETLY)
279  if (MIRTK_FOUND)
280  message(STATUS "Looking for MIRTK... - found v${MIRTK_VERSION}")
281  else ()
282  message(STATUS "Looking for MIRTK... - not found")
283  endif ()
284 endif ()
285 
286 # Make internal search path cache entries consistent with non-internal cache entry
287 if (MIRTK_FOUND)
288  mark_as_advanced(FORCE ${_cache})
289  _mirtk_config_to_root_dir(_prefix "${MIRTK_DIR}")
290 else ()
291  mark_as_advanced(CLEAR ${_cache})
292  set(_prefix NOTFOUND)
293 endif ()
294 if (NOT "^${_cache}$" STREQUAL "^MIRTK_DIR$")
295  set_property(CACHE MIRTK_DIR PROPERTY TYPE INTERNAL)
296  set(_MIRTK_DIR "${MIRTK_DIR}" CACHE INTERNAL "Previous MIRTK_DIR value" FORCE)
297 endif ()
298 get_property(_cached CACHE MIRTK_ROOT PROPERTY TYPE SET)
299 if (_cached)
300  set_property(CACHE MIRTK_ROOT PROPERTY VALUE "${_prefix}")
301 else ()
302  set(MIRTK_ROOT "${_prefix}")
303 endif ()
304 if (NOT _cache MATCHES "^MIRTK_(DIR|ROOT)$")
305  set_property(CACHE ${_cache} PROPERTY VALUE "${_prefix}")
306 endif ()
307 
308 # Make internal cache copies of alternative search path variables
309 # so we can detect when a new value was specified using -D option
310 foreach (_var IN ITEMS MIRTK_DIR MIRTK_ROOT)
311  if (NOT "^${_cache}$" STREQUAL "^${_var}$")
312  get_property(_cached CACHE ${_var} PROPERTY TYPE SET)
313  if (_cached)
314  set(_${_var} "${${_var}}" CACHE INTERNAL "Previous value of ${_var} after last find_package(MIRTK)" FORCE)
315  endif ()
316  endif ()
317 endforeach ()
318 
319 # Raise fatal error when MIRTK required but not found
320 if (MIRTK_FIND_REQUIRED AND NOT MIRTK_FOUND)
321  set(_msg "Could not find MIRTK! Please ensure that it is installed"
322  " in a standard system location or set ${_cache}")
323  if ("^${_cache}$" STREQUAL "^MIRTK_DIR$")
324  set(_msg "${_msg} to the directory containing the MIRTKConfig.cmake file.")
325  elseif ("^${_cache}$" STREQUAL "^MIRTK_ROOT$")
326  set(_msg "${_msg} to the installation prefix of MIRTK, i.e., the root directory.")
327  else ()
328  set(_msg "${_msg} either to the installation prefix of MIRTK, i.e., the root directory,"
329  " or the directory containing the MIRTKConfig.cmake file.")
330  endif ()
331  string(REPLACE ";" "" _msg "${_msg}")
332  message(FATAL_ERROR "${_msg}")
333 endif ()
334 
335 # Unset local variables
336 unset(_prefix)
337 unset(_config_dir)
338 unset(_cache)
339 unset(_argv)
340 unset(_comp)
341 unset(_comps)
342 unset(_comps_opt)
343 unset(_cached)
344 unset(_dir)
345 unset(_var)
346 unset(_msg)
cmake _prefix
cmake _cache
cmake _msg
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
cmake MIRTK_ROOT
cmake _MIRTK_DIR
cmake DIR
cmake VALUE
macro find_package()
Overloaded find_package() command.
cmake MIRTK_DIR