From b78fcf0d2f3f8144d167068fcfa834ea8062ebf5 Mon Sep 17 00:00:00 2001 From: Domen Vrankar Date: Tue, 20 Sep 2016 00:41:33 +0200 Subject: [PATCH] CPack/RPM debuginfo packages must contain sources Issue #15668 fix was missing relevant source files in debuginfo package. --- Modules/CPack.cmake | 2 + Modules/CPackRPM.cmake | 135 ++++++++++++++++-- Tests/RunCMake/CPack/DEBUGINFO.cmake | 8 ++ .../CPack/RPM/DEBUGINFO-ExpectedFiles.cmake | 4 +- 4 files changed, 135 insertions(+), 14 deletions(-) diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 99f22ecf6..50d9fc370 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -604,6 +604,8 @@ if(CMAKE_OSX_SYSROOT) _cpack_set_default(CPACK_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}") endif() +_cpack_set_default(CPACK_BUILD_SOURCE_DIRS "${CMAKE_SOURCE_DIR};${CMAKE_BINARY_DIR}") + if(DEFINED CPACK_COMPONENTS_ALL) if(CPACK_MONOLITHIC_INSTALL) message("CPack warning: both CPACK_COMPONENTS_ALL and CPACK_MONOLITHIC_INSTALL have been set.\nDefaulting to a monolithic installation.") diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index d78f7fa64..1eb4315ae 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -1321,13 +1321,37 @@ endif() # We need to check if the binaries were compiled with debug symbols # because without them the package will be useless function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) + if(NOT CPACK_BUILD_SOURCE_DIRS) + message(FATAL_ERROR "CPackRPM: CPACK_BUILD_SOURCE_DIRS variable is not set!" + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + # With objdump we should check the debug symbols find_program(OBJDUMP_EXECUTABLE objdump) if(NOT OBJDUMP_EXECUTABLE) - message(WARNING "CPackRPM: objdump binary could not be found!") + message(FATAL_ERROR "CPackRPM: objdump binary could not be found!" + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") endif() + # With debugedit we prepare source files list + find_program(DEBUGEDIT_EXECUTABLE debugedit "/usr/lib/rpm/") + if(NOT DEBUGEDIT_EXECUTABLE) + message(FATAL_ERROR "CPackRPM: debugedit binary could not be found!" + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + + unset(mkdir_list_) + unset(cp_list_) + unset(additional_sources_) + foreach(F IN LISTS INSTALL_FILES) + if(IS_DIRECTORY "${WORKING_DIR}/${F}" OR IS_SYMLINK "${WORKING_DIR}/${F}") + continue() + endif() + execute_process(COMMAND "${OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F} WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}" RESULT_VARIABLE OBJDUMP_EXEC_RESULT @@ -1335,11 +1359,70 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) # Check that if the given file was executable or not if(NOT OBJDUMP_EXEC_RESULT) string(FIND "${OBJDUMP_OUT}" "debug" FIND_RESULT) - if(NOT FIND_RESULT GREATER -1) + if(FIND_RESULT GREATER -1) + set(index_ 0) + foreach(source_dir_ IN LISTS CPACK_BUILD_SOURCE_DIRS) + string(LENGTH "${source_dir_}" source_dir_len_) + string(LENGTH "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}" debuginfo_dir_len) + if(source_dir_len_ LESS debuginfo_dir_len) + message(FATAL_ERROR "CPackRPM: source dir path '${source_dir_}' is" + " longer than debuginfo sources dir path '${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}'!" + " Source dir path must be shorter than debuginfo sources dir path." + " Set CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX variable to a shorter value" + " or make source dir path longer." + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + + file(REMOVE "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list") + execute_process(COMMAND "${DEBUGEDIT_EXECUTABLE}" -b "${source_dir_}" -d "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}" -i -l "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list" "${WORKING_DIR}/${F}" + RESULT_VARIABLE res_ + OUTPUT_VARIABLE opt_ + ERROR_VARIABLE err_ + ) + + file(STRINGS + "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list" + sources_) + list(REMOVE_DUPLICATES sources_) + + foreach(source_ IN LISTS sources_) + if(EXISTS "${source_dir_}/${source_}" AND NOT IS_DIRECTORY "${source_dir_}/${source_}") + get_filename_component(path_part_ "${source_}" DIRECTORY) + list(APPEND mkdir_list_ "%{buildroot}${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${path_part_}") + list(APPEND cp_list_ "cp \"${source_dir_}/${source_}\" \"%{buildroot}${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${path_part_}\"") + + list(APPEND additional_sources_ "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${source_}") + endif() + endforeach() + + math(EXPR index_ "${index_} + 1") + endforeach() + else() message(WARNING "CPackRPM: File: ${F} does not contain debug symbols. They will possibly be missing from debuginfo package!") endif() endif() endforeach() + + list(REMOVE_DUPLICATES mkdir_list_) + unset(TMP_RPM_DEBUGINFO_INSTALL) + foreach(part_ IN LISTS mkdir_list_) + string(APPEND TMP_RPM_DEBUGINFO_INSTALL "mkdir -p \"${part_}\"\n") + endforeach() + + list(REMOVE_DUPLICATES cp_list_) + foreach(part_ IN LISTS cp_list_) + string(APPEND TMP_RPM_DEBUGINFO_INSTALL "${part_}\n") + endforeach() + + list(REMOVE_DUPLICATES additional_sources_) + unset(TMP_DEBUGINFO_ADDITIONAL_SOURCES) + foreach(part_ IN LISTS additional_sources_) + string(APPEND TMP_DEBUGINFO_ADDITIONAL_SOURCES "${part_}\n") + endforeach() + + set(TMP_RPM_DEBUGINFO_INSTALL "${TMP_RPM_DEBUGINFO_INSTALL}" PARENT_SCOPE) + set(TMP_DEBUGINFO_ADDITIONAL_SOURCES "${TMP_DEBUGINFO_ADDITIONAL_SOURCES}" PARENT_SCOPE) endfunction() function(cpack_rpm_variable_fallback OUTPUT_VAR_NAME) @@ -1860,6 +1943,41 @@ function(cpack_rpm_generate_package) set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") endif() + cpack_rpm_variable_fallback("CPACK_RPM_DEBUGINFO_PACKAGE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_PACKAGE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_PACKAGE" + "CPACK_RPM_DEBUGINFO_PACKAGE") + if(CPACK_RPM_DEBUGINFO_PACKAGE) + cpack_rpm_variable_fallback("CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_BUILD_SOURCE_DIRS_PREFIX" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_BUILD_SOURCE_DIRS_PREFIX" + "CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX") + if(NOT CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX) + set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/usr/src/debug/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}") + endif() + cpack_rpm_debugsymbol_check("${CPACK_RPM_INSTALL_FILES}" "${WDIR}") + + set(TMP_RPM_DEBUGINFO " +# Modified version of %%debug_package macro +# defined in /usr/lib/rpm/macros as that one +# can't handle injection of extra source files. +%ifnarch noarch +%global __debug_package 1 +%package debuginfo +Summary: Debug information for package %{name} +Group: Development/Debug +AutoReqProv: 0 +%description debuginfo +This package provides debug information for package %{name}. +Debug information is useful when developing applications that use this +package or when debugging this package. +%files debuginfo -f debugfiles.list +%defattr(-,root,root) +${TMP_DEBUGINFO_ADDITIONAL_SOURCES} +%endif +") + endif() + # Prepare install files cpack_rpm_prepare_install_files( "${CPACK_RPM_INSTALL_FILES}" @@ -1919,15 +2037,6 @@ function(cpack_rpm_generate_package) "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_USER_BINARY_SPECFILE") endif() - cpack_rpm_variable_fallback("CPACK_RPM_DEBUGINFO_PACKAGE" - "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_PACKAGE" - "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_PACKAGE" - "CPACK_RPM_DEBUGINFO_PACKAGE") - if(CPACK_RPM_DEBUGINFO_PACKAGE) - cpack_rpm_debugsymbol_check("${CPACK_ABSOLUTE_DESTINATION_FILES}" "${WDIR}") - set(TMP_RPM_DEBUGINFO "%debug_package") - endif() - cpack_rpm_variable_fallback("CPACK_RPM_FILE_NAME" "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_FILE_NAME" "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_FILE_NAME" @@ -2104,6 +2213,8 @@ then fi mv %_topdir/tmpBBroot $RPM_BUILD_ROOT +\@TMP_RPM_DEBUGINFO_INSTALL\@ + %clean %post @@ -2158,7 +2269,7 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT execute_process( COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS} --define "_topdir ${CPACK_RPM_DIRECTORY}" - --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" # TODO should I remove this variable? or change the path? + --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" --target "${CPACK_RPM_PACKAGE_ARCHITECTURE}" "${CPACK_RPM_BINARY_SPECFILE}" WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" diff --git a/Tests/RunCMake/CPack/DEBUGINFO.cmake b/Tests/RunCMake/CPack/DEBUGINFO.cmake index 2a65b7f22..d98b6823f 100644 --- a/Tests/RunCMake/CPack/DEBUGINFO.cmake +++ b/Tests/RunCMake/CPack/DEBUGINFO.cmake @@ -1,5 +1,11 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH 1) +# PGI compiler doesn't add build id to binaries by default +if(CMAKE_CXX_COMPILER_ID STREQUAL "PGI") + string(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--build-id") + string(APPEND CMAKE_SHARED_LINKER_FLAGS "-Wl,--build-id") +endif() + set(CPACK_RPM_COMPONENT_INSTALL "ON") set(CMAKE_BUILD_TYPE Debug) @@ -23,4 +29,6 @@ set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT") set(CPACK_RPM_APPLICATIONS_DEBUGINFO_PACKAGE ON) set(CPACK_RPM_LIBS_DEBUGINFO_PACKAGE ON) +set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/src") + set(CPACK_PACKAGE_NAME "debuginfo") diff --git a/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake index 265ca92a1..9e62a6262 100644 --- a/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake +++ b/Tests/RunCMake/CPack/RPM/DEBUGINFO-ExpectedFiles.cmake @@ -9,6 +9,6 @@ set(EXPECTED_FILE_3 "debuginfo*-libs.rpm") set(EXPECTED_FILE_CONTENT_3 "^/usr/bas${whitespaces_}/usr/bas/libtest_lib.so$") set(EXPECTED_FILE_4 "debuginfo-applications-debuginfo*.rpm") -set(EXPECTED_FILE_CONTENT_4 ".*") +set(EXPECTED_FILE_CONTENT_4 ".*/src/src_1/main.cpp.*") set(EXPECTED_FILE_5 "debuginfo-libs-debuginfo*.rpm") -set(EXPECTED_FILE_CONTENT_5 ".*") +set(EXPECTED_FILE_CONTENT_5 ".*/src/src_1/test_lib.cpp.*")