Browse Source

Merge topic 'cpack-rpm-check-executable-flags'

a2031d3a CPack/RPM: check executable flags for debuginfo packages

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1565
Brad King 8 years ago
parent
commit
e016d6d255

+ 6 - 0
Help/release/dev/cpack-rpm-check-executable-flags.rst

@@ -0,0 +1,6 @@
+cpack-rpm-check-executable-flags
+--------------------------------
+
+* The :module:`CPackRPM` module learned to enable enforcing of execute
+  privilages on programs and shared libraries.
+  See :variable:`CPACK_RPM_INSTALL_WITH_EXEC` variable.

+ 73 - 2
Modules/CPackRPM.cmake

@@ -691,6 +691,22 @@
 #  are the same as for :variable:`CPACK_RPM_DEFAULT_FILE_PERMISSIONS`.
 #  Note that <compName> must be in upper-case.
 #
+# .. variable:: CPACK_RPM_INSTALL_WITH_EXEC
+#
+#  force execute permissions on programs and shared libraries
+#
+#  * Mandatory : NO
+#  * Default   : - (system default)
+#
+#  Force set owner, group and world execute permissions on programs and shared
+#  libraries. This can be used for creating valid rpm packages on systems such
+#  as Debian where shared libraries do not have execute permissions set.
+#
+# .. note::
+#
+#  Programs and shared libraries without execute permissions are ignored during
+#  separation of debug symbols from the binary for debuginfo packages.
+#
 # Packaging of Symbolic Links
 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 #
@@ -751,7 +767,8 @@
 # .. note::
 #
 #  Packages generated from packages without binary files, with binary files but
-#  without execute permissions or without debug symbols will be empty.
+#  without execute permissions or without debug symbols will cause packaging
+#  termination.
 #
 # .. variable:: CPACK_BUILD_SOURCE_DIRS
 #
@@ -939,6 +956,35 @@
 
 # Author: Eric Noulard with the help of Alexander Neundorf.
 
+function(get_file_permissions FILE RETURN_VAR)
+  execute_process(COMMAND ls -l ${FILE}
+          OUTPUT_VARIABLE permissions_
+          ERROR_QUIET
+          OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+  cmake_policy(SET CMP0007 NEW)
+  string(REPLACE " " ";" permissions_ "${permissions_}")
+  list(GET permissions_ 0 permissions_)
+
+  unset(text_notation_)
+  set(any_chars_ ".")
+  foreach(PERMISSION_TYPE "OWNER" "GROUP" "WORLD")
+    if(permissions_ MATCHES "${any_chars_}r.*")
+      list(APPEND text_notation_ "${PERMISSION_TYPE}_READ")
+    endif()
+    string(APPEND any_chars_ ".")
+    if(permissions_ MATCHES "${any_chars_}w.*")
+      list(APPEND text_notation_ "${PERMISSION_TYPE}_WRITE")
+    endif()
+    string(APPEND any_chars_ ".")
+    if(permissions_ MATCHES "${any_chars_}x.*")
+      list(APPEND text_notation_ "${PERMISSION_TYPE}_EXECUTE")
+    endif()
+  endforeach()
+
+  set(${RETURN_VAR} "${text_notation_}" PARENT_SCOPE)
+endfunction()
+
 function(get_unix_permissions_octal_notation PERMISSIONS_VAR RETURN_VAR)
   set(PERMISSIONS ${${PERMISSIONS_VAR}})
   list(LENGTH PERMISSIONS PERM_LEN_PRE)
@@ -1515,7 +1561,7 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
                     RESULT_VARIABLE OBJDUMP_EXEC_RESULT
                     OUTPUT_VARIABLE OBJDUMP_OUT
                     ERROR_QUIET)
-    # Check that if the given file was executable or not
+    # Check if the given file is an executable or not
     if(NOT OBJDUMP_EXEC_RESULT)
       string(FIND "${OBJDUMP_OUT}" "debug" FIND_RESULT)
       if(FIND_RESULT GREATER -1)
@@ -1560,6 +1606,31 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
       else()
         message(WARNING "CPackRPM: File: ${F} does not contain debug symbols. They will possibly be missing from debuginfo package!")
       endif()
