Просмотр исходного кода

Merge topic 'wix-multi-cab'

193f17102f CPack/WiX: Implement opt-in per component .cab

Acked-by: Kitware Robot <[email protected]>
Merge-request: !11166
Brad King 6 месяцев назад
Родитель
Сommit
568e3318bc

+ 9 - 0
Help/cpack_gen/wix.rst

@@ -487,3 +487,12 @@ Windows using WiX.
      first manually uninstall any older version.
 
  See https://docs.firegiant.com/wix3/xsd/wix/package/
+
+.. variable:: CPACK_WIX_CAB_PER_COMPONENT
+
+ .. versionadded:: 4.2
+
+ If this variable is set to true one `.cab` file per component is created.
+ The default is to create a single `.cab` file for all files in the installer.
+
+ WiX creates `.cab` files in parallel so multiple `.cab` files may be desirable for faster packaging.

+ 6 - 0
Help/release/dev/wix-multi-cab.rst

@@ -0,0 +1,6 @@
+wix-multi-cab
+-------------
+
+* :variable:`CPACK_WIX_CAB_PER_COMPONENT` allows CPack WIX opt-in generation of one
+  `.cab` file per component. Having multiple `.cab` files may improve the time it takes
+  to generate installers and may also work around per `.cab` size constraints.

+ 2 - 0
Modules/Internal/CPack/WIX-v3/WIX.template.in

@@ -19,7 +19,9 @@
         <Package InstallerVersion="301" Compressed="yes" InstallScope="$(var.CPACK_WIX_INSTALL_SCOPE)"/>
         <?endif?>
 
+        <?ifndef CPACK_WIX_CAB_PER_COMPONENT?>
         <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+        <?endif?>
 
         <MajorUpgrade
             Schedule="afterInstallInitialize"

+ 2 - 0
Modules/Internal/CPack/WIX.template.in

@@ -19,7 +19,9 @@
         Compressed="yes"
         >
 
+        <?ifndef CPACK_WIX_CAB_PER_COMPONENT?>
         <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+        <?endif?>
 
         <MajorUpgrade
             Schedule="afterInstallInitialize"

+ 35 - 9
Source/CPack/WiX/cmCPackWIXGenerator.cxx

@@ -430,6 +430,7 @@ void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
   CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
   CopyDefinition(includeFile, "CPACK_WIX_UI_REF");
   CopyDefinition(includeFile, "CPACK_WIX_INSTALL_SCOPE");
+  CopyDefinition(includeFile, "CPACK_WIX_CAB_PER_COMPONENT");
 }
 
 void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
@@ -492,6 +493,22 @@ void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
                                 cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);
   InjectXmlNamespaces(includeFile);
 
+  bool perComponentCab = GetOption("CPACK_WIX_CAB_PER_COMPONENT").IsOn();
+
+  if (perComponentCab) {
+    std::size_t cabCount = std::max<std::size_t>(1, this->Components.size());
+
+    for (std::size_t i = 0; i < cabCount; ++i) {
+      std::string diskId = std::to_string(i + 1);
+
+      includeFile.BeginElement("Media");
+      includeFile.AddAttribute("Id", diskId);
+      includeFile.AddAttribute("Cabinet", "media" + diskId + ".cab");
+      includeFile.AddAttribute("EmbedCab", "yes");
+      includeFile.EndElement("Media");
+    }
+  }
+
   this->Patch->ApplyFragment("#PRODUCT", includeFile);
 }
 
@@ -617,11 +634,17 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
   if (Components.empty()) {
     AddComponentsToFeature(toplevel, "ProductFeature", directoryDefinitions,
                            fileDefinitions, featureDefinitions,
-                           globalShortcuts);
+                           globalShortcuts, 0);
 
     globalShortcuts.AddShortcutTypes(emittedShortcutTypes);
   } else {
+    bool perComponentCab = GetOption("CPACK_WIX_CAB_PER_COMPONENT").IsOn();
+
+    std::size_t componentDiskId = 0;
+
     for (auto const& i : this->Components) {
+      ++componentDiskId;
+
       cmCPackComponent const& component = i.second;
 
       std::string componentPath = cmStrCat(toplevel, '/', component.Name);
@@ -631,7 +654,8 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
       cmWIXShortcuts featureShortcuts;
       AddComponentsToFeature(componentPath, componentFeatureId,
                              directoryDefinitions, fileDefinitions,
-                             featureDefinitions, featureShortcuts);
+                             featureDefinitions, featureShortcuts,
+                             perComponentCab ? componentDiskId : 0);
 
       featureShortcuts.AddShortcutTypes(emittedShortcutTypes);
 
@@ -779,7 +803,8 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
   std::string const& rootPath, std::string const& featureId,
   cmWIXDirectoriesSourceWriter& directoryDefinitions,
   cmWIXFilesSourceWriter& fileDefinitions,
-  cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts)
+  cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts,
+  int diskId)
 {
   featureDefinitions.BeginElement("FeatureRef");
   featureDefinitions.AddAttribute("Id", featureId);
@@ -807,7 +832,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
   AddDirectoryAndFileDefinitions(
     rootPath, "INSTALL_ROOT", directoryDefinitions, fileDefinitions,
     featureDefinitions, cpackPackageExecutablesList,
-    cpackPackageDesktopLinksList, shortcuts);
+    cpackPackageDesktopLinksList, shortcuts, diskId);
 
   featureDefinitions.EndElement("FeatureRef");
 
