[Cmake-commits] CMake branch, next, updated. v3.7.0-rc1-95-ga01b549

Domen Vrankar domen.vrankar at gmail.com
Thu Oct 6 02:54:52 EDT 2016


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  a01b5490594eb98063d8354acdd52a03fb46232f (commit)
       via  7f15429cc574f90fdd68ee254c28833a4843e2aa (commit)
       via  9d2cb3f668dd79def44829c8bd5791e7c242e026 (commit)
       via  b39bd548f9f1f96a2285e5aff638085352c21f29 (commit)
       via  bf7d0168bfdfbe1b91bae83dd0091af54e7c4e8a (commit)
       via  22605f1e230a187658c57df22b66e1b1ade09a4a (commit)
      from  003dceb9f5b416a41ba9ca38c51f24f82e867091 (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 -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a01b5490594eb98063d8354acdd52a03fb46232f
commit a01b5490594eb98063d8354acdd52a03fb46232f
Merge: 003dceb 7f15429
Author:     Domen Vrankar <domen.vrankar at gmail.com>
AuthorDate: Thu Oct 6 02:54:44 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Oct 6 02:54:44 2016 -0400

    Merge topic 'cpack-rpm-single-debuginfo' into next
    
    7f15429c CPack/RPM single debuginfo packaging
    9d2cb3f6 CPack/RPM learned defining main component
    b39bd548 CPack/RPM debuginfo package without binaries
    bf7d0168 CPack/RPM debuginfo package objdump error suppression
    22605f1e CMake Nightly Date Stamp


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7f15429cc574f90fdd68ee254c28833a4843e2aa
commit 7f15429cc574f90fdd68ee254c28833a4843e2aa
Author:     Domen Vrankar <domen.vrankar at gmail.com>
AuthorDate: Thu Oct 6 08:33:16 2016 +0200
Commit:     Domen Vrankar <domen.vrankar at gmail.com>
CommitDate: Thu Oct 6 08:47:36 2016 +0200

    CPack/RPM single debuginfo packaging
    
    Generate a single debuginfo package even
    if components packaging is enabled.
    
    This makes issue #15668 resolution feature complete.
    
    Closes: #15486

diff --git a/Help/release/dev/cpack-rpm-single-debuginfo.rst b/Help/release/dev/cpack-rpm-single-debuginfo.rst
index 281a988..34a710d 100644
--- a/Help/release/dev/cpack-rpm-single-debuginfo.rst
+++ b/Help/release/dev/cpack-rpm-single-debuginfo.rst
@@ -5,3 +5,7 @@ cpack-rpm-single-debuginfo
   which forces generation of a rpm for defined component without component
   suffix in filename and package name.
   See :variable:`CPACK_RPM_MAIN_COMPONENT` variable.
+
+* The :module:`CPackRPM` module learned to generate a single debuginfo package
+  on demand even if components packagin is used.
+  See :variable:`CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE` variable.
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 2c8c0e0..6017ce3 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -803,6 +803,26 @@
 #  * Mandatory : NO
 #  * Default   : -
 #
+# .. variable:: CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE
+#
+#  Create a single debuginfo package even if components packaging is set.
+#
+#  * Mandatory : NO
+#  * Default   : OFF
+#
+#  When this variable is enabled it produces a single debuginfo package even if
+#  component packaging is enabled.
+#
+#  When using this feature in combination with components packaging and there is
+#  more than one component this variable requires :variable:`CPACK_RPM_MAIN_COMPONENT`
+#  to be set.
+#
+# .. note::
+#
+#  If none of the :variable:`CPACK_RPM_<component>_DEBUGINFO_PACKAGE` variables
+#  is set then :variable:`CPACK_RPM_DEBUGINFO_PACKAGE` is automatically set to
+#  ``ON`` when :variable:`CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE` is set.
+#
 # Packaging of sources (SRPM)
 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 #
@@ -2076,7 +2096,7 @@ function(cpack_rpm_generate_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)
+  if(CPACK_RPM_DEBUGINFO_PACKAGE OR (CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND NOT GENERATE_SPEC_PARTS))
     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"
@@ -2084,9 +2104,81 @@ function(cpack_rpm_generate_package)
     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 "
+    if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND GENERATE_SPEC_PARTS)
+      file(WRITE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}.files"
+        "${CPACK_RPM_INSTALL_FILES}")
+    else()
+      if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND CPACK_RPM_PACKAGE_COMPONENT)
+        # this part is only required by components packaging - with monolithic
+        # packages we can be certain that there are no other components present
+        # so CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE is a noop
+        if(CPACK_RPM_DEBUGINFO_PACKAGE)
+          # only add current package files to debuginfo list if debuginfo
+          # generation is enabled for current package
+          set(install_files_ "${CPACK_RPM_INSTALL_FILES}")
+        else()
+          unset(install_files_)
+        endif()
+
+        file(GLOB files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.files")
+
+        foreach(f_ IN LISTS files_)
+          file(READ "${f_}" tmp_)
+          string(APPEND install_files_ ";${tmp_}")
+        endforeach()
+
+        # if there were other components/groups so we need to move files from them
+        # to current component otherwise those files won't be found
+        file(GLOB components_ LIST_DIRECTORIES true RELATIVE
+          "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}"
+          "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/*")
+        foreach(component_ IN LISTS components_)
+          string(TOUPPER "${component_}" component_dir_upper_)
+          if(component_dir_upper_ STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+            # skip current component
+            continue()
+          endif()
+
+          cmake_policy(PUSH)
+            cmake_policy(SET CMP0009 NEW)
+            file(GLOB_RECURSE files_for_move_ LIST_DIRECTORIES false RELATIVE
+              "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}"
+              "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/*")
+          cmake_policy(POP)
+
+          foreach(f_ IN LISTS files_for_move_)
+            get_filename_component(dir_path_ "${f_}" DIRECTORY)
+            set(src_file_
+              "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/${f_}")
+
+            # check that we are not overriding an existing file that doesn't
+            # match the file that we want to copy
+            if(EXISTS "${src_file_}" AND EXISTS "${WDIR}/${f_}")
+              execute_process(
+                  COMMAND ${CMAKE_COMMAND} -E compare_files "${src_file_}" "${WDIR}/${f_}"
+                  RESULT_VARIABLE res_
+                )
+              if(res_)
+                message(FATAL_ERROR "CPackRPM:Error: File on path '${WDIR}/${f_}'"
+                  " already exists but is a different than the one in component"
+                  " '${component_}'! Packages will not be generated.")
+              endif()
+            endif()
+
+            file(MAKE_DIRECTORY "${WDIR}/${dir_path_}")
+            file(RENAME "${src_file_}"
+              "${WDIR}/${f_}")
+          endforeach()
+        endforeach()
+
+        cpack_rpm_debugsymbol_check("${install_files_}" "${WDIR}")
+      else()
+        cpack_rpm_debugsymbol_check("${CPACK_RPM_INSTALL_FILES}" "${WDIR}")
+      endif()
+
+      if(TMP_DEBUGINFO_ADDITIONAL_SOURCES)
+        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.
@@ -2105,6 +2197,15 @@ package or when debugging this package.
 ${TMP_DEBUGINFO_ADDITIONAL_SOURCES}
 %endif
 ")
+      elseif(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE)
+        message(AUTHOR_WARNING "CPackRPM:Warning: debuginfo package was requested"
+          " but will not be generated as no source files were found!")
+      else()
+        message(AUTHOR_WARNING "CPackRPM:Warning: debuginfo package was requested"
+          " but will not be generated as no source files were found! Component: '"
+          "${CPACK_RPM_PACKAGE_COMPONENT}'.")
+      endif()
+    endif()
   endif()
 
   # Prepare install files
@@ -2194,7 +2295,12 @@ ${TMP_DEBUGINFO_ADDITIONAL_SOURCES}
     # else example:
     #set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
 
-    if(NOT CPACK_RPM_DEBUGINFO_PACKAGE)
+    if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND GENERATE_SPEC_PARTS)
+      string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" expected_filename_)
+
+      file(WRITE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}.rpm_name"
+        "${expected_filename_};${CPACK_RPM_FILE_NAME}")
+    elseif(NOT CPACK_RPM_DEBUGINFO_PACKAGE)
       set(FILE_NAME_DEFINE "%define _rpmfilename ${CPACK_RPM_FILE_NAME}")
     endif()
   endif()
