diff --git a/Help/release/dev/cpack-rpm-external-symlink-handling.rst b/Help/release/dev/cpack-rpm-external-symlink-handling.rst new file mode 100644 index 000000000..ff74e1d16 --- /dev/null +++ b/Help/release/dev/cpack-rpm-external-symlink-handling.rst @@ -0,0 +1,5 @@ +cpack-rpm-external-symlink-handling +----------------------------------- + +* The "CPackRPM" module learned how to correctly handle symlinks + that are pointing outside generated packages. diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index ae51dc103..713b9388c 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -599,9 +599,10 @@ # 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: +# Symbolic links that point to locations outside packaging path produce a +# warning and are treated as non relocatable permanent symbolic links. # -# * Only symbolic links with relative path can be packaged. +# Currenty there are a few limitations though: # # * For component based packaging component interdependency is not checked # when processing symbolic links. Symbolic links pointing to content of @@ -1068,13 +1069,28 @@ function(cpack_rpm_prepare_install_files INSTALL_FILES_LIST WDIR PACKAGE_PREFIXE get_filename_component(SYMLINK_POINT_ "${SYMLINK_LOCATION_}/${SYMLINK_POINT_}" ABSOLUTE) endif() - string(SUBSTRING "${SYMLINK_POINT_}" ${WDR_LEN_} -1 SYMLINK_POINT_WD_) + # recalculate path length after conversion to canonical form + string(LENGTH "${SYMLINK_POINT_}" SYMLINK_POINT_LENGTH_) - cpack_rpm_symlink_get_relocation_prefixes("${F}" "${PACKAGE_PREFIXES}" "SYMLINK_RELOCATIONS") - cpack_rpm_symlink_get_relocation_prefixes("${SYMLINK_POINT_WD_}" "${PACKAGE_PREFIXES}" "POINT_RELOCATIONS") + if(SYMLINK_POINT_ MATCHES "${WDIR}/.*") + # only symlinks that are pointing inside the packaging structure should be checked for relocation + 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) + list(LENGTH SYMLINK_RELOCATIONS SYMLINK_RELOCATIONS_COUNT) + list(LENGTH POINT_RELOCATIONS POINT_RELOCATIONS_COUNT) + else() + # location pointed to is ouside WDR so it should be treated as a permanent symlink + set(SYMLINK_POINT_WD_ "${SYMLINK_POINT_}") + + unset(SYMLINK_RELOCATIONS) + unset(POINT_RELOCATIONS) + unset(SYMLINK_RELOCATIONS_COUNT) + unset(POINT_RELOCATIONS_COUNT) + + message(AUTHOR_WARNING "CPackRPM:Warning: Symbolic link '${F}' points to location that is outside packaging path! Link will possibly not be relocatable.") + endif() if(SYMLINK_RELOCATIONS_COUNT AND POINT_RELOCATIONS_COUNT) # find matching diff --git a/Tests/CPackComponentsForAll/CMakeLists.txt b/Tests/CPackComponentsForAll/CMakeLists.txt index 823f6db4d..05c13a490 100644 --- a/Tests/CPackComponentsForAll/CMakeLists.txt +++ b/Tests/CPackComponentsForAll/CMakeLists.txt @@ -92,6 +92,9 @@ if("${CPACK_GENERATOR}" MATCHES "RPM") # 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) + # test symbolic link to location outside wdr (packaging directory) + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink /outside_package_wdr symlink_outside_wdr) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/symlink_outside_wdr DESTINATION ${CMAKE_INSTALL_LIBDIR}/inside_relocatable_one/depth_two COMPONENT libraries) endif() # CPack boilerplate for this project diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake index 0c5cca82d..e956f17c1 100644 --- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake @@ -188,6 +188,7 @@ if(CPackGen MATCHES "RPM") /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_outside_wdr /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 @@ -354,6 +355,8 @@ if(CPackGen MATCHES "RPM") 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_outside_wdr") + string(REGEX MATCH "^.*${whitespaces}->${whitespaces}/outside_package_wdr$" 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")