1 # ============================================================================ 2 # Copyright (c) 2011-2012 University of Pennsylvania 3 # Copyright (c) 2013-2016 Andreas Schuh 6 # See COPYING file for license information or visit 7 # https://cmake-basis.github.io/download.html#license 8 # ============================================================================ 10 ############################################################################## 11 # @file InstallationTools.cmake 12 # @brief CMake functions used for installation. 15 ############################################################################## 17 # ---------------------------------------------------------------------------- 26 ## @addtogroup CMakeUtilities 30 # ============================================================================ 32 # ============================================================================ 34 # ---------------------------------------------------------------------------- 35 ## @brief Specify rules to run at install time. 37 # This function replaces CMake's 38 # <a href="https://cmake.org/cmake/help/v3.5/command/install.html">install()</a> command. 40 # @sa https://cmake.org/cmake/help/v3.5/command/install.html 44 include(CMakeParseArguments)
45 cmake_parse_arguments (ARGN
"" "DIRECTORY" "TARGETS;FILES;PROGRAMS" ${ARGN})
46 set (_errmsg
"Options TARGETS, FILES, PROGRAMS, and DIRECTORY are mutually exclusive!")
48 if (ARGN_FILES OR ARGN_PROGRAMS OR ARGN_TARGETS)
49 message (FATAL_ERROR
"${_errmsg}")
51 install (DIRECTORY ${ARGN_DIRECTORY} ${ARGN_UNPARSED_ARGUMENTS})
53 if (ARGN_PROGRAMS OR ARGN_TARGETS OR ARGN_DIRECTORY)
54 message (FATAL_ERROR
"${_errmsg}")
56 install (FILES ${ARGN_FILES} ${ARGN_UNPARSED_ARGUMENTS})
57 elseif (ARGN_PROGRAMS)
58 if (ARGN_FILES OR ARGN_TARGETS OR ARGN_DIRECTORY)
59 message (FATAL_ERROR
"${_errmsg}")
61 install (PROGRAMS ${ARGN_PROGRAMS} ${ARGN_UNPARSED_ARGUMENTS})
63 if (ARGN_FILES OR ARGN_PROGRAMS OR ARGN_DIRECTORY)
64 message (FATAL_ERROR
"${_errmsg}")
66 install (TARGETS ${ARGN_TARGETS} ${ARGN_UNPARSED_ARGUMENTS})
68 install (${ARGN_UNPARSED_ARGUMENTS})
72 # ---------------------------------------------------------------------------- 73 ## @brief Install content of source directory excluding typical files. 75 # Files which are excluded are typical backup files, system files, files 76 # from revision control systems, and CMakeLists.txt files. 80 # basis_install_directory("${INSTALL_DATA_DIR}") 81 # basis_install_directory(. "${INSTALL_DATA_DIR}") 82 # basis_install_directory("${CMAKE_CURRENT_SOURCE_DIR}" "${INSTALL_DATA_DIR}") 83 # basis_install_directory(images "${INSTALL_DATA_DIR}/images") 86 # @param [in] ARGN The first two arguments are extracted from the beginning 87 # of this list in the named order (without option name), 88 # and the remaining arguments are passed on to CMake's 89 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:install"> 90 # <tt>install(DIRECTORY)</tt></a> command. 94 # @tp @b SOURCE @endtp 95 # <td>Source directory. Defaults to current source directory 96 # if only one argument, the @p DESTINATION, is given./td> 99 # @tp @b DESTINATION @endtp 100 # <td>Destination directory.</td> 104 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:install 109 set (SOURCE
"${CMAKE_CURRENT_SOURCE_DIR}")
110 set (DESTINATION
"${ARGV0}")
111 set (OPTIONS
"${ARGV}")
112 list (REMOVE_AT OPTIONS 0)
113 elseif (ARGC GREATER 1)
114 set (SOURCE
"${ARGV0}")
115 set (DESTINATION
"${ARGV1}")
116 set (OPTIONS
"${ARGV}")
117 list (REMOVE_AT OPTIONS 0 1)
119 message (FATAL_ERROR
"Too few arguments given!")
122 if (NOT IS_ABSOLUTE
"${SOURCE}")
125 string (REGEX REPLACE
"/+$" "" SOURCE
"${SOURCE}")
126 if (NOT IS_ABSOLUTE
"${DESTINATION}")
127 set (DESTINATION
"${CMAKE_INSTALL_PREFIX}/${DESTINATION}")
130 if (
"${DESTINATION}" MATCHES
"^${PROJECT_SOURCE_DIR_RE}(/|$)")
131 message (FATAL_ERROR
"Installation directory ${DESTINATION} is inside the project source tree!")
141 foreach (O IN LISTS OPTIONS)
142 if (O MATCHES
"^(FILES_MATCHING|.*PERMISSIONS|OPTIONAL|DESTINATION|DIRECTORY)$")
143 message (FATAL_ERROR
"Option ${O} not supported by basis_install_directory()!")
145 if (OPT MATCHES
"^(PATTERN|REGEX)$")
147 if (O MATCHES
"^EXCLUDE$")
148 list (APPEND EXCLUDE
"${RE}")
150 list (APPEND MATCH
"${RE}")
155 if (OPT MATCHES
"PATTERN")
156 string (REGEX REPLACE
"(^|[^\\])\\*" "☆" O
"${O}")
158 string (REPLACE
"☆" ".*" O
"${O}")
163 elseif (OPT MATCHES
"^COMPONENT$")
164 set (COMPONENT
"${O}")
166 elseif (OPT MATCHES
"^CONFIGURATIONS$")
167 if (O MATCHES
"^(PATTERN|REGEX|COMPONENT|CONFIGURATIONS)$")
170 list (APPEND CONFIGURATIONS
"${O}")
171 math (EXPR NUM
"${NUM} + 1")
174 if (O MATCHES
"^(PATTERN|REGEX|COMPONENT|CONFIGURATIONS)$")
176 message (FATAL_ERROR
"basis_install_directory(): Option ${OPT} is missing an argument!")
182 if (OPT MATCHES
"CONFIGURATIONS" AND NOT NUM GREATER 0)
183 message (FATAL_ERROR
"basis_install_directory(): Missing argument(s) for ${OPT} option!")
184 elseif (OPT MATCHES
"PATTERN|REGEX")
186 list (APPEND MATCH
"${RE}")
188 message (FATAL_ERROR
"basis_install_directory(): Missing argument(s) for ${OPT} option!")
190 elseif (OPT MATCHES
"COMPONENT")
191 message (FATAL_ERROR
"basis_install_directory(): Missing argument for ${OPT} option!")
193 list (APPEND EXCLUDE
"CMakeLists.txt$" "/.svn/" "/.git/" ".DS_Store$" ".*~$")
# default excludes 196 string (REPLACE
"\\" "\\\\" MATCH
"${MATCH}")
197 string (REPLACE
"\"" "\\\"" MATCH
"${MATCH}")
198 string (REPLACE
"\\" "\\\\" EXCLUDE
"${EXCLUDE}")
199 string (REPLACE
"\"" "\\\"" EXCLUDE
"${EXCLUDE}")
200 # Add installation instructions. Note that install(DIRECTORY) is here not 201 # used to avoid the generation of empty directories 204 list (APPEND OPTIONS CONFIGURATIONS ${CONFIGURATIONS})
207 list (APPEND OPTIONS COMPONENT ${COMPONENT})
210 "# ----------------------------------------------------------------------- 211 # basis_install_directory(): ${SOURCE} 212 set (BASIS_INSTALL_DIRECTORY_FILES) 213 set (BASIS_INSTALL_DIRECTORY_SOURCE \"${SOURCE}\") 214 set (BASIS_INSTALL_DIRECTORY_DESTINATION \"\$ENV{DESTDIR}${DESTINATION}\") 215 set (BASIS_INSTALL_DIRECTORY_MATCH \"${MATCH}\") 216 set (BASIS_INSTALL_DIRECTORY_EXCLUDE \"${EXCLUDE}\") 217 file (GLOB_RECURSE BASIS_INSTALL_DIRECTORY_ALL_FILES \"\${BASIS_INSTALL_DIRECTORY_SOURCE}/*\") 218 foreach (BASIS_INSTALL_DIRECTORY_FILE IN LISTS BASIS_INSTALL_DIRECTORY_ALL_FILES) 219 if (NOT BASIS_INSTALL_DIRECTORY_MATCH OR 220 BASIS_INSTALL_DIRECTORY_FILE MATCHES \"\${BASIS_INSTALL_DIRECTORY_MATCH}\" AND 221 NOT BASIS_INSTALL_DIRECTORY_FILE MATCHES \"\${BASIS_INSTALL_DIRECTORY_EXCLUDE}\") 222 list (APPEND BASIS_INSTALL_DIRECTORY_FILES \"\${BASIS_INSTALL_DIRECTORY_FILE}\") 225 foreach (BASIS_INSTALL_DIRECTORY_FILE IN LISTS BASIS_INSTALL_DIRECTORY_FILES) 226 file (RELATIVE_PATH BASIS_INSTALL_DIRECTORY_FILE \"\${BASIS_INSTALL_DIRECTORY_SOURCE}\" \"\${BASIS_INSTALL_DIRECTORY_FILE}\") 228 COMMAND \"${CMAKE_COMMAND}\" -E compare_files 229 \"\${BASIS_INSTALL_DIRECTORY_SOURCE}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 230 \"\${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 236 message (STATUS \"Up-to-date: \${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 238 message (STATUS \"Installing: \${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 240 COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different 241 \"\${BASIS_INSTALL_DIRECTORY_SOURCE}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 242 \"\${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\" 248 list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 250 message (STATUS \"Failed to install \${BASIS_INSTALL_DIRECTORY_DESTINATION}/\${BASIS_INSTALL_DIRECTORY_FILE}\") 254 # -----------------------------------------------------------------------" 259 # ---------------------------------------------------------------------------- 260 ## @brief Add installation rule for project template. 262 if (NOT IS_ABSOLUTE
"${TEMPLATE}")
263 set (
TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/${TEMPLATE}")
266 DIRECTORY
"${TEMPLATE}/" 267 DESTINATION
"${DESTINATION}" 272 PATTERN .DS_Store EXCLUDE
276 # ---------------------------------------------------------------------------- 277 ## @brief Add installation rule to create a symbolic link. 279 # Note that the installation rule will only be effective on a Unix-like 280 # system, i.e., one which supports the creation of a symbolic link. 282 # @param [in] OLD The value of the symbolic link. 283 # @param [in] NEW The name of the symbolic link. 285 # @returns Adds installation rule to create the symbolic link @p NEW. 294 if (NOT IS_ABSOLUTE \"\${OLD}\") 295 set (OLD \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${OLD}\") 297 if (NOT IS_ABSOLUTE \"\${NEW}\") 298 set (NEW \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${NEW}\") 301 if (IS_SYMLINK \"\${NEW}\") 302 file (REMOVE \"\${NEW}\") 305 if (EXISTS \"\${NEW}\") 306 message (STATUS \"Skipping: \${NEW} -> \${OLD}\") 308 message (STATUS \"Installing: \${NEW} -> \${OLD}\") 310 get_filename_component (SYMDIR \"\${NEW}\" PATH) 312 file (RELATIVE_PATH OLD \"\${SYMDIR}\" \"\${OLD}\") 314 if (NOT EXISTS \${SYMDIR}) 315 file (MAKE_DIRECTORY \"\${SYMDIR}\") 319 COMMAND \"${CMAKE_COMMAND}\" -E create_symlink \"\${OLD}\" \"\${NEW}\" 320 RESULT_VARIABLE RETVAL 323 if (NOT RETVAL EQUAL 0) 324 message (ERROR \"Failed to create (symbolic) link \${NEW} -> \${OLD}\") 326 list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${NEW}\") 332 string (CONFIGURE
"${CMD_IN}" CMD @ONLY)
333 install (CODE
"${CMD}")
336 # ---------------------------------------------------------------------------- 337 ## @brief Adds installation rules to create default symbolic links. 339 # This function creates for each main executable a symbolic link directly 340 # in the directory @c INSTALL_PREFIX/bin if @c INSTALL_SINFIX is TRUE and the 341 # software is installed on a Unix-like system, i.e., one which 342 # supports the creation of symbolic links. 344 # @returns Adds installation command for creation of symbolic links in the 353 foreach (TARGET_UID ${TARGETS})
354 get_target_property (IMPORTED ${TARGET_UID} IMPORTED)
357 get_target_property (BASIS_TYPE ${TARGET_UID} BASIS_TYPE)
358 get_target_property (LIBEXEC ${TARGET_UID} LIBEXEC)
359 get_target_property (IS_TEST ${TARGET_UID} TEST)
361 if (BASIS_TYPE MATCHES
"EXECUTABLE" AND NOT LIBEXEC AND NOT IS_TEST)
362 get_target_property (SYMLINK_NAME ${TARGET_UID} SYMLINK_NAME)
363 if (NOT
"${SYMLINK_NAME}" MATCHES
"^none$|^None$|^NONE$")
364 get_target_property (SYMLINK_PREFIX ${TARGET_UID} SYMLINK_PREFIX)
365 get_target_property (SYMLINK_SUFFIX ${TARGET_UID} SYMLINK_SUFFIX)
366 get_target_property (INSTALL_DIR ${TARGET_UID} RUNTIME_INSTALL_DIRECTORY)
368 get_target_property (INSTALL_DIR ${TARGET_UID} INSTALL_DIRECTORY)
373 if (NOT SYMLINK_NAME)
374 set (SYMLINK_NAME
"${OUTPUT_NAME}")
377 set (SYMLINK_NAME
"${SYMLINK_PREFIX}${SYMLINK_NAME}")
380 set (SYMLINK_NAME
"${SYMLINK_NAME}${SYMLINK_SUFFIX}")
383 # avoid creation of symbolic link if there would be a conflict with 384 # the subdirectory in bin/ where the actual executables are installed 385 if (INSTALL_SINFIX AND
"${SYMLINK_NAME}" STREQUAL
"${BASIS_INSALL_SINFIX}")
386 message (STATUS \
"Skipping: ${INSTALL_DIR}/${OUTPUT_NAME} -> ${INSTALL_PREFIX}/bin/${SYMLINK_NAME}\") 389 "${INSTALL_DIR}/${OUTPUT_NAME}
" 390 "bin/${SYMLINK_NAME}
" 399 # ============================================================================ 400 # Package registration 401 # ============================================================================ 403 # ---------------------------------------------------------------------------- 404 ## @brief Register installed package with CMake. 406 # This function adds an entry to the CMake registry for packages with the 407 # path of the directory where the package configuration file is located in 408 # order to help CMake find the package. 410 # The uninstaller whose template can be found in cmake_uninstaller.cmake.in 411 # is responsible for removing the registry entry again. 412 function (basis_register_package) 418 COMMAND reg add \
"HKCU\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PROJECT_PACKAGE_CONFIG_PREFIX}\" /v \"${PKGUID}\" /d \"${PKGDIR}\" /t REG_SZ /f 424 message (STATUS \"Register: Added HKEY_CURRENT_USER\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PROJECT_PACKAGE_CONFIG_PREFIX}\\\\${PKGUID}\") 426 string (STRIP \"\${ERR}\" ERR) 427 message (STATUS \"Register: Failed to add registry entry: \${ERR}\") 430 elseif (IS_DIRECTORY
"$ENV{HOME}")
431 file (WRITE
"${BINARY_CONFIG_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}RegistryFile" "${PKGDIR}")
433 FILES
"${BINARY_CONFIG_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}RegistryFile" 434 DESTINATION
"$ENV{HOME}/.cmake/packages/${PROJECT_PACKAGE_CONFIG_PREFIX}" 440 # ============================================================================ 442 # ============================================================================ 444 # ---------------------------------------------------------------------------- 445 ## @brief Add uninstall target. 447 # @returns Adds the custom target @c uninstall and code to 448 # <tt>cmake_install.cmake</tt> to install an uninstaller. 450 # add uninstall target
452 ${BASIS_MODULE_PATH}/cmake_uninstall.cmake.in
453 ${PROJECT_BINARY_DIR}/cmake_uninstall.cmake
458 COMMAND ${CMAKE_COMMAND} -P
"${PROJECT_BINARY_DIR}/cmake_uninstall.cmake" 459 COMMENT
"Uninstalling..." 465 # end of Doxygen group cmake INSTALL_CONFIG_DIR
Path of installation directory for CMake package configuration files relative to CMAKE_INSTALL_PREFIX...
cmake CMAKE_INSTALL_PREFIX
Installation prefix, i.e., root directory of installation.
function basis_get_project_property(out VARIABLE, in ARGN)
Get project-global property value.
function basis_install()
Specify rules to run at install time.
macro basis_sanitize_for_regex(out OUT, in STR)
Sanitize string variable for use in regular expression.
cmake TOPLEVEL_PROJECT_PACKAGE_UID
UID of package in CMake's user package registry.
function basis_install_template(in TEMPLATE, in DESTINATION)
Add installation rule for project template.
function basis_add_uninstall()
Add uninstall target.
function basis_install_links()
Adds installation rules to create default symbolic links.
#define UNIX
Whether the sources are compiled on a Unix-based system.
function basis_list_to_delimited_string(out STR, in DELIM, in ARGN)
Concatenates all list elements into a single delimited string.
function basis_install_directory(in ARGN)
Install content of source directory excluding typical files.
function basis_install_link(in OLD, in NEW)
Add installation rule to create a symbolic link.
function get_filename_component(inout ARGN)
Fixes CMake's get_filename_component() command.
function basis_get_target_location(out VAR, in TARGET_NAME, in PART)
Get location of build target output file(s).