@@ -2289,7 +2395,54 @@ Vendor:         \@CPACK_RPM_PACKAGE_VENDOR\@
 \@CPACK_RPM_SPEC_CHANGELOG\@
 "
     )
+
+  elseif(GENERATE_SPEC_PARTS) # binary rpm with single debuginfo package
+    file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in
+        "# -*- rpm-spec -*-
+%package -n \@CPACK_RPM_PACKAGE_NAME\@
+Summary:        \@CPACK_RPM_PACKAGE_SUMMARY\@
+Version:        \@CPACK_RPM_PACKAGE_VERSION\@
+Release:        \@CPACK_RPM_PACKAGE_RELEASE\@
+License:        \@CPACK_RPM_PACKAGE_LICENSE\@
+Group:          \@CPACK_RPM_PACKAGE_GROUP\@
+Vendor:         \@CPACK_RPM_PACKAGE_VENDOR\@
+
+\@TMP_RPM_URL\@
+\@TMP_RPM_REQUIRES\@
+\@TMP_RPM_REQUIRES_PRE\@
+\@TMP_RPM_REQUIRES_POST\@
+\@TMP_RPM_REQUIRES_PREUN\@
+\@TMP_RPM_REQUIRES_POSTUN\@
+\@TMP_RPM_PROVIDES\@
+\@TMP_RPM_OBSOLETES\@
+\@TMP_RPM_CONFLICTS\@
+\@TMP_RPM_AUTOPROV\@
+\@TMP_RPM_AUTOREQ\@
+\@TMP_RPM_AUTOREQPROV\@
+\@TMP_RPM_BUILDARCH\@
+\@TMP_RPM_PREFIXES\@
+
+%description -n \@CPACK_RPM_PACKAGE_NAME\@
+\@CPACK_RPM_PACKAGE_DESCRIPTION\@
+
+%files -n \@CPACK_RPM_PACKAGE_NAME\@
+%defattr(\@TMP_DEFAULT_FILE_PERMISSIONS\@,\@TMP_DEFAULT_USER\@,\@TMP_DEFAULT_GROUP\@,\@TMP_DEFAULT_DIR_PERMISSIONS\@)
+\@CPACK_RPM_INSTALL_FILES\@
+\@CPACK_RPM_ABSOLUTE_INSTALL_FILES\@
+\@CPACK_RPM_USER_INSTALL_FILES\@
+"
+    )
+
   else()  # binary rpm
+    if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE)
+      # find generated spec file and take its name
+      file(GLOB spec_files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.spec")
+
+      foreach(f_ IN LISTS spec_files_)
+        file(READ "${f_}" tmp_)
+        string(APPEND TMP_OTHER_COMPONENTS "\n${tmp_}\n")
+      endforeach()
+    endif()
 
     # We should generate a USER spec file template:
     #  - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE
@@ -2375,6 +2528,8 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
 
 %changelog
 \@CPACK_RPM_SPEC_CHANGELOG\@
+
+\@TMP_OTHER_COMPONENTS\@
 "
       )
     endif()
@@ -2401,60 +2556,90 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
     configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY)
   endif()
 
