This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, next has been updated via 8f5703fd6de2bb597f4b0f1397aaf3356a82cf47 (commit) via 85ec2aa184259e1da15af73094bde6ecfc7026e3 (commit) from eb0b17c2f07271753f202b14a5e52d30f8f5430d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8f5703fd6de2bb597f4b0f1397aaf3356a82cf47 commit 8f5703fd6de2bb597f4b0f1397aaf3356a82cf47 Merge: eb0b17c 85ec2aa Author: Domen Vrankar <domen.vran...@gmail.com> AuthorDate: Sun Mar 29 14:58:06 2015 -0400 Commit: CMake Topic Stage <kwro...@kitware.com> CommitDate: Sun Mar 29 14:58:06 2015 -0400 Merge topic 'cpack-rpm-basic-symlink-handling' into next 85ec2aa1 CPack/RPM basic symlink support http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=85ec2aa184259e1da15af73094bde6ecfc7026e3 commit 85ec2aa184259e1da15af73094bde6ecfc7026e3 Author: Domen Vrankar <domen.vran...@gmail.com> AuthorDate: Sun Mar 29 20:55:20 2015 +0200 Commit: Domen Vrankar <domen.vran...@gmail.com> CommitDate: Sun Mar 29 20:55:20 2015 +0200 CPack/RPM basic symlink support RPM packages can contain symbolic links to relative paths - including support for multiple relocation paths through generation of post install relocation scripts. This is basic support with limitations described in documentation. Feature is addressing mantis bug report id 15209. diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index 162eba7..f4c853b 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -4,6 +4,43 @@ # # The builtin (binary) CPack RPM generator (Unix only) # +# Packaging of symbolic links +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +# CPackRPM supports packaging of symbolic links. +# +# :: +# +# execute_process(COMMAND ${CMAKE_COMMAND} +# -E create_symlink <relative_path_location> <symlink_name>) +# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/<symlink_name> +# DESTINATION <symlink_location> COMPONENT libraries) +# +# Symbolic links will be optimized (paths will be shortened if possible) +# before being added to the package or if multiple relocation paths are +# detected, a post install symlink relocation script will be generated. +# +# Symbolic links may point to locations that are not packaged by the same +# package (either a different component or even not packaged at all) but +# those locations will be treated as if they were a part of the package +# while determining if symlink should be either created or present in a +# post install script - depending on relocation paths. +# +# Currenty there are a few limitations though: +# +# * Only symbolic links with relative path can be packaged. +# +# * For component based packaging component interdependency is not checked +# when processing symbolic links. Symbolic links pointing to content of +# a different component are treated the same way as if pointing to location +# that will not be packaged. +# +# * Symbolic links pointing to a location through one or more intermediate +# symbolic links will not be handled differently - if the intermediate +# symbolic link(s) is also on a relocatable path, relocating it during +# package installation may cause initial symbolic link to point to an +# invalid location. +# # Variables specific to CPack RPM generator # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # @@ -503,6 +540,301 @@ function(cpack_rpm_prepare_relocation_paths) set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}" PARENT_SCOPE) endfunction() +function(cpack_rpm_symlink_get_relocation_prefixes LOCATION PACKAGE_PREFIXES RETURN_VARIABLE) + foreach(PKG_PREFIX IN LISTS PACKAGE_PREFIXES) + string(REGEX MATCH "^${PKG_PREFIX}/.*" FOUND_ "${LOCATION}") + if(FOUND_) + list(APPEND TMP_PREFIXES "${PKG_PREFIX}") + endif() + endforeach() + + set(${RETURN_VARIABLE} "${TMP_PREFIXES}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_symlink_create_relocation_script PACKAGE_PREFIXES) + list(LENGTH PACKAGE_PREFIXES LAST_INDEX) + set(SORTED_PACKAGE_PREFIXES "${PACKAGE_PREFIXES}") + list(SORT SORTED_PACKAGE_PREFIXES) + list(REVERSE SORTED_PACKAGE_PREFIXES) + math(EXPR LAST_INDEX ${LAST_INDEX}-1) + + foreach(SYMLINK_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${SYMLINK_INDEX} SRC_PATH) + list(FIND PACKAGE_PREFIXES "${SRC_PATH}" SYMLINK_INDEX) # reverse magic + string(LENGTH "${SRC_PATH}" SRC_PATH_LEN) + + set(PARTS_CNT 0) + set(SCRIPT_PART "if [ \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}\" != \"${SRC_PATH}\" ]; then\n") + + # both paths relocated + foreach(POINT_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH) + list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic + string(LENGTH "${POINT_PATH}" POINT_PATH_LEN) + + if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}) + if("${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}") + set(INDENT "") + else() + set(SCRIPT_PART "${SCRIPT_PART} if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n") + set(INDENT " ") + endif() + + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}) + math(EXPR PARTS_CNT ${PARTS_CNT}+1) + + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n") + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + set(SCRIPT_PART "${SCRIPT_PART} ${INDENT}fi\n") + endforeach() + + if(NOT "${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}") + set(SCRIPT_PART "${SCRIPT_PART} fi\n") + endif() + endif() + endforeach() + + # source path relocated + if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X) + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X) + math(EXPR PARTS_CNT ${PARTS_CNT}+1) + + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT_PART "${SCRIPT_PART} if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT_PART "${SCRIPT_PART} ln -s \"${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n") + set(SCRIPT_PART "${SCRIPT_PART} CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + set(SCRIPT_PART "${SCRIPT_PART} fi\n") + endforeach() + endif() + + if(PARTS_CNT) + set(SCRIPT "${SCRIPT_PART}") + set(SCRIPT "${SCRIPT}fi\n") + endif() + endforeach() + + # point path relocated + foreach(POINT_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH) + list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic + string(LENGTH "${POINT_PATH}" POINT_PATH_LEN) + + if(_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}) + set(SCRIPT "${SCRIPT}if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n") + + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}) + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT "${SCRIPT} if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT "${SCRIPT} ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"${SYMLINK_}\"\n") + set(SCRIPT "${SCRIPT} CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + set(SCRIPT "${SCRIPT} fi\n") + endforeach() + + set(SCRIPT "${SCRIPT}fi\n") + endif() + endforeach() + + # no path relocated + if(_RPM_RELOCATION_SCRIPT_X_X) + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_X) + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + set(SCRIPT "${SCRIPT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + set(SCRIPT "${SCRIPT} ln -s \"${POINT_}\" \"${SYMLINK_}\"\n") + set(SCRIPT "${SCRIPT}fi\n") + endforeach() + endif() + + set(RPM_SYMLINK_POSTINSTALL "${SCRIPT}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_symlink_add_for_relocation_script PACKAGE_PREFIXES SYMLINK SYMLINK_RELOCATION_PATHS POINT POINT_RELOCATION_PATHS) + list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUTN) + list(LENGTH POINT_RELOCATION_PATHS POINT_PATHS_COUNT) + + list(APPEND _RPM_RELOCATION_SCRIPT_PAIRS "${SYMLINK}:${POINT}") + list(LENGTH _RPM_RELOCATION_SCRIPT_PAIRS PAIR_NO) + + if(SYMLINK_PATHS_COUTN) + foreach(SYMLINK_RELOC_PATH IN LISTS SYMLINK_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${SYMLINK_RELOC_PATH}" SYMLINK_INDEX) + + # source path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X") + + foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX) + + # both paths relocated + list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}") + + # point path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}") + endforeach() + endforeach() + elseif(POINT_PATHS_COUNT) + foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX) + + # point path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}") + endforeach() + endif() + + # no path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_X "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_X") + + # place variables into parent scope + foreach(VAR IN LISTS RELOCATION_VARS) + set(${VAR} "${${VAR}}" PARENT_SCOPE) + endforeach() + set(_RPM_RELOCATION_SCRIPT_PAIRS "${_RPM_RELOCATION_SCRIPT_PAIRS}" PARENT_SCOPE) + set(REQUIRES_SYMLINK_RELOCATION_SCRIPT "true" PARENT_SCOPE) + set(DIRECTIVE "%ghost " PARENT_SCOPE) +endfunction() + +function(cpack_rpm_prepare_install_files INSTALL_FILES_LIST WDIR PACKAGE_PREFIXES IS_RELOCATABLE) + # Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir + # This is necessary to avoid duplicate files since rpmbuild does + # recursion on its own when encountering a pathname which is a directory + # which is not flagged as %dir + string(STRIP "${INSTALL_FILES_LIST}" INSTALL_FILES_LIST) + string(REPLACE "\n" ";" INSTALL_FILES_LIST + "${INSTALL_FILES_LIST}") + string(REPLACE "\"" "" INSTALL_FILES_LIST + "${INSTALL_FILES_LIST}") + string(LENGTH "${WDIR}" WDR_LEN_) + + list(SORT INSTALL_FILES_LIST) # make file order consistent on all platforms + + foreach(F IN LISTS INSTALL_FILES_LIST) + unset(DIRECTIVE) + + if(IS_SYMLINK "${WDIR}/${F}") + if(IS_RELOCATABLE) + # check that symlink has relocatable format + get_filename_component(SYMLINK_LOCATION_ "${WDIR}/${F}" DIRECTORY) + execute_process(COMMAND ls -la "${WDIR}/${F}" + WORKING_DIRECTORY "${WDIR}" + OUTPUT_VARIABLE SYMLINK_POINT_ + OUTPUT_STRIP_TRAILING_WHITESPACE) + + string(FIND "${SYMLINK_POINT_}" "->" SYMLINK_POINT_INDEX_ REVERSE) + math(EXPR SYMLINK_POINT_INDEX_ ${SYMLINK_POINT_INDEX_}+3) + string(LENGTH "${SYMLINK_POINT_}" SYMLINK_POINT_LENGTH_) + + # get destination path + string(SUBSTRING "${SYMLINK_POINT_}" ${SYMLINK_POINT_INDEX_} ${SYMLINK_POINT_LENGTH_} SYMLINK_POINT_) + + # check if path is relative or absolute + string(SUBSTRING "${SYMLINK_POINT_}" 0 1 SYMLINK_IS_ABSOLUTE_) + + if(${SYMLINK_IS_ABSOLUTE_} STREQUAL "/") + # prevent absolute paths from having /../ or /./ section inside of them + get_filename_component(SYMLINK_POINT_ "${SYMLINK_POINT_}" ABSOLUTE) + else() + # handle relative path + get_filename_component(SYMLINK_POINT_ "${SYMLINK_LOCATION_}/${SYMLINK_POINT_}" ABSOLUTE) + endif() + + string(SUBSTRING "${SYMLINK_POINT_}" ${WDR_LEN_} -1 SYMLINK_POINT_WD_) + + cpack_rpm_symlink_get_relocation_prefixes("${F}" "${PACKAGE_PREFIXES}" "SYMLINK_RELOCATIONS") + cpack_rpm_symlink_get_relocation_prefixes("${SYMLINK_POINT_WD_}" "${PACKAGE_PREFIXES}" "POINT_RELOCATIONS") + + list(LENGTH SYMLINK_RELOCATIONS SYMLINK_RELOCATIONS_COUNT) + list(LENGTH POINT_RELOCATIONS POINT_RELOCATIONS_COUNT) + + if(SYMLINK_RELOCATIONS_COUNT AND POINT_RELOCATIONS_COUNT) + # find matching + foreach(SYMLINK_RELOCATION_PREFIX IN LISTS SYMLINK_RELOCATIONS) + list(FIND POINT_RELOCATIONS "${SYMLINK_RELOCATION_PREFIX}" FOUND_INDEX) + if(NOT ${FOUND_INDEX} EQUAL -1) + break() + endif() + endforeach() + + if(NOT ${FOUND_INDEX} EQUAL -1) + # symlinks have the same subpath + if(${SYMLINK_RELOCATIONS_COUNT} EQUAL 1 AND ${POINT_RELOCATIONS_COUNT} EQUAL 1) + # permanent symlink + get_filename_component(SYMLINK_LOCATION_ "${F}" DIRECTORY) + file(RELATIVE_PATH FINAL_PATH_ ${SYMLINK_LOCATION_} ${SYMLINK_POINT_WD_}) + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${FINAL_PATH_}" "${WDIR}/${F}") + else() + # relocation subpaths + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + endif() + else() + # not on the same relocation path + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + endif() + elseif(POINT_RELOCATIONS_COUNT) + # point is relocatable + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + else() + # is not relocatable or points to non relocatable path - permanent symlink + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${SYMLINK_POINT_WD_}" "${WDIR}/${F}") + endif() + endif() + elseif(IS_DIRECTORY "${WDIR}/${F}") + set(DIRECTIVE "%dir ") + endif() + + set(INSTALL_FILES "${INSTALL_FILES}${DIRECTIVE}\"${F}\"\n") + endforeach() + + if(REQUIRES_SYMLINK_RELOCATION_SCRIPT) + cpack_rpm_symlink_create_relocation_script("${PACKAGE_PREFIXES}") + endif() + + set(RPM_SYMLINK_POSTINSTALL "${RPM_SYMLINK_POSTINSTALL}" PARENT_SCOPE) + set(CPACK_RPM_INSTALL_FILES "${INSTALL_FILES}" PARENT_SCOPE) +endfunction() + if(CMAKE_BINARY_DIR) message(FATAL_ERROR "CPackRPM.cmake may only be used by CPack internally.") endif() @@ -963,9 +1295,10 @@ function(cpack_rpm_generate_package) # destinct parent paths of other relocation paths and remove the # final element (so the install-prefix dir itself is not omitted # from the RPM's content-list) - list(SORT RPM_USED_PACKAGE_PREFIXES) + set(SORTED_RPM_USED_PACKAGE_PREFIXES "${RPM_USED_PACKAGE_PREFIXES}") + list(SORT SORTED_RPM_USED_PACKAGE_PREFIXES) set(_DISTINCT_PATH "NOT_SET") - foreach(_RPM_RELOCATION_PREFIX ${RPM_USED_PACKAGE_PREFIXES}) + foreach(_RPM_RELOCATION_PREFIX ${SORTED_RPM_USED_PACKAGE_PREFIXES}) if(NOT "${_RPM_RELOCATION_PREFIX}" MATCHES "${_DISTINCT_PATH}/.*") set(_DISTINCT_PATH "${_RPM_RELOCATION_PREFIX}") @@ -1142,25 +1475,13 @@ function(cpack_rpm_generate_package) set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") endif() - - # Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir - # This is necessary to avoid duplicate files since rpmbuild do - # recursion on its own when encountering a pathname which is a directory - # which is not flagged as %dir - string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) - string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST - "${CPACK_RPM_INSTALL_FILES_LIST}") - string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST - "${CPACK_RPM_INSTALL_FILES_LIST}") - set(CPACK_RPM_INSTALL_FILES "") - foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) - if(IS_DIRECTORY "${WDIR}/${F}") - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}%dir \"${F}\"\n") - else() - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") - endif() - endforeach() - set(CPACK_RPM_INSTALL_FILES_LIST "") + # Prepare install files + cpack_rpm_prepare_install_files( + "${CPACK_RPM_INSTALL_FILES}" + "${WDIR}" + "${RPM_USED_PACKAGE_PREFIXES}" + "${CPACK_RPM_PACKAGE_RELOCATABLE}" + ) # The name of the final spec file to be used by rpmbuild set(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.spec") @@ -1246,6 +1567,7 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT %clean %post +\@RPM_SYMLINK_POSTINSTALL\@ \@CPACK_RPM_SPEC_POSTINSTALL\@ %postun diff --git a/Tests/CPackComponentsForAll/CMakeLists.txt b/Tests/CPackComponentsForAll/CMakeLists.txt index 51af297..b172f83 100644 --- a/Tests/CPackComponentsForAll/CMakeLists.txt +++ b/Tests/CPackComponentsForAll/CMakeLists.txt @@ -49,6 +49,42 @@ install(FILES mylib.h DESTINATION include COMPONENT headers) +# Package symbolic links +install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three COMPONENT libraries) +install(DIRECTORY DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two/different_relocatable/bar COMPONENT libraries) +install(DIRECTORY DESTINATION other_relocatable/depth_two COMPONENT libraries) +install(DIRECTORY DESTINATION non_relocatable/depth_two COMPONENT libraries) +# test symbolic links to same dir +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink depth_three symlink_samedir_path) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) +# test symbolic links to same dir with current dir ./ prefix +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./depth_three symlink_samedir_path_current_dir) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path_current_dir DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) +# test symbolic links to same dir with longer relative path +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../../${CMAKE_INSTALL_LIBDIR}/.././${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/./depth_two/depth_three symlink_samedir_path_longer) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_samedir_path_longer DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) +# test symbolic links to sub dir +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three symlink_subdir_path) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_subdir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one COMPONENT libraries) +# test symbolic links to parent dir +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../../../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/./depth_two symlink_parentdir_path) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_parentdir_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two/depth_three COMPONENT libraries) +# test symbolic link to another relocatable path +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././.././../other_relocatable/./depth_two symlink_other_relocatable_path) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_other_relocatable_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two COMPONENT libraries) +# test symbolic link to non relocatable path +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../../non_relocatable/./depth_two symlink_to_non_relocatable_path) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_to_non_relocatable_path DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two COMPONENT libraries) +# test symbolic link from non relocatable path +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .././../${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two symlink_from_non_relocatable_path) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_from_non_relocatable_path DESTINATION non_relocatable/depth_two COMPONENT libraries) +# test symbolic link relocatable path to its relocatable subpath +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../../inside_relocatable_two/depth_two/different_relocatable/bar symlink_relocatable_subpath) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_relocatable_subpath DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) +# test symbolic link to location outside package +execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ./outside_package symlink_outside_package) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_outside_package DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) + # CPack boilerplate for this project set(CPACK_PACKAGE_NAME "MyLib") set(CPACK_PACKAGE_CONTACT "None") @@ -114,7 +150,8 @@ set(CPACK_COMPONENT_APPLICATIONS_INSTALL_TYPES Full) # can not be used in CPack scripts due to CMAKE_SIZEOF_VOID_P # variable not being set set(CPACK_RPM_RELOCATION_PATHS "${CMAKE_INSTALL_INCLUDEDIR}" - "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_BINDIR}") + "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_BINDIR}" "other_relocatable" + "${CMAKE_INSTALL_LIBDIR}/inside_relocatable_two/depth_two/different_relocatable") # We may use the CPack specific config file in order # to tailor CPack behavior on a CPack generator specific way diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake index cf4da74..e747052 100644 --- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake @@ -1,3 +1,7 @@ +# prevent older policies from interfearing with this script +cmake_policy(PUSH) +cmake_policy(VERSION ${CMAKE_VERSION}) + message(STATUS "=============================================================================") message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") message(STATUS "") @@ -138,6 +142,7 @@ if(CPackGen MATCHES "RPM") "An extremely useful application that makes use of MyLib") set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Static libraries used to build programs with MyLib") + set(LIB_SUFFIX "6?4?") # test package info if(${CPackComponentWay} STREQUAL "IgnoreGroup") @@ -174,10 +179,32 @@ if(CPackGen MATCHES "RPM") if(check_file_libraries_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_COMPONENT_LIBRARIES_DESCRIPTION}.*") - set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") + set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/other_relocatable${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable") set(check_file_match_expected_architecture "") # we don't explicitly set this value so it is different on each platform - ignore it set(spec_regex "*libraries*") - set(check_content_list "^/usr/foo/bar/lib.*\n/usr/foo/bar/lib.*/libmylib.a$") + set(check_content_list "^/usr/foo/bar/lib${LIB_SUFFIX} +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/depth_three/symlink_parentdir_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_outside_package +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_relocatable_subpath +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_current_dir +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/depth_two/symlink_samedir_path_longer +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_one/symlink_subdir_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/different_relocatable/bar +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_other_relocatable_path +/usr/foo/bar/lib${LIB_SUFFIX}/inside_relocatable_two/depth_two/symlink_to_non_relocatable_path +/usr/foo/bar/lib${LIB_SUFFIX}/libmylib.a +/usr/foo/bar/non_relocatable +/usr/foo/bar/non_relocatable/depth_two +/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path +/usr/foo/bar/other_relocatable +/usr/foo/bar/other_relocatable/depth_two$") elseif(check_file_headers_match) set(check_file_match_expected_summary ".*${CPACK_RPM_headers_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_RPM_headers_PACKAGE_DESCRIPTION}.*") @@ -188,10 +215,12 @@ if(CPackGen MATCHES "RPM") elseif(check_file_applications_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*${CPACK_COMPONENT_APPLICATIONS_DESCRIPTION}.*") - set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}.*") + set(check_file_match_expected_relocation_path "Relocations${whitespaces}:${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}") set(check_file_match_expected_architecture "armv7hf") set(spec_regex "*applications*") - set(check_content_list "^/usr/foo/bar\n/usr/foo/bar/bin\n/usr/foo/bar/bin/mylibapp$") + set(check_content_list "^/usr/foo/bar +/usr/foo/bar/bin +/usr/foo/bar/bin/mylibapp$") elseif(check_file_Unspecified_match) set(check_file_match_expected_summary ".*${CPACK_RPM_PACKAGE_SUMMARY}.*") set(check_file_match_expected_description ".*DESCRIPTION.*") @@ -269,5 +298,59 @@ if(CPackGen MATCHES "RPM") message(FATAL_ERROR "error: '${check_file}' rpm package content does not match expected value - regex '${check_content_list}'; RPM output: '${check_package_content}'; generated spec file: '${spec_file_content}'") endif() endforeach() + + ####################### + # verify generated symbolic links + ####################### + file(GLOB_RECURSE symlink_files RELATIVE "${CPackComponentsForAll_BINARY_DIR}" "${CPackComponentsForAll_BINARY_DIR}/*/symlink_*") + + foreach(check_symlink IN LISTS symlink_files) + get_filename_component(symlink_name "${check_symlink}" NAME) + execute_process(COMMAND ls -la "${check_symlink}" + WORKING_DIRECTORY "${CPackComponentsForAll_BINARY_DIR}" + OUTPUT_VARIABLE SYMLINK_POINT_ + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if("${symlink_name}" STREQUAL "symlink_samedir_path" + OR "${symlink_name}" STREQUAL "symlink_samedir_path_current_dir" + OR "${symlink_name}" STREQUAL "symlink_samedir_path_longer") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_three$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_subdir_path") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}depth_two/depth_three$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_parentdir_path") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}../$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_to_non_relocatable_path") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}${CPACK_PACKAGING_INSTALL_PREFIX}/non_relocatable/depth_two$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_outside_package") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}outside_package$" check_symlink "${SYMLINK_POINT_}") + elseif("${symlink_name}" STREQUAL "symlink_other_relocatable_path" + OR "${symlink_name}" STREQUAL "symlink_from_non_relocatable_path" + OR "${symlink_name}" STREQUAL "symlink_relocatable_subpath") + # these links were not canged - post install script only - ignore them + else() + message(FATAL_ERROR "error: unexpected rpm symbolic link '${check_symlink}'") + endif() + + if(NOT check_symlink) + message(FATAL_ERROR "symlink points to unexpected location '${SYMLINK_POINT_}'") + endif() + endforeach() + + # verify post install symlink relocation script + file(GLOB_RECURSE spec_file "${CPackComponentsForAll_BINARY_DIR}/*libraries*.spec") + file(READ ${spec_file} spec_file_content) + file(READ "${CMAKE_CURRENT_LIST_DIR}/symlink_postinstall_expected.txt" symlink_postinstall_expected) + # prepare regex + string(STRIP "${symlink_postinstall_expected}" symlink_postinstall_expected) + string(REPLACE "[" "\\[" symlink_postinstall_expected "${symlink_postinstall_expected}") + string(REPLACE "$" "\\$" symlink_postinstall_expected "${symlink_postinstall_expected}") + string(REPLACE "lib" "lib${LIB_SUFFIX}" symlink_postinstall_expected "${symlink_postinstall_expected}") + # compare + string(REGEX MATCH ".*${symlink_postinstall_expected}.*" symlink_postinstall_expected_matches "${spec_file_content}") + if(NOT symlink_postinstall_expected_matches) + message(FATAL_ERROR "error: unexpected rpm symbolic link postinstall script! generated spec file: '${spec_file_content}'") + endif() endif() endif() + +cmake_policy(POP) diff --git a/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt b/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt new file mode 100644 index 0000000..ba46792 --- /dev/null +++ b/Tests/CPackComponentsForAll/symlink_postinstall_expected.txt @@ -0,0 +1,57 @@ +if [ "$RPM_INSTALL_PREFIX0" != "/usr/foo/bar/lib" ]; then + if [ "$RPM_INSTALL_PREFIX1" != "/usr/foo/bar/other_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "$RPM_INSTALL_PREFIX1/depth_two" "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/symlink_other_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_1=true + fi + fi + if [ "$RPM_INSTALL_PREFIX2" != "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX2/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/different_relocatable/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable/bar" "$RPM_INSTALL_PREFIX0/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "/usr/foo/bar/other_relocatable/depth_two" "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/symlink_other_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_1=true + fi +fi +if [ "$RPM_INSTALL_PREFIX1" != "/usr/foo/bar/other_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "$RPM_INSTALL_PREFIX1/depth_two" "/usr/foo/bar/lib/inside_relocatable_two/depth_two/symlink_other_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_1=true + fi +fi +if [ "$RPM_INSTALL_PREFIX2" != "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX2/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi +fi +if [ "$RPM_INSTALL_PREFIX0" != "/usr/foo/bar/lib" ]; then + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two/different_relocatable/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath" + CPACK_RPM_RELOCATED_SYMLINK_0=true + fi + if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_2" ]; then + ln -s "$RPM_INSTALL_PREFIX0/inside_relocatable_two/depth_two" "/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path" + CPACK_RPM_RELOCATED_SYMLINK_2=true + fi +fi +if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_0" ]; then + ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two/different_relocatable/bar" "/usr/foo/bar/lib/inside_relocatable_one/depth_two/symlink_relocatable_subpath" +fi +if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_1" ]; then + ln -s "/usr/foo/bar/other_relocatable/depth_two" "/usr/foo/bar/lib/inside_relocatable_two/depth_two/symlink_other_relocatable_path" +fi +if [ -z "$CPACK_RPM_RELOCATED_SYMLINK_2" ]; then + ln -s "/usr/foo/bar/lib/inside_relocatable_two/depth_two" "/usr/foo/bar/non_relocatable/depth_two/symlink_from_non_relocatable_path" +fi ----------------------------------------------------------------------- Summary of changes: Modules/CPackRPM.cmake | 364 ++++++++++++++++++-- Tests/CPackComponentsForAll/CMakeLists.txt | 39 ++- .../RunCPackVerifyResult.cmake | 91 ++++- .../symlink_postinstall_expected.txt | 57 +++ 4 files changed, 525 insertions(+), 26 deletions(-) create mode 100644 Tests/CPackComponentsForAll/symlink_postinstall_expected.txt hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/mailman/listinfo/cmake-commits