@@ -995,7 +1020,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
   cmWIXFeaturesSourceWriter& featureDefinitions,
   std::vector<std::string> const& packageExecutables,
   std::vector<std::string> const& desktopExecutables,
-  cmWIXShortcuts& shortcuts)
+  cmWIXShortcuts& shortcuts, int diskId)
 {
   cmsys::Directory dir;
   dir.Load(topdir.c_str());
@@ -1054,9 +1079,10 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
       directoryDefinitions.AddAttribute("Name", fileName);
       this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
 
-      AddDirectoryAndFileDefinitions(
-        fullPath, subDirectoryId, directoryDefinitions, fileDefinitions,
-        featureDefinitions, packageExecutables, desktopExecutables, shortcuts);
+      AddDirectoryAndFileDefinitions(fullPath, subDirectoryId,
+                                     directoryDefinitions, fileDefinitions,
+                                     featureDefinitions, packageExecutables,
+                                     desktopExecutables, shortcuts, diskId);
 
       directoryDefinitions.EndElement("Directory");
     } else {
@@ -1068,7 +1094,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
       }
 
       std::string componentId = fileDefinitions.EmitComponentFile(
-        directoryId, id, fullPath, *(this->Patch), installedFile);
+        directoryId, id, fullPath, *(this->Patch), installedFile, diskId);
 
       featureDefinitions.EmitComponentRef(componentId);
 

+ 3 - 2
Source/CPack/WiX/cmCPackWIXGenerator.h

@@ -86,7 +86,8 @@ private:
     std::string const& rootPath, std::string const& featureId,
     cmWIXDirectoriesSourceWriter& directoryDefinitions,
     cmWIXFilesSourceWriter& fileDefinitions,
-    cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts);
+    cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts,
+    int diskId);
 
   bool CreateShortcuts(std::string const& cpackComponentName,
                        std::string const& featureId,
@@ -122,7 +123,7 @@ private:
     cmWIXFeaturesSourceWriter& featureDefinitions,
     std::vector<std::string> const& packageExecutables,
     std::vector<std::string> const& desktopExecutables,
-    cmWIXShortcuts& shortcuts);
+    cmWIXShortcuts& shortcuts, int diskId);
 
   bool RequireOption(std::string const& name, std::string& value) const;
 

+ 5 - 1
Source/CPack/WiX/cmWIXFilesSourceWriter.cxx

@@ -122,7 +122,7 @@ std::string cmWIXFilesSourceWriter::EmitComponentCreateFolder(
 std::string cmWIXFilesSourceWriter::EmitComponentFile(
   std::string const& directoryId, std::string const& id,
   std::string const& filePath, cmWIXPatch& patch,
-  cmInstalledFile const* installedFile)
+  cmInstalledFile const* installedFile, int diskId)
 {
   std::string componentId = std::string("CM_C") + id;
   std::string fileId = std::string("CM_F") + id;
@@ -136,6 +136,10 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
   AddAttribute("Id", componentId);
   AddAttribute("Guid", guid);
 
+  if (diskId) {
+    AddAttribute("DiskId", std::to_string(diskId));
+  }
+
   if (installedFile) {
     if (installedFile->GetPropertyAsBool("CPACK_NEVER_OVERWRITE")) {
       AddAttribute("NeverOverwrite", "yes");

+ 2 - 1
Source/CPack/WiX/cmWIXFilesSourceWriter.h

@@ -35,5 +35,6 @@ public:
   std::string EmitComponentFile(std::string const& directoryId,
                                 std::string const& id,
                                 std::string const& filePath, cmWIXPatch& patch,
-                                cmInstalledFile const* installedFile);
+                                cmInstalledFile const* installedFile,
+                                int diskId);
 };