-  if(RPMBUILD_EXECUTABLE)
-    # Now call rpmbuild using the SPECFILE
-    execute_process(
-      COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS}
-              --define "_topdir ${CPACK_RPM_DIRECTORY}"
-              --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}"
-      RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT
-      ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err"
-      OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
-    if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
-      file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err RPMBUILDERR)
-      file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out RPMBUILDOUT)
-      message("CPackRPM:Debug: You may consult rpmbuild logs in: ")
-      message("CPackRPM:Debug:    - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err")
-      message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
-      message("CPackRPM:Debug:    - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
-      message("CPackRPM:Debug: *** ${RPMBUILDOUT} ***")
+  if(NOT GENERATE_SPEC_PARTS) # generate package
+    if(RPMBUILD_EXECUTABLE)
+      # Now call rpmbuild using the SPECFILE
+      execute_process(
+        COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS}
+                --define "_topdir ${CPACK_RPM_DIRECTORY}"
+                --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}"
+        RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT
+        ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err"
+        OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
+      if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT)
+        file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err RPMBUILDERR)
+        file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out RPMBUILDOUT)
+        message("CPackRPM:Debug: You may consult rpmbuild logs in: ")
+        message("CPackRPM:Debug:    - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err")
+        message("CPackRPM:Debug: *** ${RPMBUILDERR} ***")
+        message("CPackRPM:Debug:    - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out")
+        message("CPackRPM:Debug: *** ${RPMBUILDOUT} ***")
+      endif()
+    else()
+      if(ALIEN_EXECUTABLE)
+        message(FATAL_ERROR "RPM packaging through alien not done (yet)")
+      endif()
     endif()
-  else()
-    if(ALIEN_EXECUTABLE)
-      message(FATAL_ERROR "RPM packaging through alien not done (yet)")
+
+    # find generated rpm files and take their names
+    cmake_policy(PUSH)
+      # Tell file(GLOB_RECURSE) not to follow directory symlinks
+      # even if the project does not set this policy to NEW.
+      cmake_policy(SET CMP0009 NEW)
+      file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/RPMS/*.rpm"
+        "${CPACK_RPM_DIRECTORY}/SRPMS/*.rpm")
+    cmake_policy(POP)
+
+    if(NOT GENERATED_FILES)
+      message(FATAL_ERROR "RPM package was not generated! ${CPACK_RPM_DIRECTORY}")
     endif()
-  endif()
 
-  # find generated rpm files and take their names
-  cmake_policy(PUSH)
-    # Tell file(GLOB_RECURSE) not to follow directory symlinks
-    # even if the project does not set this policy to NEW.
-    cmake_policy(SET CMP0009 NEW)
-    file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/RPMS/*.rpm"
-      "${CPACK_RPM_DIRECTORY}/SRPMS/*.rpm")
-  cmake_policy(POP)
+    unset(expected_filenames_)
+    unset(filenames_)
+    if(CPACK_RPM_DEBUGINFO_PACKAGE AND NOT CPACK_RPM_FILE_NAME STREQUAL "RPM-DEFAULT")
+      string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" efn_)
+      list(APPEND expected_filenames_ "${efn_}")
+      list(APPEND filenames_ "${CPACK_RPM_FILE_NAME}")
+    endif()
 
-  if(NOT GENERATED_FILES)
-    message(FATAL_ERROR "RPM package was not generated! ${CPACK_RPM_DIRECTORY}")
-  endif()
+    # check if other files have to be renamed
+    file(GLOB rename_files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.rpm_name")
+    if(rename_files_)
+      foreach(f_ IN LISTS rename_files_)
+        file(READ "${f_}" tmp_)
+        list(GET tmp_ 0 efn_)
+        list(APPEND expected_filenames_ "${efn_}")
+        list(GET tmp_ 1 fn_)
+        list(APPEND filenames_ "${fn_}")
+      endforeach()
+    endif()
 
-  if(CPACK_RPM_DEBUGINFO_PACKAGE AND NOT CPACK_RPM_FILE_NAME STREQUAL "RPM-DEFAULT")
-    string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" EXPECTED_FILENAME)
+    if(expected_filenames_)
+      foreach(F IN LISTS GENERATED_FILES)
+        unset(matched_)
+        foreach(expected_ IN LISTS expected_filenames_)
+          if(F MATCHES ".*/${expected_}")
+            list(FIND expected_filenames_ "${expected_}" idx_)
+            list(GET filenames_ ${idx_} filename_)
+            get_filename_component(FILE_PATH "${F}" DIRECTORY)
+            file(RENAME "${F}" "${FILE_PATH}/${filename_}")
+            list(APPEND new_files_list_ "${FILE_PATH}/${filename_}")
+            set(matched_ "YES")
+
+            break()
+          endif()
+        endforeach()
 
-    foreach(F IN LISTS GENERATED_FILES)
-      if(F MATCHES ".*/${EXPECTED_FILENAME}")
-        get_filename_component(FILE_PATH "${F}" DIRECTORY)
-        file(RENAME "${F}" "${FILE_PATH}/${CPACK_RPM_FILE_NAME}")
-        list(APPEND new_files_list_ "${FILE_PATH}/${CPACK_RPM_FILE_NAME}")
-      else()
-        list(APPEND new_files_list_ "${F}")
-      endif()
-    endforeach()
+        if(NOT matched_)
+          list(APPEND new_files_list_ "${F}")
+        endif()
+      endforeach()
 
-    set(GENERATED_FILES "${new_files_list_}")
+      set(GENERATED_FILES "${new_files_list_}")
+    endif()
   endif()
 
   set(GEN_CPACK_OUTPUT_FILES "${GENERATED_FILES}" PARENT_SCOPE)
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 7f89d5e..9817327 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -107,7 +107,78 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
 
   const char* mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT");
 
