Browse Source

CPackWiX: Add support for CPACK_CREATE_DESKTOP_LINKS

Timo Rothenpieler 11 years ago
parent
commit
b78d74de64

+ 3 - 1
Modules/CPack.cmake

@@ -174,7 +174,7 @@
 #  create Start Menu shortcuts. For example, setting this to the list
 #  ccmake;CMake will create a shortcut named "CMake" that will execute the
 #  installed executable ccmake. Not all CPack generators use it (at least
-#  NSIS and OSXX11 do).
+#  NSIS, WIX and OSXX11 do).
 #
 # .. variable:: CPACK_STRIP_FILES
 #
@@ -261,6 +261,8 @@
 # .. variable:: CPACK_CREATE_DESKTOP_LINKS
 #
 #  List of desktop links to create.
+#  Each desktop link requires a corresponding start menu shortcut
+#  as created by :variable:`CPACK_PACKAGE_EXECUTABLES`.
 
 #=============================================================================
 # Copyright 2006-2009 Kitware, Inc.

+ 101 - 2
Source/CPack/WiX/cmCPackWIXGenerator.cxx

@@ -31,6 +31,12 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+cmCPackWIXGenerator::cmCPackWIXGenerator():
+  HasDesktopShortcuts(false)
+{
+
+}
+
 int cmCPackWIXGenerator::InitializeInternal()
 {
   componentPackageMethod = ONE_PACKAGE;
@@ -519,6 +525,11 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
     CreateStartMenuFolder(directoryDefinitions);
     }
 
+  if(this->HasDesktopShortcuts)
+    {
+    CreateDesktopFolder(directoryDefinitions);
+    }
+
   directoryDefinitions.EndElement("Directory");
   directoryDefinitions.EndElement("Fragment");
 
@@ -733,10 +744,20 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
         }
     }
 
+  std::vector<std::string> cpackPackageDesktopLinksList;
+  const char *cpackPackageDesktopLinks =
+    GetOption("CPACK_CREATE_DESKTOP_LINKS");
+  if(cpackPackageDesktopLinks)
+    {
+      cmSystemTools::ExpandListArgument(cpackPackageDesktopLinks,
+        cpackPackageDesktopLinksList);
+    }
+
   AddDirectoryAndFileDefinitons(
     rootPath, "INSTALL_ROOT",
     directoryDefinitions, fileDefinitions, featureDefinitions,
-    cpackPackageExecutablesList, shortcutMap);
+    cpackPackageExecutablesList, cpackPackageDesktopLinksList,
+    shortcutMap);
 
   featureDefinitions.EndElement("FeatureRef");
 
@@ -750,6 +771,8 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
   cmWIXSourceWriter& fileDefinitions,
   cmWIXSourceWriter& featureDefinitions)
 {
+  bool thisHasDesktopShortcuts = false;
+
   featureDefinitions.BeginElement("FeatureRef");
   featureDefinitions.AddAttribute("Id", featureId);
 
@@ -797,6 +820,11 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
     fileDefinitions.AddAttribute("WorkingDirectory",
       shortcut.workingDirectoryId);
     fileDefinitions.EndElement("Shortcut");
+
+    if (shortcut.desktop)
+      {
+        thisHasDesktopShortcuts = true;
+      }
     }
 
   if(cpackComponentName.empty())
@@ -805,7 +833,8 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
     }
 
   fileDefinitions.BeginElement("RemoveFolder");
