Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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)