+  if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE") &&
+      !this->IsOn("CPACK_RPM_DEBUGINFO_PACKAGE")) {
+    // check if we need to set CPACK_RPM_DEBUGINFO_PACKAGE because non of
+    // the components is setting per component debuginfo package variable
+    bool shouldSet = true;
+
+    if (ignoreGroup) {
+      std::map<std::string, cmCPackComponent>::iterator compIt;
+      for (compIt = this->Components.begin(); compIt != this->Components.end();
+           ++compIt) {
+        std::string component(compIt->first);
+        std::transform(component.begin(), component.end(), component.begin(),
+                       ::toupper);
+
+        if (this->IsOn("CPACK_RPM_" + compIt->first + "_DEBUGINFO_PACKAGE") ||
+            this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
+          shouldSet = false;
+          break;
+        }
+      }
+    } else {
+      std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+      for (compGIt = this->ComponentGroups.begin();
+           compGIt != this->ComponentGroups.end(); ++compGIt) {
+        std::string component(compGIt->first);
+        std::transform(component.begin(), component.end(), component.begin(),
+                       ::toupper);
+
+        if (this->IsOn("CPACK_RPM_" + compGIt->first + "_DEBUGINFO_PACKAGE") ||
+            this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
+          shouldSet = false;
+          break;
+        }
+      }
+
+      if (shouldSet) {
+        std::map<std::string, cmCPackComponent>::iterator compIt;
+        for (compIt = this->Components.begin();
+             compIt != this->Components.end(); ++compIt) {
+          // Does the component belong to a group?
+          if (compIt->second.Group == CM_NULLPTR) {
+            std::string component(compIt->first);
+            std::transform(component.begin(), component.end(),
+                           component.begin(), ::toupper);
+
+            if (this->IsOn("CPACK_RPM_" + compIt->first +
+                           "_DEBUGINFO_PACKAGE") ||
+                this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
+              shouldSet = false;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    if (shouldSet) {
+      cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Setting "
+                      << "CPACK_RPM_DEBUGINFO_PACKAGE because "
+                      << "CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE is set but "
+                      << " none of the "
+                      << "CPACK_RPM_<component>_DEBUGINFO_PACKAGE variables "
+                      << "are set." << std::endl);
+      this->SetOption("CPACK_RPM_DEBUGINFO_PACKAGE", "ON");
+    }
+  }
+
   if (mainComponent) {
+    if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE")) {
+      this->SetOption("GENERATE_SPEC_PARTS", "ON");
+    }
+
     std::string mainComponentUpper(mainComponent);
     std::transform(mainComponentUpper.begin(), mainComponentUpper.end(),
                    mainComponentUpper.begin(), ::toupper);
@@ -163,6 +234,8 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
       }
 
       if (retval) {
+        this->SetOption("GENERATE_SPEC_PARTS", "OFF");
+
         if (mainCompGIt != this->ComponentGroups.end()) {
           retval &= PackageOnePack(initialTopLevel, mainCompGIt->first);
         } else if (mainCompIt != this->Components.end()) {
@@ -197,6 +270,8 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
       }
 
       if (retval) {
+        this->SetOption("GENERATE_SPEC_PARTS", "OFF");
+
         if (mainCompIt != this->Components.end()) {
           retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
         } else {
@@ -206,7 +281,8 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
         }
       }
     }
-  } else {
+  } else if (!this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE") ||
+             this->Components.size() == 1) {
     // The default behavior is to have one package by component group
     // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
     if (!ignoreGroup) {
@@ -241,6 +317,12 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
         retval &= PackageOnePack(initialTopLevel, compIt->first);
       }
     }
+  } else {
+    cmCPackLogger(
+      cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT not set but"
+        << " it is mandatory with CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE"
+        << " being set.\n");
+    retval = 0;
   }
 
   if (retval) {
@@ -259,6 +341,10 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne(
   packageFileNames.clear();
   std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
 
+  if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE")) {
+    this->SetOption("CPACK_RPM_DEBUGINFO_PACKAGE", "ON");
+  }
+
   cmCPackLogger(cmCPackLog::LOG_VERBOSE,
                 "Packaging all groups in one package..."
                 "(CPACK_COMPONENTS_ALL_[GROUPS_]IN_ONE_PACKAGE is set)"
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake
new file mode 100644
index 0000000..dc49343
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake
@@ -0,0 +1,30 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "0")
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid" OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo")
+  set(EXPECTED_FILES_COUNT "4")
+  set(EXPECTED_FILE_1 "single_debuginfo-0.1.1-1.*.rpm")
+  set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/test_prog$")
+  set(EXPECTED_FILE_2 "single_debuginfo*-headers.rpm")
+  set(EXPECTED_FILE_CONTENT_2 "^/usr/bar${whitespaces_}/usr/bar/CMakeLists.txt$")
+  set(EXPECTED_FILE_3 "single_debuginfo*-libs.rpm")
+  set(EXPECTED_FILE_CONTENT_3 "^/usr/bas${whitespaces_}/usr/bas/libtest_lib.so$")
+
+  set(EXPECTED_FILE_4 "single_debuginfo-debuginfo*.rpm")
+  set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp${whitespaces_}/src/src_1/test_lib.cpp.*")
+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 "^/usr/foo${whitespaces_}/usr/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.*")
+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 "^/usr/foo${whitespaces_}/usr/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.*")
+endif()
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt
new file mode 100644
index 0000000..d80939f
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_components-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt
new file mode 100644
index 0000000..86396db
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt
@@ -0,0 +1,3 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-headers.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-libs.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt
new file mode 100644
index 0000000..454283c
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt
@@ -0,0 +1 @@
+CPack Error: CPACK_RPM_MAIN_COMPONENT not set but it is mandatory with CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE being set.
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt
new file mode 100644
index 0000000..080c4ff
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-one_component-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-applications.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt
new file mode 100644
index 0000000..665597c
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-one_component_main-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt
new file mode 100644
index 0000000..b64b1f5
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt
@@ -0,0 +1 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-one_component_no_debuginfo-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-applications.spec$
diff --git a/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt
new file mode 100644
index 0000000..f4c1bef
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt
@@ -0,0 +1,3 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-valid-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-headers.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-valid-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo-libs.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/SINGLE_DEBUGINFO-build-valid-subtest/_CPack_Packages/.*/RPM/SPECS/single_debuginfo.spec$
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 45dbcea..474ee33 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -19,5 +19,6 @@ run_cpack_test(INSTALL_SCRIPTS "RPM" false)
 run_cpack_test(DEB_GENERATE_SHLIBS "DEB" true)
 run_cpack_test(DEB_GENERATE_SHLIBS_LDCONFIG "DEB" true)
 run_cpack_test(DEBUGINFO "RPM" true)
