Medical Imaging Interaction Toolkit  2018.4.99-e1268d66
Medical Imaging Interaction Toolkit
CMakePackageConfigHelpers.cmake
Go to the documentation of this file.
1 # - CONFIGURE_PACKAGE_CONFIG_FILE(), WRITE_BASIC_PACKAGE_VERSION_FILE()
2 #
3 # CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path>
4 # [PATH_VARS <var1> <var2> ... <varN>]
5 # [NO_SET_AND_CHECK_MACRO]
6 # [NO_CHECK_REQUIRED_COMPONENTS_MACRO])
7 #
8 # CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain
9 # configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
10 # file for installing a project or library. It helps making the resulting package
11 # relocatable by avoiding hardcoded paths in the installed Config.cmake file.
12 #
13 # In a FooConfig.cmake file there may be code like this to make the
14 # install destinations know to the using project:
15 # set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
16 # set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
17 # set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
18 # ...logic to determine installedPrefix from the own location...
19 # set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
20 # All 4 options shown above are not sufficient, since the first 3 hardcode
21 # the absolute directory locations, and the 4th case works only if the logic
22 # to determine the installedPrefix is correct, and if CONFIG_INSTALL_DIR contains
23 # a relative path, which in general cannot be guaranteed.
24 # This has the effect that the resulting FooConfig.cmake file would work poorly
25 # under Windows and OSX, where users are used to choose the install location
26 # of a binary package at install time, independent from how CMAKE_INSTALL_PREFIX
27 # was set at build/cmake time.
28 #
29 # Using CONFIGURE_PACKAGE_CONFIG_FILE() helps. If used correctly, it makes the
30 # resulting FooConfig.cmake file relocatable.
31 # Usage:
32 # 1. write a FooConfig.cmake.in file as you are used to
33 # 2. insert a line containing only the string "@PACKAGE_INIT@"
34 # 3. instead of set(FOO_DIR "@SOME_INSTALL_DIR@"), use set(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")
35 # (this must be after the @PACKAGE_INIT@ line)
36 # 4. instead of using the normal configure_file(), use CONFIGURE_PACKAGE_CONFIG_FILE()
37 #
38 # The <input> and <output> arguments are the input and output file, the same way
39 # as in configure_file().
40 #
41 # The <path> given to INSTALL_DESTINATION must be the destination where the FooConfig.cmake
42 # file will be installed to. This can either be a relative or absolute path, both work.
43 #
44 # The variables <var1> to <varN> given as PATH_VARS are the variables which contain
45 # install destinations. For each of them the macro will create a helper variable
46 # PACKAGE_<var...>. These helper variables must be used
47 # in the FooConfig.cmake.in file for setting the installed location. They are calculated
48 # by CONFIGURE_PACKAGE_CONFIG_FILE() so that they are always relative to the
49 # installed location of the package. This works both for relative and also for absolute locations.
50 # For absolute locations it works only if the absolute location is a subdirectory
51 # of CMAKE_INSTALL_PREFIX.
52 #
53 # By default configure_package_config_file() also generates two helper macros,
54 # set_and_check() and check_required_components() into the FooConfig.cmake file.
55 #
56 # set_and_check() should be used instead of the normal set()
57 # command for setting directories and file locations. Additionally to setting the
58 # variable it also checks that the referenced file or directory actually exists
59 # and fails with a FATAL_ERROR otherwise. This makes sure that the created
60 # FooConfig.cmake file does not contain wrong references.
61 # When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the
62 # FooConfig.cmake file.
63 #
64 # check_required_components(<package_name>) should be called at the end of the
65 # FooConfig.cmake file if the package supports components.
66 # This macro checks whether all requested, non-optional components have been found,
67 # and if this is not the case, sets the Foo_FOUND variable to FALSE, so that the package
68 # is considered to be not found.
69 # It does that by testing the Foo_<Component>_FOUND variables for all requested
70 # required components.
71 # When using the NO_CHECK_REQUIRED_COMPONENTS option, this macro is not generated
72 # into the FooConfig.cmake file.
73 #
74 # For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE().
75 #
76 #
77 # WRITE_BASIC_PACKAGE_VERSION_FILE( filename VERSION major.minor.patch COMPATIBILITY (AnyNewerVersion|SameMajorVersion|ExactVersion) )
78 #
79 # Writes a file for use as <package>ConfigVersion.cmake file to <filename>.
80 # See the documentation of find_package() for details on this.
81 # filename is the output filename, it should be in the build tree.
82 # major.minor.patch is the version number of the project to be installed
83 # The COMPATIBILITY mode AnyNewerVersion means that the installed package version
84 # will be considered compatible if it is newer or exactly the same as the requested version.
85 # This mode should be used for packages which are fully backward compatible,
86 # also across major versions.
87 # If SameMajorVersion is used instead, then the behaviour differs from AnyNewerVersion
88 # in that the major version number must be the same as requested, e.g. version 2.0 will
89 # not be considered compatible if 1.0 is requested.
90 # This mode should be used for packages which guarantee backward compatibility within the
91 # same major version.
92 # If ExactVersion is used, then the package is only considered compatible if the requested
93 # version matches exactly its own version number (not considering the tweak version).
94 # For example, version 1.2.3 of a package is only considered compatible to requested version 1.2.3.
95 # This mode is for packages without compatibility guarantees.
96 # If your project has more elaborated version matching rules, you will need to write your
97 # own custom ConfigVersion.cmake file instead of using this macro.
98 #
99 # Internally, this macro executes configure_file() to create the resulting
100 # version file. Depending on the COMPATIBLITY, either the file
101 # BasicConfigVersion-SameMajorVersion.cmake.in or BasicConfigVersion-AnyNewerVersion.cmake.in
102 # is used. Please note that these two files are internal to CMake and you should
103 # not call configure_file() on them yourself, but they can be used as starting
104 # point to create more sophisticted custom ConfigVersion.cmake files.
105 #
106 #
107 # Example using both configure_package_config_file() and write_basic_package_version_file():
108 # CMakeLists.txt:
109 # set(INCLUDE_INSTALL_DIR include/ ... CACHE )
110 # set(LIB_INSTALL_DIR lib/ ... CACHE )
111 # set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE )
112 # ...
113 # include(CMakePackageConfigHelpers)
114 # configure_package_config_file(FooConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
115 # INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
116 # PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
117 # write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
118 # VERSION 1.2.3
119 # COMPATIBILITY SameMajorVersion )
120 # install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
121 # DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake )
122 #
123 # With a FooConfig.cmake.in:
124 # set(FOO_VERSION x.y.z)
125 # ...
126 # @PACKAGE_INIT@
127 # ...
128 # set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
129 # set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
130 #
131 # check_required_components(Foo)
132 
133 #=============================================================================
134 # Copyright 2012 Alexander Neundorf <neundorf@kde.org>
135 #
136 # CMake - Cross Platform Makefile Generator
137 # Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
138 # All rights reserved.
139 #
140 # Redistribution and use in source and binary forms, with or without
141 # modification, are permitted provided that the following conditions
142 # are met:
143 #
144 # * Redistributions of source code must retain the above copyright
145 # notice, this list of conditions and the following disclaimer.
146 #
147 # * Redistributions in binary form must reproduce the above copyright
148 # notice, this list of conditions and the following disclaimer in the
149 # documentation and/or other materials provided with the distribution.
150 #
151 # * Neither the names of Kitware, Inc., the Insight Software Consortium,
152 # nor the names of their contributors may be used to endorse or promote
153 # products derived from this software without specific prior written
154 # permission.
155 #
156 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
157 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
158 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
159 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
160 # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
162 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
163 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
164 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
165 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
166 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
167 #
168 # ------------------------------------------------------------------------------
169 #
170 # The above copyright and license notice applies to distributions of
171 # CMake in source and binary form. Some source files contain additional
172 # notices of original copyright by their contributors; see each source
173 # for details. Third-party software packages supplied with CMake under
174 # compatible licenses provide their own copyright notices documented in
175 # corresponding subdirectories.
176 #
177 #------------------------------------------------------------------------------
178 #
179 # CMake was initially developed by Kitware with the following sponsorship:
180 #
181 # * National Library of Medicine at the National Institutes of Health
182 # as part of the Insight Segmentation and Registration Toolkit (ITK).
183 #
184 # * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
185 # Visualization Initiative.
186 #
187 # * National Alliance for Medical Image Computing (NAMIC) is funded by the
188 # National Institutes of Health through the NIH Roadmap for Medical Research,
189 # Grant U54 EB005149.
190 #
191 # * Kitware, Inc.
192 #=============================================================================
193 
194 include(CMakeParseArguments)
195 
196 function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
197  set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
198  set(oneValueArgs INSTALL_DESTINATION )
199  set(multiValueArgs PATH_VARS )
200 
201  cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
202 
203  if(CCF_UNPARSED_ARGUMENTS)
204  message(FATAL_ERROR "Unknown keywords given to CONFIGURE_PACKAGE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"")
205  endif()
206 
207  if(NOT CCF_INSTALL_DESTINATION)
208  message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()")
209  endif()
210 
211  if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}")
212  set(absInstallDir "${CCF_INSTALL_DESTINATION}")
213  else()
214  set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
215  endif()
216 
217  file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
218 
219  foreach(var ${CCF_PATH_VARS})
220  if(NOT DEFINED ${var})
221  message(FATAL_ERROR "Variable ${var} does not exist")
222  else()
223  if(IS_ABSOLUTE "${${var}}")
224  string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
225  PACKAGE_${var} "${${var}}")
226  else()
227  set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
228  endif()
229  endif()
230  endforeach()
231 
232  get_filename_component(inputFileName "${_inputFile}" NAME)
233 
234  set(PACKAGE_INIT "
235 ####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
236 ####### Any changes to this file will be overwritten by the next CMake run ####
237 ####### The input file was ${inputFileName} ########
238 
239 get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
240 ")
241 
242  if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
243  # Handle "/usr move" symlinks created by some Linux distros.
244  set(PACKAGE_INIT "${PACKAGE_INIT}
245 # Use original install prefix when loaded through a \"/usr move\"
246 # cross-prefix symbolic link such as /lib -> /usr/lib.
247 get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH)
248 get_filename_component(_realOrig \"${absInstallDir}\" REALPATH)
249 if(_realCurr STREQUAL _realOrig)
250  set(PACKAGE_PREFIX_DIR \"${CMAKE_INSTALL_PREFIX}\")
251 endif()
252 unset(_realOrig)
253 unset(_realCurr)
254 ")
255  endif()
256 
257  if(NOT CCF_NO_SET_AND_CHECK_MACRO)
258  set(PACKAGE_INIT "${PACKAGE_INIT}
259 macro(set_and_check _var _file)
260  set(\${_var} \"\${_file}\")
261  if(NOT EXISTS \"\${_file}\")
262  message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\")
263  endif()
264 endmacro()
265 ")
266  endif()
267 
268 
269  if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO)
270  set(PACKAGE_INIT "${PACKAGE_INIT}
271 macro(check_required_components _NAME)
272  foreach(comp \${\${_NAME}_FIND_COMPONENTS})
273  if(NOT \${_NAME}_\${comp}_FOUND)
274  if(\${_NAME}_FIND_REQUIRED_\${comp})
275  set(\${_NAME}_FOUND FALSE)
276  endif()
277  endif()
278  endforeach()
279 endmacro()
280 ")
281  endif()
282 
283  set(PACKAGE_INIT "${PACKAGE_INIT}
284 ####################################################################################")
285 
286  configure_file("${_inputFile}" "${_outputFile}" @ONLY)
287 
288 endfunction()
CONFIGURE_PACKAGE_CONFIG_FILE(_inputFile, _outputFile)