InstallationTools.cmake
Go to the documentation of this file.
00001 ############################################################################## 00002 # @file InstallationTools.cmake 00003 # @brief CMake functions used for installation. 00004 # 00005 # Copyright (c) 2011, 2012 University of Pennsylvania. All rights reserved.<br /> 00006 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file. 00007 # 00008 # Contact: SBIA Group <sbia-software at uphs.upenn.edu> 00009 # 00010 # @ingroup CMakeTools 00011 ############################################################################## 00012 00013 ## @addtogroup CMakeUtilities 00014 # @{ 00015 00016 00017 # ============================================================================ 00018 # Installation 00019 # ============================================================================ 00020 00021 # ---------------------------------------------------------------------------- 00022 ## @brief Specify rules to run at install time. 00023 # 00024 # This function replaces CMake's 00025 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:install"> 00026 # install()</a> command. 00027 # 00028 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:install 00029 # 00030 # @ingroup CMakeAPI 00031 function (basis_install) 00032 install (${ARGN}) 00033 endfunction () 00034 00035 # ---------------------------------------------------------------------------- 00036 ## @brief Install content of source directory excluding typical files. 00037 # 00038 # Files which are excluded are typical backup files, system files, files 00039 # from revision control systems, and CMakeLists.txt files. 00040 # 00041 # Example: 00042 # @code 00043 # basis_install_directory("${INSTALL_DATA_DIR}") 00044 # basis_install_directory(. "${INSTALL_DATA_DIR}") 00045 # basis_install_directory("${CMAKE_CURRENT_SOURCE_DIR}" "${INSTALL_DATA_DIR}") 00046 # basis_install_directory(images "${INSTALL_DATA_DIR}/images") 00047 # @endcode 00048 # 00049 # @param [in] ARGN The first two arguments are extracted from the beginning 00050 # of this list in the named order (without option name), 00051 # and the remaining arguments are passed on to CMake's 00052 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:install"> 00053 # <tt>install(DIRECTORY)</tt></a> command. 00054 # @par 00055 # <table border="0"> 00056 # <tr> 00057 # @tp @b SOURCE @endtp 00058 # <td>Source directory. Defaults to current source directory 00059 # if only one argument, the @p DESTINATION, is given./td> 00060 # </tr> 00061 # <tr> 00062 # @tp @b DESTINATION @endtp 00063 # <td>Destination directory.</td> 00064 # </tr> 00065 # </table> 00066 # 00067 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:install 00068 # 00069 # @ingroup CMakeAPI 00070 function (basis_install_directory) 00071 if (ARGC EQUAL 1) 00072 set (SOURCE "${CMAKE_CURRENT_SOURCE_DIR}") 00073 set (DESTINATION "${ARGV0}") 00074 set (OPTIONS "${ARGV}") 00075 list (REMOVE_AT OPTIONS 0) 00076 elseif (ARGC GREATER 1) 00077 set (SOURCE "${ARGV0}") 00078 set (DESTINATION "${ARGV1}") 00079 set (OPTIONS "${ARGV}") 00080 list (REMOVE_AT OPTIONS 0 1) 00081 else () 00082 message (FATAL_ERROR "Too few arguments given!") 00083 endif () 00084 # check arguments 00085 if (NOT IS_ABSOLUTE "${SOURCE}") 00086 get_filename_component (SOURCE "${SOURCE}" ABSOLUTE) 00087 endif () 00088 string (REGEX REPLACE "/+$" "" SOURCE "${SOURCE}") 00089 if (NOT IS_ABSOLUTE "${DESTINATION}") 00090 set (DESTINATION "${CMAKE_INSTALL_PREFIX}/${DESTINATION}") 00091 endif () 00092 basis_sanitize_for_regex (PROJECT_SOURCE_DIR_RE "${PROJECT_SOURCE_DIR}") 00093 if ("${DESTINATION}" MATCHES "^${PROJECT_SOURCE_DIR_RE}") 00094 message (FATAL_ERROR "Installation directory ${DESTINATION} is inside the project source tree!") 00095 endif () 00096 # parse options 00097 set (MATCH) 00098 set (EXCLUDE) 00099 set (COMPONENT) 00100 set (CONFIGURATIONS) 00101 set (RE) 00102 set (OPT) 00103 set (NUM) 00104 foreach (O IN LISTS OPTIONS) 00105 if (O MATCHES "^(FILES_MATCHING|.*PERMISSIONS|OPTIONAL|DESTINATION|DIRECTORY)$") 00106 message (FATAL_ERROR "Option ${O} not supported by basis_install_directory()!") 00107 endif () 00108 if (OPT MATCHES "^(PATTERN|REGEX)$") 00109 if (NUM EQUAL 1) 00110 if (O MATCHES "^EXCLUDE$") 00111 list (APPEND EXCLUDE "${RE}") 00112 else () 00113 list (APPEND MATCH "${RE}") 00114 endif () 00115 set (OPT) 00116 set (RE) 00117 else () 00118 if (OPT MATCHES "PATTERN") 00119 string (REGEX REPLACE "(^|[^\\])\\*" "☆" O "${O}") 00120 basis_sanitize_for_regex (O "${O}") 00121 string (REPLACE "☆" ".*" O "${O}") 00122 endif () 00123 set (RE "${O}") 00124 set (NUM 1) 00125 endif () 00126 elseif (OPT MATCHES "^COMPONENT$") 00127 set (COMPONENT "${O}") 00128 set (OPT) 00129 elseif (OPT MATCHES "^CONFIGURATIONS$") 00130 if (O MATCHES "^(PATTERN|REGEX|COMPONENT|CONFIGURATIONS)$") 00131 set (OPT) 00132 else () 00133 list (APPEND CONFIGURATIONS "${O}") 00134 math (EXPR NUM "${NUM} + 1") 00135 endif () 00136 endif () 00137 if (O MATCHES "^(PATTERN|REGEX|COMPONENT|CONFIGURATIONS)$") 00138 if (OPT) 00139 message (FATAL_ERROR "basis_install_directory(): Option ${OPT} is missing an argument!") 00140 endif () 00141 set (OPT ${O}) 00142 set (NUM 0) 00143 endif () 00144 endforeach () 00145 if (OPT MATCHES "CONFIGURATIONS" AND NOT NUM GREATER 0) 00146 message (FATAL_ERROR "basis_install_directory(): Missing argument(s) for ${OPT} option!") 00147 elseif (OPT MATCHES "PATTERN|REGEX") 00148 if (NUM EQUAL 1) 00149 list (APPEND MATCH "${RE}") 00150 else () 00151 message (FATAL_ERROR "basis_install_directory(): Missing argument(s) for ${OPT} option!") 00152 endif () 00153 elseif (OPT MATCHES "COMPONENT") 00154 message (FATAL_ERROR "basis_install_directory(): Missing argument for ${OPT} option!") 00155 endif () 00156 list (APPEND EXCLUDE "CMakeLists.txt$" "/.svn/" "/.git/" ".DS_Store$" ".*~$") # default excludes 00157 basis_list_to_delimited_string (MATCH "|" NOAUTOQUOTE ${MATCH}) 00158 basis_list_to_delimited_string (EXCLUDE "|" NOAUTOQUOTE ${EXCLUDE}) 00159 string (REPLACE "\\" "\\\\" MATCH "${MATCH}") 00160 string (REPLACE "\"" "\\\"" MATCH "${MATCH}") 00161 string (REPLACE "\\" "\\\\" EXCLUDE "${EXCLUDE}") 00162 string (REPLACE "\"" "\\\"" EXCLUDE "${EXCLUDE}") 00163 # Add installation instructions. Note that install(DIRECTORY) is here not 00164 # used to avoid the generation of empty directories 00165 set (OPTIONS) 00166 if (CONFIGURATIONS) 00167 list (APPEND OPTIONS CONFIGURATIONS ${CONFIGURATIONS}) 00168 endif () 00169 if (COMPONENT) 00170 list (APPEND OPTIONS COMPONENT ${COMPONENT}) 00171 endif () 00172 install (CODE 00173 "# ----------------------------------------------------------------------- 00174 # basis_install_directory(): ${SOURCE} 00175 set (BASIS_INSTALL_DIRECTORY_FILES) 00176 set (BASIS_INSTALL_DIRECTORY_SOURCE \"${SOURCE}\") 00177 set (BASIS_INSTALL_DIRECTORY_DESTINATION \"\$ENV{DESTDIR}${DESTINATION}\") 00178 set (BASIS_INSTALL_DIRECTORY_MATCH \"${MATCH}\") 00179 set (BASIS_INSTALL_DIRECTORY_EXCLUDE \"${EXCLUDE}\") 00180 file (GLOB_RECURSE BASIS_INSTALL_DIRECTORY_ALL_FILES \"\${BASIS_INSTALL_DIRECTORY_SOURCE}/*\") 00181 foreach (BASIS_INSTALL_DIRECTORY_FILE IN LISTS BASIS_INSTALL_DIRECTORY_ALL_FILES) 00182 if (NOT BASIS_INSTALL_DIRECTORY_MATCH OR 00183 BASIS_INSTALL_DIRECTORY_FILE MATCHES \"\${BASIS_INSTALL_DIRECTORY_MATCH}\" AND 00184 NOT BASIS_INSTALL_DIRECTORY_FILE MATCHES \"\${BASIS_INSTALL_DIRECTORY_EXCLUDE}\") 00185 list (APPEND BASIS_INSTALL_DIRECTORY_FILES \"\${BASIS_INSTALL_DIRECTORY_FILE}\") 00186 endif () 00187 endforeach () 00188 foreach (BASIS_INSTALL_DIRECTORY_FILE IN LISTS BASIS_INSTALL_DIRECTORY_FILES) 00189 file (RELATIVE_PATH BASIS_INSTALL_DIRECTORY_FILE \"\${BASIS_INSTALL_DIRECTORY_SOURCE}\" \"\${BASIS_INSTALL_DIRECTORY_FILE}\") 00190 execute_process ( 00191 COMMAND \"${CMAKE_COMMAND}\" -E compare_files 00192 \"\${BASIS_INSTALL_DIRECTORY_SOURCE}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 00193 \"\${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 00194 RESULT_VARIABLE RC 00195 OUTPUT_QUIET 00196 ERROR_QUIET 00197 ) 00198 if (RC EQUAL 0) 00199 message (STATUS \"Up-to-date: \${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 00200 else () 00201 message (STATUS \"Installing: \${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 00202 execute_process ( 00203 COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different 00204 \"\${BASIS_INSTALL_DIRECTORY_SOURCE}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 00205 \"\${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 00206 RESULT_VARIABLE RC 00207 OUTPUT_QUIET 00208 ERROR_QUIET 00209 ) 00210 if (RC EQUAL 0) 00211 list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 00212 else () 00213 message (STATUS \"Failed to install \${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 00214 endif () 00215 endif () 00216 endforeach () 00217 # -----------------------------------------------------------------------" 00218 ${OPTIONS} 00219 ) 00220 endfunction () 00221 00222 # ---------------------------------------------------------------------------- 00223 ## @brief Add installation rule to create a symbolic link. 00224 # 00225 # Note that the installation rule will only be effective on a Unix-like 00226 # system, i.e., one which supports the creation of a symbolic link. 00227 # 00228 # @param [in] OLD The value of the symbolic link. 00229 # @param [in] NEW The name of the symbolic link. 00230 # 00231 # @returns Adds installation rule to create the symbolic link @p NEW. 00232 # 00233 # @ingroup CMakeAPI 00234 function (basis_install_link OLD NEW) 00235 # Attention: CMAKE_INSTALL_PREFIX must be used instead of CMAKE_INSTALL_PREFIX. 00236 set (CMD_IN 00237 " 00238 set (OLD \"@OLD@\") 00239 set (NEW \"@NEW@\") 00240 00241 if (NOT IS_ABSOLUTE \"\${OLD}\") 00242 set (OLD \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${OLD}\") 00243 endif () 00244 if (NOT IS_ABSOLUTE \"\${NEW}\") 00245 set (NEW \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${NEW}\") 00246 endif () 00247 00248 if (IS_SYMLINK \"\${NEW}\") 00249 file (REMOVE \"\${NEW}\") 00250 endif () 00251 00252 if (EXISTS \"\${NEW}\") 00253 message (STATUS \"Skipping: \${NEW} -> \${OLD}\") 00254 else () 00255 message (STATUS \"Installing: \${NEW} -> \${OLD}\") 00256 00257 get_filename_component (SYMDIR \"\${NEW}\" PATH) 00258 00259 file (RELATIVE_PATH OLD \"\${SYMDIR}\" \"\${OLD}\") 00260 00261 if (NOT EXISTS \${SYMDIR}) 00262 file (MAKE_DIRECTORY \"\${SYMDIR}\") 00263 endif () 00264 00265 execute_process ( 00266 COMMAND \"${CMAKE_COMMAND}\" -E create_symlink \"\${OLD}\" \"\${NEW}\" 00267 RESULT_VARIABLE RETVAL 00268 ) 00269 00270 if (NOT RETVAL EQUAL 0) 00271 message (ERROR \"Failed to create (symbolic) link \${NEW} -> \${OLD}\") 00272 else () 00273 list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${NEW}\") 00274 endif () 00275 endif () 00276 " 00277 ) 00278 00279 string (CONFIGURE "${CMD_IN}" CMD @ONLY) 00280 install (CODE "${CMD}") 00281 endfunction () 00282 00283 # ---------------------------------------------------------------------------- 00284 ## @brief Adds installation rules to create default symbolic links. 00285 # 00286 # This function creates for each main executable a symbolic link directly 00287 # in the directory @c INSTALL_PREFIX/bin if @c INSTALL_SINFIX is TRUE and the 00288 # software is installed on a Unix-like system, i.e., one which 00289 # supports the creation of symbolic links. 00290 # 00291 # @returns Adds installation command for creation of symbolic links in the 00292 # installation tree. 00293 function (basis_install_links) 00294 if (NOT UNIX) 00295 return () 00296 endif () 00297 00298 # main executables 00299 basis_get_project_property (TARGETS PROPERTY TARGETS) 00300 foreach (TARGET_UID ${TARGETS}) 00301 get_target_property (IMPORTED ${TARGET_UID} "IMPORTED") 00302 00303 if (NOT IMPORTED) 00304 get_target_property (BASIS_TYPE ${TARGET_UID} "BASIS_TYPE") 00305 get_target_property (LIBEXEC ${TARGET_UID} "LIBEXEC") 00306 get_target_property (TEST ${TARGET_UID} "TEST") 00307 00308 if (BASIS_TYPE MATCHES "EXECUTABLE" AND NOT LIBEXEC AND NOT TEST) 00309 get_target_property (SYMLINK_NAME ${TARGET_UID} "SYMLINK_NAME") 00310 if (NOT "${SYMLINK_NAME}" MATCHES "^none$|^None$|^NONE$") 00311 get_target_property (SYMLINK_PREFIX ${TARGET_UID} "SYMLINK_PREFIX") 00312 get_target_property (SYMLINK_SUFFIX ${TARGET_UID} "SYMLINK_SUFFIX") 00313 get_target_property (INSTALL_DIR ${TARGET_UID} "RUNTIME_INSTALL_DIRECTORY") 00314 if (NOT INSTALL_DIR) 00315 get_target_property (INSTALL_DIR ${TARGET_UID} "INSTALL_DIRECTORY") 00316 endif () 00317 00318 basis_get_target_location (OUTPUT_NAME ${TARGET_UID} NAME) 00319 00320 if (NOT SYMLINK_NAME) 00321 set (SYMLINK_NAME "${OUTPUT_NAME}") 00322 endif () 00323 if (SYMLINK_PREFIX) 00324 set (SYMLINK_NAME "${SYMLINK_PREFIX}${SYMLINK_NAME}") 00325 endif () 00326 if (SYMLINK_SUFFIX) 00327 set (SYMLINK_NAME "${SYMLINK_NAME}${SYMLINK_SUFFIX}") 00328 endif () 00329 00330 # avoid creation of symbolic link if there would be a conflict with 00331 # the subdirectory in bin/ where the actual executables are installed 00332 if (INSTALL_SINFIX AND "${SYMLINK_NAME}" STREQUAL "${BASIS_INSALL_SINFIX}") 00333 message (STATUS \"Skipping: ${INSTALL_DIR}/${OUTPUT_NAME} -> ${INSTALL_PREFIX}/bin/${SYMLINK_NAME}\") 00334 else () 00335 basis_install_link ( 00336 "${INSTALL_DIR}/${OUTPUT_NAME}" 00337 "bin/${SYMLINK_NAME}" 00338 ) 00339 endif () 00340 endif () 00341 endif () 00342 endif () 00343 endforeach () 00344 endfunction () 00345 00346 # ============================================================================ 00347 # Package registration 00348 # ============================================================================ 00349 00350 # ---------------------------------------------------------------------------- 00351 ## @brief Register installed package with CMake. 00352 # 00353 # This function adds an entry to the CMake registry for packages with the 00354 # path of the directory where the package configuration file is located in 00355 # order to help CMake find the package. 00356 # 00357 # The uninstaller whose template can be found in cmake_uninstaller.cmake.in 00358 # is responsible for removing the registry entry again. 00359 function (basis_register_package) 00360 set (PKGDIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CONFIG_DIR}") 00361 set (PKGUID "${BASIS_PROJECT_PACKAGE_UID}") 00362 if (WIN32) 00363 install (CODE 00364 "execute_process ( 00365 COMMAND reg add \"HKCU\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PROJECT_PACKAGE_CONFIG_PREFIX}\" /v \"${PKGUID}\" /d \"${PKGDIR}\" /t REG_SZ /f 00366 RESULT_VARIABLE RT 00367 ERROR_VARIABLE ERR 00368 OUTPUT_QUIET 00369 ) 00370 if (RT EQUAL 0) 00371 message (STATUS \"Register: Added HKEY_CURRENT_USER\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PROJECT_PACKAGE_CONFIG_PREFIX}\\\\${PKGUID}\") 00372 else () 00373 string (STRIP \"\${ERR}\" ERR) 00374 message (STATUS \"Register: Failed to add registry entry: \${ERR}\") 00375 endif ()" 00376 ) 00377 elseif (IS_DIRECTORY "$ENV{HOME}") 00378 file (WRITE "${PROJECT_BINARY_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}RegistryFile" "${PKGDIR}") 00379 install ( 00380 FILES "${PROJECT_BINARY_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}RegistryFile" 00381 DESTINATION "$ENV{HOME}/.cmake/packages/${PROJECT_PACKAGE_CONFIG_PREFIX}" 00382 RENAME "${PKGUID}" 00383 ) 00384 endif () 00385 endfunction () 00386 00387 # ============================================================================ 00388 # Deinstallation 00389 # ============================================================================ 00390 00391 # ---------------------------------------------------------------------------- 00392 ## @brief Add uninstall target. 00393 # 00394 # @returns Adds the custom target @c uninstall and code to 00395 # <tt>cmake_install.cmake</tt> to install an uninstaller. 00396 function (basis_add_uninstall) 00397 # add uninstall target 00398 configure_file ( 00399 ${BASIS_MODULE_PATH}/cmake_uninstall.cmake.in 00400 ${PROJECT_BINARY_DIR}/cmake_uninstall.cmake 00401 @ONLY 00402 ) 00403 add_custom_target ( 00404 uninstall 00405 COMMAND ${CMAKE_COMMAND} -P "${PROJECT_BINARY_DIR}/cmake_uninstall.cmake" 00406 COMMENT "Uninstalling..." 00407 ) 00408 endfunction () 00409 00410 00411 ## @} 00412 # end of Doxygen group