+run_cpack_test_subtests(SINGLE_DEBUGINFO "no_main_component;one_component;one_component_main;no_debuginfo;one_component_no_debuginfo;no_components;valid" "RPM" true)
 run_cpack_test(LONG_FILENAMES "DEB" false)
 run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false)
diff --git a/Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake b/Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake
new file mode 100644
index 0000000..ae4995e
--- /dev/null
+++ b/Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake
@@ -0,0 +1,56 @@
+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()
+
+if(NOT RunCMake_SUBTEST_SUFFIX STREQUAL "no_components")
+  set(CPACK_RPM_COMPONENT_INSTALL "ON")
+endif()
+
+set(CMAKE_BUILD_TYPE Debug)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.hpp"
+    "int test_lib();\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp"
+    "#include \"test_lib.hpp\"\nint test_lib() {return 0;}\n")
+add_library(test_lib SHARED "${CMAKE_CURRENT_BINARY_DIR}/test_lib.cpp")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main.cpp"
+    "#include \"test_lib.hpp\"\nint main() {return test_lib();}\n")
+add_executable(test_prog "${CMAKE_CURRENT_BINARY_DIR}/main.cpp")
+target_link_libraries(test_prog test_lib)
+
+install(TARGETS test_prog DESTINATION foo COMPONENT applications)
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_main_component"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo")
+  install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
+  install(TARGETS test_lib DESTINATION bas COMPONENT libs)
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "one_component"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_no_debuginfo")
+  set(CPACK_COMPONENTS_ALL applications)
+endif()
+
+set(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE ON)
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component_main"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_debuginfo")
+  set(CPACK_RPM_MAIN_COMPONENT "applications")
+  set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT")
+endif()
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "valid"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "no_main_component"
+  OR RunCMake_SUBTEST_SUFFIX STREQUAL "one_component")
+  set(CPACK_RPM_APPLICATIONS_DEBUGINFO_PACKAGE ON)
+  set(CPACK_RPM_LIBS_DEBUGINFO_PACKAGE ON)
+endif()
+
+set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/src")
+
+set(CPACK_PACKAGE_NAME "single_debuginfo")

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9d2cb3f668dd79def44829c8bd5791e7c242e026
commit 9d2cb3f668dd79def44829c8bd5791e7c242e026
Author:     Domen Vrankar <domen.vrankar at gmail.com>
AuthorDate: Wed Oct 5 00:43:28 2016 +0200
Commit:     Domen Vrankar <domen.vrankar at gmail.com>
CommitDate: Thu Oct 6 08:42:43 2016 +0200

    CPack/RPM learned defining main component
    
    Main component rpm package is generated
    without component suffix in filename
    and package name.

diff --git a/Help/release/dev/cpack-rpm-single-debuginfo.rst b/Help/release/dev/cpack-rpm-single-debuginfo.rst
new file mode 100644
index 0000000..281a988
--- /dev/null
+++ b/Help/release/dev/cpack-rpm-single-debuginfo.rst
@@ -0,0 +1,7 @@
+cpack-rpm-single-debuginfo
+--------------------------
+
+* The :module:`CPackRPM` module learned to generate main component package
+  which forces generation of a rpm for defined component without component
+  suffix in filename and package name.
+  See :variable:`CPACK_RPM_MAIN_COMPONENT` variable.
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 15b62c7..2c8c0e0 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -95,6 +95,17 @@
 #    and it is up to the packager to set the variables in a manner that will
 #    prevent such errors.
 #
+# .. variable:: CPACK_RPM_MAIN_COMPONENT
+#
+#  Main component that is packaged without component suffix.
+#
+#  * Mandatory : NO
+#  * Default   : -
+#
+#  This variable can be set to any component or group name so that component or
+#  group rpm package is generated without component suffix in filename and
+#  package name.
+#
 # .. variable:: CPACK_RPM_PACKAGE_VERSION
 #
 #  The RPM package version.
@@ -1649,10 +1660,16 @@ function(cpack_rpm_generate_package)
   endif()
 
   if(CPACK_RPM_PACKAGE_COMPONENT)
-    string(APPEND CPACK_RPM_PACKAGE_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
-    cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_NAME"
-      "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME"
-      "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME")
+    string(TOUPPER "${CPACK_RPM_MAIN_COMPONENT}"
+      CPACK_RPM_MAIN_COMPONENT_UPPER)
+
+    if(NOT CPACK_RPM_MAIN_COMPONENT_UPPER STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+      string(APPEND CPACK_RPM_PACKAGE_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}")
+
+      cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_NAME"
+        "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME"
+        "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME")
+    endif()
   endif()
 
   # CPACK_RPM_PACKAGE_VERSION (mandatory)
@@ -2164,7 +2181,15 @@ ${TMP_DEBUGINFO_ADDITIONAL_SOURCES}
       cmake_policy(POP)
     else()
       # old file name format for back compatibility