+
+      get_file_permissions("${WORKING_DIR}/${F}" permissions_)
+      cmake_policy(SET CMP0057 NEW)
+      if(NOT "USER_EXECUTE" IN_LIST permissions_ AND
+         NOT "GROUP_EXECUTE" IN_LIST permissions_ AND
+         NOT "WORLD_EXECUTE" IN_LIST permissions_)
+        if(CPACK_RPM_INSTALL_WITH_EXEC)
+          execute_process(COMMAND chmod a+x ${WORKING_DIR}/${F}
+                  RESULT_VARIABLE res_
+                  ERROR_VARIABLE err_
+                  OUTPUT_QUIET)
+
+          if(res_)
+            message(FATAL_ERROR "CPackRPM: could not apply execute permissions "
+              "requested by CPACK_RPM_INSTALL_WITH_EXEC variable on "
+              "'${WORKING_DIR}/${F}'! Reason: '${err_}'")
+          endif()
+        else()
+          message(AUTHOR_WARNING "CPackRPM: File: ${WORKING_DIR}/${F} does not "
+            "have execute permissions. Debuginfo symbols will not be extracted"
+            "! Missing debuginfo may cause packaging failure. Consider setting "
+            "execute permissions or setting 'CPACK_RPM_INSTALL_WITH_EXEC' "
+            "variable.")
+        endif()
+      endif()
     endif()
   endforeach()
 

+ 2 - 2
Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake

@@ -13,6 +13,6 @@ set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so")
 
 set(EXPECTED_FILE_4_NAME "Debuginfo")
 set(EXPECTED_FILE_4_COMPONENT "applications-debuginfo")
-set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
+set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*")
 set(EXPECTED_FILE_5 "libs-DebugInfoPackage.rpm")
-set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*")
+set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*")

+ 4 - 0
Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake

@@ -8,6 +8,10 @@ endif()
 
 set(CMAKE_BUILD_TYPE Debug)
 
+# for rpm packages execute flag must be set for shared libs if debuginfo
+# packages are generated
+set(CPACK_RPM_INSTALL_WITH_EXEC TRUE)
+
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp"
     "int test_lib();\n")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp"

+ 2 - 2
Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/ExpectedFiles.cmake

@@ -12,6 +12,6 @@ set(EXPECTED_FILE_3 "extra_slash_in_path*-libs.rpm")
 set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so")
 
 set(EXPECTED_FILE_4_COMPONENT "applications-debuginfo")
-set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
+set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*")
 set(EXPECTED_FILE_5_COMPONENT "libs-debuginfo")
-set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*")
+set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*")

+ 4 - 0
Tests/RunCMake/CPack/tests/EXTRA_SLASH_IN_PATH/test.cmake

@@ -8,6 +8,10 @@ endif()
 
 set(CMAKE_BUILD_TYPE Debug)
 
+# for rpm packages execute flag must be set for shared libs if debuginfo
+# packages are generated
+set(CPACK_RPM_INSTALL_WITH_EXEC TRUE)
+
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp"
     "int test_lib();\n")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp"

+ 3 - 3
Tests/RunCMake/CPack/tests/SINGLE_DEBUGINFO/ExpectedFiles.cmake

@@ -12,19 +12,19 @@ if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid" OR RunCMake_SUBTEST_SUFFIX STREQUAL
   set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so")
 
   set(EXPECTED_FILE_4_COMPONENT "debuginfo")
-  set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*")
+  set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*")
 elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component" OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_no_debuginfo")
   set(EXPECTED_FILES_COUNT "2")
   set(EXPECTED_FILE_1 "single_debuginfo-0*-applications.rpm")
   set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/test_prog")
 
   set(EXPECTED_FILE_2 "single_debuginfo-applications-debuginfo*.rpm")
-  set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
+  set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*")
 elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_main" OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_components")
   set(EXPECTED_FILES_COUNT "2")
   set(EXPECTED_FILE_1 "single_debuginfo-0*.rpm")
   set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/test_prog")
 
   set(EXPECTED_FILE_2 "single_debuginfo-debuginfo*.rpm")
-  set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*")
+  set(EXPECTED_FILE_CONTENT_2 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*")
 endif()