浏览代码

cpack: Add `CPACK_INSTALL_CMAKE_CONFIGURATIONS` variable

For the multi-configuration generators one can specify the list
of configurations to include in the package.

E.g. having a project, where debug libraries have a suffix to
distinct them from the release builds, one can build the package
containing both `Debug` and `Release` binaries.
Alex Turbov 6 年之前
父节点
当前提交
da5ac4bb60

+ 5 - 3
Help/manual/cpack.1.rst

@@ -48,9 +48,11 @@ Options
   the :variable:`CPACK_GENERATOR` variable determines the default set of
   generators that will be used.
 
-``-C <Configuration>``
-  Specify the project configuration to be packaged (e.g. ``Debug``,
-  ``Release``, etc.).  When the CMake project uses a multi-configuration
+``-C <configs>``
+  Specify the project configuration(s) to be packaged (e.g. ``Debug``,
+  ``Release``, etc.), where ``<configs>`` is a
+  :ref:`semicolon-separated list <CMake Language Lists>`.
+  When the CMake project uses a multi-configuration
   generator such as Xcode or Visual Studio, this option is needed to tell
   ``cpack`` which built executables to include in the package.
 

+ 5 - 0
Help/release/dev/cpack-install-multiple-configurations.rst

@@ -0,0 +1,5 @@
+cpack-install-multiple-configurations
+-------------------------------------
+
+* CPack learned :variable:`CPACK_INSTALL_CMAKE_CONFIGURATIONS` to control
+  what configurations going to be packaged for multi-configuration generators.

+ 7 - 0
Modules/CPack.cmake

@@ -301,6 +301,13 @@ The following variables are for advanced uses of CPack:
   project.  Defaults to the value of :variable:`CMAKE_GENERATOR`.  Few users
   will want to change this setting.
 
+.. variable:: CPACK_INSTALL_CMAKE_CONFIGURATIONS
+
+  Specify the project configurations to be packaged (e.g. ``Debug``, ``Release``,
+  etc.). When the CMake project uses a multi-configuration generator such as Xcode
+  or Visual Studio, this option can be used to specify what configurations
+  to include in the package.
+
 .. variable:: CPACK_INSTALL_CMAKE_PROJECTS
 
   List of four values that specify what project to install.  The four values

+ 47 - 17
Source/CPack/cmCPackGenerator.cxx

@@ -598,8 +598,34 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
         componentsVector.push_back(project.Component);
       }
 
-      const char* buildConfigCstr = this->GetOption("CPACK_BUILD_CONFIG");
-      std::string buildConfig = buildConfigCstr ? buildConfigCstr : "";
+      std::vector<std::string> buildConfigs;
+
+      // Try get configuration names given via `-C` CLI option
+      {
+        const char* const buildConfigCstr =
+          this->GetOption("CPACK_BUILD_CONFIG");
+        auto buildConfig = buildConfigCstr ? buildConfigCstr : std::string{};
+        cmExpandList(buildConfig, buildConfigs);
+      }
+
+      // Try get configurations requested by the user explicitly
+      {
+        const char* const configsCstr =
+          this->GetOption("CPACK_INSTALL_CMAKE_CONFIGURATIONS");
+        auto configs = configsCstr ? configsCstr : std::string{};
+        cmExpandList(configs, buildConfigs);
+      }
+
+      // Remove duplicates
+      std::sort(buildConfigs.begin(), buildConfigs.end());
+      buildConfigs.erase(std::unique(buildConfigs.begin(), buildConfigs.end()),
+                         buildConfigs.end());
+
+      // Ensure we have at least one configuration.
+      if (buildConfigs.empty()) {
+        buildConfigs.emplace_back();
+      }
+
       std::unique_ptr<cmGlobalGenerator> globalGenerator(
         this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
           cmakeGenerator));
@@ -615,25 +641,29 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
       // on windows.
       cmSystemTools::SetForceUnixPaths(globalGenerator->GetForceUnixPaths());
 
-      if (!this->RunPreinstallTarget(project.ProjectName, project.Directory,
-                                     globalGenerator.get(), buildConfig)) {
-        return 0;
-      }
-
-      cmCPackLogger(cmCPackLog::LOG_OUTPUT,
-                    "- Install project: " << project.ProjectName << std::endl);
-
-      // Run the installation for each component
-      for (std::string const& component : componentsVector) {
-        if (!this->InstallCMakeProject(
-              setDestDir, project.Directory, baseTempInstallDirectory,
-              default_dir_mode, component, componentInstall,
-              project.SubDirectory, buildConfig, absoluteDestFiles)) {
+      // Run the installation for the selected build configurations
+      for (auto const& buildConfig : buildConfigs) {
+        if (!this->RunPreinstallTarget(project.ProjectName, project.Directory,
+                                       globalGenerator.get(), buildConfig)) {
           return 0;
         }
+
+        cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                      "- Install project: " << project.ProjectName << " ["
+                                            << buildConfig << ']'
+                                            << std::endl);
+        // Run the installation for each component
+        for (std::string const& component : componentsVector) {
+          if (!this->InstallCMakeProject(
+                setDestDir, project.Directory, baseTempInstallDirectory,
+                default_dir_mode, component, componentInstall,
+                project.SubDirectory, buildConfig, absoluteDestFiles)) {
+            return 0;
+          }
+        }
       }
 
-      this->CMakeProjects.push_back(project);
+      this->CMakeProjects.emplace_back(std::move(project));
     }
   }
   this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",

+ 3 - 0
Tests/RunCMake/CPack/RunCMakeTest.cmake

@@ -36,3 +36,6 @@ run_cpack_test(MD5SUMS "DEB.MD5SUMS" false "MONOLITHIC;COMPONENT")
 run_cpack_test_subtests(CPACK_INSTALL_SCRIPTS "singular;plural;both" "ZIP" false "MONOLITHIC")
 run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB.DEB_PACKAGE_VERSION_BACK_COMPATIBILITY" false "MONOLITHIC;COMPONENT")
 run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT")
+if(RunCMake_GENERATOR MATCHES "Visual Studio|Xcode")
+  run_cpack_test(CPACK_INSTALL_CMAKE_CONFIGURATIONS "ZIP" false "MONOLITHIC")
+endif()

+ 3 - 0
Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ExpectedFiles.cmake

@@ -0,0 +1,3 @@
+set(EXPECTED_FILES_COUNT "1")
+
+set(EXPECTED_FILE_CONTENT_1_LIST "foo;foo/debug.txt;foo/release.txt")

+ 3 - 0
Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/ZIP-stdout.txt

@@ -0,0 +1,3 @@
+CPack: Install projects
+CPack: - Install project: CPACK_INSTALL_CMAKE_CONFIGURATIONS-MONOLITHIC-type \[Debug\]
+CPack: - Install project: CPACK_INSTALL_CMAKE_CONFIGURATIONS-MONOLITHIC-type \[Release\]

+ 9 - 0
Tests/RunCMake/CPack/tests/CPACK_INSTALL_CMAKE_CONFIGURATIONS/test.cmake

@@ -0,0 +1,9 @@
+set(CMAKE_CONFIGURATION_TYPES Debug Release)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/debug.txt" "debug content")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/release.txt" "release content")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/debug.txt" DESTINATION "foo" CONFIGURATIONS Debug)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/release.txt" DESTINATION "foo" CONFIGURATIONS Release)
+
+set(CPACK_INSTALL_CMAKE_CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})