-      set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
+      string(TOUPPER "${CPACK_RPM_MAIN_COMPONENT}"
+        CPACK_RPM_MAIN_COMPONENT_UPPER)
+
+      if(CPACK_RPM_MAIN_COMPONENT_UPPER STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER)
+        # this is the main component so ignore the component filename part
+        set(CPACK_RPM_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.rpm")
+      else()
+        set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}")
+      endif()
     endif()
     # else example:
     #set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm")
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index bd55206..7f89d5e 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -105,38 +105,141 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup)
   packageFileNames.clear();
   std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
 
-  // The default behavior is to have one package by component group
-  // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
-  if (!ignoreGroup) {
-    std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
-    for (compGIt = this->ComponentGroups.begin();
-         compGIt != this->ComponentGroups.end(); ++compGIt) {
-      cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
-                      << compGIt->first << std::endl);
-      retval &= PackageOnePack(initialTopLevel, compGIt->first);
+  const char* mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT");
+
+  if (mainComponent) {
+    std::string mainComponentUpper(mainComponent);
+    std::transform(mainComponentUpper.begin(), mainComponentUpper.end(),
+                   mainComponentUpper.begin(), ::toupper);
+
+    // The default behavior is to have one package by component group
+    // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+    if (!ignoreGroup) {
+      std::map<std::string, cmCPackComponentGroup>::iterator mainCompGIt =
+        this->ComponentGroups.end();
+
+      std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+      for (compGIt = this->ComponentGroups.begin();
+           compGIt != this->ComponentGroups.end(); ++compGIt) {
+        std::string component(compGIt->first);
+        std::transform(component.begin(), component.end(), component.begin(),
+                       ::toupper);
+
+        if (mainComponentUpper == component) {
+          // main component will be handled last
+          mainCompGIt = compGIt;
+          continue;
+        }
+
+        cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+                        << compGIt->first << std::endl);
+        retval &= PackageOnePack(initialTopLevel, compGIt->first);
+      }
+      // Handle Orphan components (components not belonging to any groups)
+      std::map<std::string, cmCPackComponent>::iterator mainCompIt =
+        this->Components.end();
+      std::map<std::string, cmCPackComponent>::iterator compIt;
+      for (compIt = this->Components.begin(); compIt != this->Components.end();
+           ++compIt) {
+        // Does the component belong to a group?
+        if (compIt->second.Group == CM_NULLPTR) {
+          std::string component(compIt->first);
+          std::transform(component.begin(), component.end(), component.begin(),
+                         ::toupper);
+
+          if (mainComponentUpper == component) {
+            // main component will be handled last
+            mainCompIt = compIt;
+            continue;
+          }
+
+          cmCPackLogger(
+            cmCPackLog::LOG_VERBOSE, "Component <"
+              << compIt->second.Name
+              << "> does not belong to any group, package it separately."
+              << std::endl);
+          retval &= PackageOnePack(initialTopLevel, compIt->first);
+        }
+      }
+
+      if (retval) {
+        if (mainCompGIt != this->ComponentGroups.end()) {
+          retval &= PackageOnePack(initialTopLevel, mainCompGIt->first);
+        } else if (mainCompIt != this->Components.end()) {
+          retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
+        } else {
+          cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT set"
+                          << " to non existing component.\n");
+          retval = 0;
+        }
+      }
     }
-    // Handle Orphan components (components not belonging to any groups)
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
-      // Does the component belong to a group?
-      if (compIt->second.Group == CM_NULLPTR) {
-        cmCPackLogger(
-          cmCPackLog::LOG_VERBOSE, "Component <"
-            << compIt->second.Name
-            << "> does not belong to any group, package it separately."
-            << std::endl);
+    // CPACK_COMPONENTS_IGNORE_GROUPS is set
+    // We build 1 package per component
+    else {
+      std::map<std::string, cmCPackComponent>::iterator mainCompIt =
+        this->Components.end();
+
+      std::map<std::string, cmCPackComponent>::iterator compIt;
+      for (compIt = this->Components.begin(); compIt != this->Components.end();
+           ++compIt) {
+        std::string component(compIt->first);
+        std::transform(component.begin(), component.end(), component.begin(),
+                       ::toupper);
+
+        if (mainComponentUpper == component) {
+          // main component will be handled last
+          mainCompIt = compIt;
+          continue;
+        }
+
         retval &= PackageOnePack(initialTopLevel, compIt->first);
       }
+
+      if (retval) {
+        if (mainCompIt != this->Components.end()) {
+          retval &= PackageOnePack(initialTopLevel, mainCompIt->first);
+        } else {
+          cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT set"
+                          << " to non existing component.\n");
+          retval = 0;
+        }
+      }
     }
-  }
-  // CPACK_COMPONENTS_IGNORE_GROUPS is set
-  // We build 1 package per component
-  else {
-    std::map<std::string, cmCPackComponent>::iterator compIt;
-    for (compIt = this->Components.begin(); compIt != this->Components.end();
-         ++compIt) {
-      retval &= PackageOnePack(initialTopLevel, compIt->first);
+  } else {
+    // The default behavior is to have one package by component group
+    // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
+    if (!ignoreGroup) {
+      std::map<std::string, cmCPackComponentGroup>::iterator compGIt;
+      for (compGIt = this->ComponentGroups.begin();
+           compGIt != this->ComponentGroups.end(); ++compGIt) {
+        cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: "
+                        << compGIt->first << std::endl);
+        retval &= PackageOnePack(initialTopLevel, compGIt->first);
+      }
+      // Handle Orphan components (components not belonging to any groups)
+      std::map<std::string, cmCPackComponent>::iterator compIt;
+      for (compIt = this->Components.begin(); compIt != this->Components.end();
+           ++compIt) {
+        // Does the component belong to a group?
+        if (compIt->second.Group == CM_NULLPTR) {
+          cmCPackLogger(
+            cmCPackLog::LOG_VERBOSE, "Component <"
+              << compIt->second.Name
+              << "> does not belong to any group, package it separately."
+              << std::endl);
+          retval &= PackageOnePack(initialTopLevel, compIt->first);
+        }
+      }
+    }
+    // CPACK_COMPONENTS_IGNORE_GROUPS is set
+    // We build 1 package per component
+    else {
+      std::map<std::string, cmCPackComponent>::iterator compIt;
+      for (compIt = this->Components.begin(); compIt != this->Components.end();
+           ++compIt) {
+        retval &= PackageOnePack(initialTopLevel, compIt->first);
+      }
     }
   }
 