-  fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER" + idSuffix);
+  fileDefinitions.AddAttribute("Id",
+    "CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix);
   fileDefinitions.AddAttribute("On", "uninstall");
   fileDefinitions.EndElement("RemoveFolder");
 
@@ -836,6 +865,56 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
   featureDefinitions.AddAttribute("Id", componentId);
   featureDefinitions.EndElement("ComponentRef");
 
+  if (thisHasDesktopShortcuts)
+    {
+    this->HasDesktopShortcuts = true;
+    componentId = "CM_DESKTOP_SHORTCUT" + idSuffix;
+
+    fileDefinitions.BeginElement("DirectoryRef");
+    fileDefinitions.AddAttribute("Id", "DesktopFolder");
+    fileDefinitions.BeginElement("Component");
+    fileDefinitions.AddAttribute("Id", componentId);
+    fileDefinitions.AddAttribute("Guid", "*");
+
+    for (shortcut_map_t::const_iterator
+      i = shortcutMap.begin(); i != shortcutMap.end(); ++i)
+      {
+      std::string const& id = i->first;
+      cmWIXShortcut const& shortcut = i->second;
+
+      if (!shortcut.desktop)
+        continue;
+
+      std::string shortcutId = std::string("CM_DS") + id;
+      std::string fileId = std::string("CM_F") + id;
+
+      fileDefinitions.BeginElement("Shortcut");
+      fileDefinitions.AddAttribute("Id", shortcutId);
+      fileDefinitions.AddAttribute("Name", shortcut.textLabel);
+      std::string target = "[#" + fileId + "]";
+      fileDefinitions.AddAttribute("Target", target);
+      fileDefinitions.AddAttribute("WorkingDirectory",
+        shortcut.workingDirectoryId);
+      fileDefinitions.EndElement("Shortcut");
+      }
+
+    fileDefinitions.BeginElement("RegistryValue");
+    fileDefinitions.AddAttribute("Root", "HKCU");
+    fileDefinitions.AddAttribute("Key", registryKey);
+    fileDefinitions.AddAttribute("Name", valueName + "_desktop");
+    fileDefinitions.AddAttribute("Type", "integer");
+    fileDefinitions.AddAttribute("Value", "1");
+    fileDefinitions.AddAttribute("KeyPath", "yes");
+    fileDefinitions.EndElement("RegistryValue");
+
+    fileDefinitions.EndElement("Component");
+    fileDefinitions.EndElement("DirectoryRef");
+
+    featureDefinitions.BeginElement("ComponentRef");
+    featureDefinitions.AddAttribute("Id", componentId);
+    featureDefinitions.EndElement("ComponentRef");
+    }
+
   featureDefinitions.EndElement("FeatureRef");
 
   return true;
@@ -908,6 +987,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
   cmWIXSourceWriter& fileDefinitions,
   cmWIXSourceWriter& featureDefinitions,
   const std::vector<std::string>& packageExecutables,
+  const std::vector<std::string>& desktopExecutables,
   shortcut_map_t& shortcutMap)
 {
   cmsys::Directory dir;
@@ -943,6 +1023,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
         fileDefinitions,
         featureDefinitions,
         packageExecutables,
+        desktopExecutables,
         shortcutMap);
 
       ApplyPatchFragment(subDirectoryId, directoryDefinitions);
@@ -995,6 +1076,15 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
           cmWIXShortcut &shortcut = shortcutMap[id];
           shortcut.textLabel= textLabel;
           shortcut.workingDirectoryId = directoryId;
+
+          if(desktopExecutables.size() &&
+             std::find(desktopExecutables.begin(),
+                       desktopExecutables.end(),
+                       executableName)
+             != desktopExecutables.end())
+            {
+              shortcut.desktop = true;
+            }
           }
         }
       }
@@ -1232,6 +1322,15 @@ void cmCPackWIXGenerator::CreateStartMenuFolder(
   directoryDefinitions.EndElement("Directory");
 }
 
+void cmCPackWIXGenerator::CreateDesktopFolder(
+    cmWIXSourceWriter& directoryDefinitions)
+{
+    directoryDefinitions.BeginElement("Directory");
+    directoryDefinitions.AddAttribute("Id", "DesktopFolder");
+    directoryDefinitions.AddAttribute("Name", "Desktop");
+    directoryDefinitions.EndElement("Directory");
+}
+
 void cmCPackWIXGenerator::LoadPatchFragments(const std::string& patchFilePath)
 {
   cmWIXPatchParser parser(Fragments, Logger);

+ 12 - 0
Source/CPack/WiX/cmCPackWIXGenerator.h

@@ -22,8 +22,13 @@
 
 struct cmWIXShortcut
 {
+  cmWIXShortcut()
+    :desktop(false)
+    {}
+
   std::string textLabel;
   std::string workingDirectoryId;
+  bool desktop;
 };
 
 class cmWIXSourceWriter;
@@ -36,6 +41,8 @@ class cmCPackWIXGenerator : public cmCPackGenerator
 public:
   cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
 
+  cmCPackWIXGenerator();
+
 protected:
   virtual int InitializeInternal();
 
@@ -133,6 +140,7 @@ private:
     cmWIXSourceWriter& fileDefinitions,
     cmWIXSourceWriter& featureDefinitions,
     const std::vector<std::string>& pkgExecutables,
+    const std::vector<std::string>& desktopExecutables,
     shortcut_map_t& shortcutMap);
 
   bool RequireOption(const std::string& name, std::string& value) const;
@@ -165,6 +173,8 @@ private:
 
   void CreateStartMenuFolder(cmWIXSourceWriter& directoryDefinitions);
 
+  void CreateDesktopFolder(cmWIXSourceWriter& directoryDefinitions);
+
   void LoadPatchFragments(const std::string& patchFilePath);
 
   void ApplyPatchFragment(const std::string& id, cmWIXSourceWriter& writer);
@@ -180,6 +190,8 @@ private:
   extension_set_t LightExtensions;
 
   cmWIXPatchParser::fragment_map_t Fragments;
+
+  bool HasDesktopShortcuts;
 };
 
 #endif

+ 5 - 0
Tests/CPackWiXGenerator/CMakeLists.txt

@@ -49,6 +49,11 @@ set(CPACK_PACKAGE_EXECUTABLES
   "my-other-app" "Second CPack WiX Test"
 )
 
+set(CPACK_CREATE_DESKTOP_LINKS
+  "my-libapp"
+  "my-other-app"
+)
+
 set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/patch.xml")
 
 set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt")