From eae4eef0c48188027b5c25657054b12b6b301c85 Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Thu, 31 Mar 2016 07:48:38 +0200 Subject: [PATCH] CPack/RPM external symlink handling Symbolic links that point to external location no longer cause cmake to fail with string out of bounds error but are instead packaged as non relocatable symlinks and print out a warning message. --- .../cpack-rpm-external-symlink-handling.rst | 5 ++++ Modules/CPackRPM.cmake | 30 ++++++++++++++----- Tests/CPackComponentsForAll/CMakeLists.txt | 3 ++ .../RunCPackVerifyResult.cmake | 3 ++ 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 Help/release/dev/cpack-rpm-external-symlink-handling.rst 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")