diff --git a/Tests/RunCMake/CPack/MAIN_COMPONENT.cmake b/Tests/RunCMake/CPack/MAIN_COMPONENT.cmake
new file mode 100644
index 0000000..99c6cae
--- /dev/null
+++ b/Tests/RunCMake/CPack/MAIN_COMPONENT.cmake
@@ -0,0 +1,14 @@
+set(CPACK_RPM_COMPONENT_INSTALL "ON")
+
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT applications)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
+install(FILES CMakeLists.txt DESTINATION bas COMPONENT libs)
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "invalid")
+  set(CPACK_RPM_MAIN_COMPONENT "")
+else()
+  set(CPACK_RPM_MAIN_COMPONENT "applications")
+  set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT")
+endif()
+
+set(CPACK_PACKAGE_NAME "main_component")
diff --git a/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake
new file mode 100644
index 0000000..69603dd
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake
@@ -0,0 +1,13 @@
+set(whitespaces_ "[\t\n\r ]*")
+
+set(EXPECTED_FILES_COUNT "0")
+
+if(NOT RunCMake_SUBTEST_SUFFIX STREQUAL "invalid")
+  set(EXPECTED_FILES_COUNT "3")
+  set(EXPECTED_FILE_1 "main_component-0.1.1-1.*.rpm")
+  set(EXPECTED_FILE_CONTENT_1 "^/usr/foo${whitespaces_}/usr/foo/CMakeLists.txt$")
+  set(EXPECTED_FILE_2 "main_component*-headers.rpm")
+  set(EXPECTED_FILE_CONTENT_2 "^/usr/bar${whitespaces_}/usr/bar/CMakeLists.txt$")
+  set(EXPECTED_FILE_3 "main_component*-libs.rpm")
+  set(EXPECTED_FILE_CONTENT_3 "^/usr/bas${whitespaces_}/usr/bas/CMakeLists.txt$")
+endif()
diff --git a/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt
new file mode 100644
index 0000000..dff163d
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt
@@ -0,0 +1,3 @@
+^CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MAIN_COMPONENT-build-found-subtest/_CPack_Packages/.*/RPM/SPECS/main_component-headers.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MAIN_COMPONENT-build-found-subtest/_CPack_Packages/.*/RPM/SPECS/main_component-libs.spec
+CPackRPM: Will use GENERATED spec file: .*/Tests/RunCMake/RPM/CPack/MAIN_COMPONENT-build-found-subtest/_CPack_Packages/.*/RPM/SPECS/main_component.spec$
diff --git a/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt
new file mode 100644
index 0000000..4d8ac6e
--- /dev/null
+++ b/Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt
@@ -0,0 +1 @@
+CPACK_RPM_MAIN_COMPONENT set to non existing component.
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 60d42ac..45dbcea 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -12,6 +12,7 @@ run_cpack_test(DEPENDENCIES "RPM;DEB" true)
 run_cpack_test(EMPTY_DIR "RPM;DEB;TGZ" true)
 run_cpack_test(COMPONENTS_EMPTY_DIR "RPM;DEB;TGZ" true)
 run_cpack_test(CUSTOM_NAMES "RPM;DEB" true)
+run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM" false)
 run_cpack_test(PER_COMPONENT_FIELDS "RPM;DEB" false)
 run_cpack_test(RPM_DIST "RPM" false)
 run_cpack_test(INSTALL_SCRIPTS "RPM" false)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b39bd548f9f1f96a2285e5aff638085352c21f29
commit b39bd548f9f1f96a2285e5aff638085352c21f29
Author:     Domen Vrankar <domen.vrankar at gmail.com>
AuthorDate: Thu Oct 6 08:04:58 2016 +0200
Commit:     Domen Vrankar <domen.vrankar at gmail.com>
CommitDate: Thu Oct 6 08:42:43 2016 +0200

    CPack/RPM debuginfo package without binaries
    
    Handle case when a component doesn't contain
    any debuginfo symbols.

diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 8f3f7ca..15b62c7 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -1477,16 +1477,22 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
     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(LENGTH mkdir_list_ len_)
+  if(len_)
+    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()
+  endif()
 
-  list(REMOVE_DUPLICATES cp_list_)
-  foreach(part_ IN LISTS cp_list_)
-    string(APPEND TMP_RPM_DEBUGINFO_INSTALL "${part_}\n")
-  endforeach()
+  list(LENGTH cp_list_ len_)
+  if(len_)
+    list(REMOVE_DUPLICATES cp_list_)
+    foreach(part_ IN LISTS cp_list_)
+      string(APPEND TMP_RPM_DEBUGINFO_INSTALL "${part_}\n")
+    endforeach()
+  endif()
 
   if(NOT DEFINED CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS)
     set(CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS /usr /usr/src /usr/src/debug)
@@ -1501,29 +1507,34 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
     message("CPackRPM:Debug: CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS= ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS}")
   endif()
 
