diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index ccc36eb71..89547af2d 100644 --- a/Modules/CPack.cmake +++ b/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. diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 998b5f105..43119d6a5 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -31,6 +31,12 @@ #include #include +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 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& packageExecutables, + const std::vector& 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); diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index 1f4facfbc..1de4810ba 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/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& pkgExecutables, + const std::vector& 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 diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt index bc3322ef3..d673d145d 100644 --- a/Tests/CPackWiXGenerator/CMakeLists.txt +++ b/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")