-  list(REMOVE_DUPLICATES additional_sources_)
-  unset(additional_sources_all_)
-  foreach(source_ IN LISTS additional_sources_)
-    string(REPLACE "/" ";" split_source_ " ${source_}")
-    list(REMOVE_AT split_source_ 0)
-    unset(tmp_path_)
-    # Now generate all segments of the path
-    foreach(segment_ IN LISTS split_source_)
-      string(APPEND tmp_path_ "/${segment_}")
-      list(APPEND additional_sources_all_ "${tmp_path_}")
+  list(LENGTH additional_sources_ len_)
+  if(len_)
+    list(REMOVE_DUPLICATES additional_sources_)
+    unset(additional_sources_all_)
+    foreach(source_ IN LISTS additional_sources_)
+      string(REPLACE "/" ";" split_source_ " ${source_}")
+      list(REMOVE_AT split_source_ 0)
+      unset(tmp_path_)
+      # Now generate all segments of the path
+      foreach(segment_ IN LISTS split_source_)
+        string(APPEND tmp_path_ "/${segment_}")
+        list(APPEND additional_sources_all_ "${tmp_path_}")
+      endforeach()
     endforeach()
-  endforeach()
 
-  list(REMOVE_DUPLICATES additional_sources_all_)
-  list(REMOVE_ITEM additional_sources_all_ ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS})
+    list(REMOVE_DUPLICATES additional_sources_all_)
+    list(REMOVE_ITEM additional_sources_all_
+      ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS})
 
-  unset(TMP_DEBUGINFO_ADDITIONAL_SOURCES)
-  foreach(source_ IN LISTS additional_sources_all_)
-    string(APPEND TMP_DEBUGINFO_ADDITIONAL_SOURCES "${source_}\n")
-  endforeach()
+    unset(TMP_DEBUGINFO_ADDITIONAL_SOURCES)
+    foreach(source_ IN LISTS additional_sources_all_)
+      string(APPEND TMP_DEBUGINFO_ADDITIONAL_SOURCES "${source_}\n")
+    endforeach()
+  endif()
 
   set(TMP_RPM_DEBUGINFO_INSTALL "${TMP_RPM_DEBUGINFO_INSTALL}" PARENT_SCOPE)
-  set(TMP_DEBUGINFO_ADDITIONAL_SOURCES "${TMP_DEBUGINFO_ADDITIONAL_SOURCES}" PARENT_SCOPE)
+  set(TMP_DEBUGINFO_ADDITIONAL_SOURCES "${TMP_DEBUGINFO_ADDITIONAL_SOURCES}"
+    PARENT_SCOPE)
 endfunction()
 
 function(cpack_rpm_variable_fallback OUTPUT_VAR_NAME)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bf7d0168bfdfbe1b91bae83dd0091af54e7c4e8a
commit bf7d0168bfdfbe1b91bae83dd0091af54e7c4e8a
Author:     Domen Vrankar <domen.vrankar at gmail.com>
AuthorDate: Wed Oct 5 22:31:41 2016 +0200
Commit:     Domen Vrankar <domen.vrankar at gmail.com>
CommitDate: Thu Oct 6 08:42:43 2016 +0200

    CPack/RPM debuginfo package objdump error suppression
    
    objdump prints out error text if file is not an
    executable and that should be suppressed as we
    don't care about non executable files during that
    test

diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake
index 3bbaae9..8f3f7ca 100644
--- a/Modules/CPackRPM.cmake
+++ b/Modules/CPackRPM.cmake
@@ -1427,7 +1427,8 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
     execute_process(COMMAND "${OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F}
                     WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}"
                     RESULT_VARIABLE OBJDUMP_EXEC_RESULT
-                    OUTPUT_VARIABLE OBJDUMP_OUT)
+                    OUTPUT_VARIABLE OBJDUMP_OUT
+                    ERROR_QUIET)
     # Check that if the given file was executable or not
     if(NOT OBJDUMP_EXEC_RESULT)
       string(FIND "${OBJDUMP_OUT}" "debug" FIND_RESULT)

-----------------------------------------------------------------------

Summary of changes:
 Help/release/dev/cpack-rpm-single-debuginfo.rst    |   11 +
 Modules/CPackRPM.cmake                             |  390 +++++++++++++++-----
 Source/CMakeVersion.cmake                          |    2 +-
 Source/CPack/cmCPackRPMGenerator.cxx               |  245 ++++++++++--
 Tests/RunCMake/CPack/MAIN_COMPONENT.cmake          |   14 +
 .../CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake   |   13 +
 .../CPack/RPM/MAIN_COMPONENT-found-stderr.txt      |    3 +
 .../CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt    |    1 +
 .../CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake |   30 ++
 .../RPM/SINGLE_DEBUGINFO-no_components-stderr.txt  |    1 +
 .../RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt   |    3 +
 .../SINGLE_DEBUGINFO-no_main_component-stderr.txt  |    1 +
 .../RPM/SINGLE_DEBUGINFO-one_component-stderr.txt  |    1 +
 .../SINGLE_DEBUGINFO-one_component_main-stderr.txt |    1 +
 ...DEBUGINFO-one_component_no_debuginfo-stderr.txt |    1 +
 .../CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt    |    3 +
 Tests/RunCMake/CPack/RunCMakeTest.cmake            |    2 +
 Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake        |   56 +++
 18 files changed, 665 insertions(+), 113 deletions(-)
 create mode 100644 Help/release/dev/cpack-rpm-single-debuginfo.rst
 create mode 100644 Tests/RunCMake/CPack/MAIN_COMPONENT.cmake
 create mode 100644 Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-ExpectedFiles.cmake
 create mode 100644 Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-found-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/MAIN_COMPONENT-invalid-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-ExpectedFiles.cmake
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_components-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_debuginfo-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-no_main_component-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_main-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-one_component_no_debuginfo-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/RPM/SINGLE_DEBUGINFO-valid-stderr.txt
 create mode 100644 Tests/RunCMake/CPack/SINGLE_DEBUGINFO.cmake


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list