diff options
author | Brad King <brad.king@kitware.com> | 2013-12-02 17:07:24 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2013-12-02 17:07:24 (GMT) |
commit | ed1de30da06a22bc6d9cfd147a99f7728f175802 (patch) | |
tree | 1b4c0899f270d04c7e099045e436688f46cf2e36 /Source/CPack | |
parent | 55f2a3d62754001fe44209f513ed81f90dab9338 (diff) | |
parent | 7b390f75e82ad79f6759656c52825c89e5c92902 (diff) | |
download | CMake-ed1de30da06a22bc6d9cfd147a99f7728f175802.zip CMake-ed1de30da06a22bc6d9cfd147a99f7728f175802.tar.gz CMake-ed1de30da06a22bc6d9cfd147a99f7728f175802.tar.bz2 |
Merge topic 'wix-components'
7b390f7 CPackWiX: add CPack component support
Diffstat (limited to 'Source/CPack')
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.cxx | 306 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.h | 31 | ||||
-rw-r--r-- | Source/CPack/WiX/cmWIXSourceWriter.cxx | 9 | ||||
-rw-r--r-- | Source/CPack/WiX/cmWIXSourceWriter.h | 3 |
4 files changed, 303 insertions, 46 deletions
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 1d7681b..91701c2 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -198,6 +198,18 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() << std::endl); } + if(GetOption("CPACK_WIX_UI_REF") == 0) + { + std::string defaultRef = "WixUI_InstallDir"; + + if(Components.size()) + { + defaultRef = "WixUI_FeatureTree"; + } + + SetOption("CPACK_WIX_UI_REF", defaultRef.c_str()); + } + CollectExtensions("CPACK_WIX_EXTENSIONS", candleExtensions); CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", candleExtensions); @@ -296,6 +308,7 @@ bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile() SetOptionIfNotSet("CPACK_WIX_PROGRAM_MENU_FOLDER", GetOption("CPACK_PACKAGE_NAME")); CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER"); + CopyDefinition(includeFile, "CPACK_WIX_UI_REF"); return true; } @@ -401,40 +414,77 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() featureDefinitions.BeginElement("Feature"); featureDefinitions.AddAttribute("Id", "ProductFeature"); - featureDefinitions.AddAttribute("Title", Name); + featureDefinitions.AddAttribute("Display", "expand"); + featureDefinitions.AddAttribute("ConfigurableDirectory", "INSTALL_ROOT"); + + std::string cpackPackageName; + if(!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName)) + { + return false; + } + featureDefinitions.AddAttribute("Title", cpackPackageName); + featureDefinitions.AddAttribute("Level", "1"); + + CreateFeatureHierarchy(featureDefinitions); + featureDefinitions.EndElement("Feature"); - featureDefinitions.BeginElement("FeatureRef"); - featureDefinitions.AddAttribute("Id", "ProductFeature"); + bool hasShortcuts = false; - std::vector<std::string> cpackPackageExecutablesList; - const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); - if(cpackPackageExecutables) + shortcut_map_t globalShortcuts; + if(Components.empty()) { - cmSystemTools::ExpandListArgument(cpackPackageExecutables, - cpackPackageExecutablesList); - if(cpackPackageExecutablesList.size() % 2 != 0 ) + AddComponentsToFeature(toplevel, "ProductFeature", + directoryDefinitions, fileDefinitions, featureDefinitions, + globalShortcuts); + if(globalShortcuts.size()) + { + hasShortcuts = true; + } + } + else + { + for(std::map<std::string, cmCPackComponent>::const_iterator + i = Components.begin(); i != Components.end(); ++i) + { + cmCPackComponent const& component = i->second; + + std::string componentPath = toplevel; + componentPath += "/"; + componentPath += component.Name; + + std::string componentFeatureId = "CM_C_" + component.Name; + + shortcut_map_t featureShortcuts; + AddComponentsToFeature(componentPath, componentFeatureId, + directoryDefinitions, fileDefinitions, + featureDefinitions, featureShortcuts); + if(featureShortcuts.size()) { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and " - "<text label>." << std::endl); - return false; + hasShortcuts = true; } - } - AddDirectoryAndFileDefinitons( - toplevel, "INSTALL_ROOT", - directoryDefinitions, fileDefinitions, featureDefinitions, - cpackPackageExecutablesList); + if(featureShortcuts.size()) + { + if(!CreateStartMenuShortcuts(component.Name, componentFeatureId, + featureShortcuts, fileDefinitions, featureDefinitions)) + { + return false; + } + } + } + } - if(!CreateStartMenuShortcuts( - directoryDefinitions, fileDefinitions, featureDefinitions)) + if(hasShortcuts) { + if(!CreateStartMenuShortcuts(std::string(), "ProductFeature", + globalShortcuts, fileDefinitions, featureDefinitions)) + { return false; + } } - featureDefinitions.EndElement("FeatureRef"); featureDefinitions.EndElement("Fragment"); fileDefinitions.EndElement("Fragment"); @@ -444,6 +494,12 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() } directoryDefinitions.EndElement("Directory"); + + if(hasShortcuts) + { + CreateStartMenuFolder(directoryDefinitions); + } + directoryDefinitions.EndElement("Directory"); directoryDefinitions.EndElement("Fragment"); @@ -475,16 +531,154 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() return true; } -bool cmCPackWIXGenerator::CreateStartMenuShortcuts( +bool cmCPackWIXGenerator::CreateFeatureHierarchy( + cmWIXSourceWriter& featureDefinitions) +{ + for(std::map<std::string, cmCPackComponentGroup>::const_iterator + i = ComponentGroups.begin(); i != ComponentGroups.end(); ++i) + { + cmCPackComponentGroup const& group = i->second; + if(group.ParentGroup == 0) + { + if(!EmitFeatureForComponentGroup(featureDefinitions, group)) + { + return false; + } + } + } + + for(std::map<std::string, cmCPackComponent>::const_iterator + i = Components.begin(); i != Components.end(); ++i) + { + cmCPackComponent const& component = i->second; + + if(!component.Group) + { + if(!EmitFeatureForComponent(featureDefinitions, component)) + { + return false; + } + } + } + + return true; +} + +bool cmCPackWIXGenerator::EmitFeatureForComponentGroup( + cmWIXSourceWriter& featureDefinitions, + cmCPackComponentGroup const& group) +{ + featureDefinitions.BeginElement("Feature"); + featureDefinitions.AddAttribute("Id", "CM_G_" + group.Name); + + if(group.IsExpandedByDefault) + { + featureDefinitions.AddAttribute("Display", "expand"); + } + + featureDefinitions.AddAttributeUnlessEmpty( + "Title", group.DisplayName); + + featureDefinitions.AddAttributeUnlessEmpty( + "Description", group.Description); + + for(std::vector<cmCPackComponentGroup*>::const_iterator + i = group.Subgroups.begin(); i != group.Subgroups.end(); ++i) + { + if(!EmitFeatureForComponentGroup(featureDefinitions, **i)) + { + return false; + } + } + + for(std::vector<cmCPackComponent*>::const_iterator + i = group.Components.begin(); i != group.Components.end(); ++i) + { + if(!EmitFeatureForComponent(featureDefinitions, **i)) + { + return false; + } + } + + featureDefinitions.EndElement("Feature"); + + return true; +} + +bool cmCPackWIXGenerator::EmitFeatureForComponent( + cmWIXSourceWriter& featureDefinitions, + cmCPackComponent const& component) +{ + featureDefinitions.BeginElement("Feature"); + featureDefinitions.AddAttribute("Id", "CM_C_" + component.Name); + + featureDefinitions.AddAttributeUnlessEmpty( + "Title", component.DisplayName); + + featureDefinitions.AddAttributeUnlessEmpty( + "Description", component.Description); + + if(component.IsRequired) + { + featureDefinitions.AddAttribute("Absent", "disallow"); + } + + if(component.IsHidden) + { + featureDefinitions.AddAttribute("Display", "hidden"); + } + + featureDefinitions.EndElement("Feature"); + + return true; +} + +bool cmCPackWIXGenerator::AddComponentsToFeature( + std::string const& rootPath, + std::string const& featureId, cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, - cmWIXSourceWriter& featureDefinitions) + cmWIXSourceWriter& featureDefinitions, + shortcut_map_t& shortcutMap) { - if(shortcutMap.empty()) + featureDefinitions.BeginElement("FeatureRef"); + featureDefinitions.AddAttribute("Id", featureId); + + std::vector<std::string> cpackPackageExecutablesList; + const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); + if(cpackPackageExecutables) { - return true; + cmSystemTools::ExpandListArgument(cpackPackageExecutables, + cpackPackageExecutablesList); + if(cpackPackageExecutablesList.size() % 2 != 0 ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and " + "<text label>." << std::endl); + return false; + } } + AddDirectoryAndFileDefinitons( + rootPath, "INSTALL_ROOT", + directoryDefinitions, fileDefinitions, featureDefinitions, + cpackPackageExecutablesList, shortcutMap); + + featureDefinitions.EndElement("FeatureRef"); + + return true; +} + +bool cmCPackWIXGenerator::CreateStartMenuShortcuts( + std::string const& cpackComponentName, + std::string const& featureId, + shortcut_map_t& shortcutMap, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions) +{ + featureDefinitions.BeginElement("FeatureRef"); + featureDefinitions.AddAttribute("Id", featureId); + std::string cpackVendor; if(!RequireOption("CPACK_PACKAGE_VENDOR", cpackVendor)) { @@ -497,10 +691,19 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts( return false; } + std::string idSuffix; + if(!cpackComponentName.empty()) + { + idSuffix += "_"; + idSuffix += cpackComponentName; + } + + std::string componentId = "CM_SHORTCUT" + idSuffix; + fileDefinitions.BeginElement("DirectoryRef"); fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); fileDefinitions.BeginElement("Component"); - fileDefinitions.AddAttribute("Id", "SHORTCUT"); + fileDefinitions.AddAttribute("Id", componentId); fileDefinitions.AddAttribute("Guid", "*"); for(shortcut_map_t::const_iterator @@ -522,10 +725,13 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts( fileDefinitions.EndElement("Shortcut"); } - CreateUninstallShortcut(cpackPackageName, fileDefinitions); + if(cpackComponentName.empty()) + { + CreateUninstallShortcut(cpackPackageName, fileDefinitions); + } fileDefinitions.BeginElement("RemoveFolder"); - fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER" + idSuffix); fileDefinitions.AddAttribute("On", "uninstall"); fileDefinitions.EndElement("RemoveFolder"); @@ -535,7 +741,15 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts( fileDefinitions.BeginElement("RegistryValue"); fileDefinitions.AddAttribute("Root", "HKCU"); fileDefinitions.AddAttribute("Key", registryKey); - fileDefinitions.AddAttribute("Name", "installed"); + + std::string valueName; + if(!cpackComponentName.empty()) + { + valueName = cpackComponentName + "_"; + } + valueName += "installed"; + + fileDefinitions.AddAttribute("Name", valueName); fileDefinitions.AddAttribute("Type", "integer"); fileDefinitions.AddAttribute("Value", "1"); fileDefinitions.AddAttribute("KeyPath", "yes"); @@ -545,19 +759,10 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts( fileDefinitions.EndElement("DirectoryRef"); featureDefinitions.BeginElement("ComponentRef"); - featureDefinitions.AddAttribute("Id", "SHORTCUT"); + featureDefinitions.AddAttribute("Id", componentId); featureDefinitions.EndElement("ComponentRef"); - directoryDefinitions.BeginElement("Directory"); - directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder"); - - directoryDefinitions.BeginElement("Directory"); - directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); - directoryDefinitions.AddAttribute("Name", startMenuFolder); - directoryDefinitions.EndElement("Directory"); - - directoryDefinitions.EndElement("Directory"); + featureDefinitions.EndElement("FeatureRef"); return true; } @@ -628,7 +833,8 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - const std::vector<std::string>& packageExecutables) + const std::vector<std::string>& packageExecutables, + shortcut_map_t& shortcutMap) { cmsys::Directory dir; dir.Load(topdir.c_str()); @@ -662,7 +868,8 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( directoryDefinitions, fileDefinitions, featureDefinitions, - packageExecutables); + packageExecutables, + shortcutMap); directoryDefinitions.EndElement("Directory"); } @@ -922,3 +1129,18 @@ void cmCPackWIXGenerator::AddCustomFlags( stream << " " << QuotePath(*i); } } + +void cmCPackWIXGenerator::CreateStartMenuFolder( + cmWIXSourceWriter& directoryDefinitions) +{ + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder"); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); + directoryDefinitions.AddAttribute("Name", startMenuFolder); + directoryDefinitions.EndElement("Directory"); + + directoryDefinitions.EndElement("Directory"); +} diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index 481a07d..84f68b6 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -56,7 +56,7 @@ protected: virtual bool SupportsComponentInstallation() const { - return false; + return true; } private: @@ -79,9 +79,30 @@ private: bool CreateWiXSourceFiles(); - bool CreateStartMenuShortcuts( + bool CreateFeatureHierarchy( + cmWIXSourceWriter& featureDefinitions); + + bool EmitFeatureForComponentGroup( + cmWIXSourceWriter& featureDefinitions, + cmCPackComponentGroup const& group); + + bool EmitFeatureForComponent( + cmWIXSourceWriter& featureDefinitions, + cmCPackComponent const& component); + + bool AddComponentsToFeature( + std::string const& rootPath, + std::string const& featureId, cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions, + shortcut_map_t& shortcutMap); + + bool CreateStartMenuShortcuts( + std::string const& cpackComponentName, + std::string const& featureId, + shortcut_map_t& shortcutMap, + cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions); void CreateUninstallShortcut( @@ -106,7 +127,8 @@ private: cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - const std::vector<std::string>& pkgExecutables); + const std::vector<std::string>& pkgExecutables, + shortcut_map_t& shortcutMap); bool RequireOption(const std::string& name, std::string& value) const; @@ -136,10 +158,11 @@ private: void AddCustomFlags( const std::string& variableName, std::ostream& stream); + void CreateStartMenuFolder(cmWIXSourceWriter& directoryDefinitions); + std::vector<std::string> wixSources; id_map_t pathToIdMap; ambiguity_map_t idAmbiguityCounter; - shortcut_map_t shortcutMap; extension_set_t candleExtensions; extension_set_t lightExtensions; diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index 214b8ac..c8a3922 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -123,6 +123,15 @@ void cmWIXSourceWriter::AddAttribute( file << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"'; } +void cmWIXSourceWriter::AddAttributeUnlessEmpty( + const std::string& key, const std::string& value) +{ + if(value.size()) + { + AddAttribute(key, value); + } +} + std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value) { if(value.empty()) diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h index 0c7803c..670d4c0 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.h +++ b/Source/CPack/WiX/cmWIXSourceWriter.h @@ -40,6 +40,9 @@ public: void AddAttribute( const std::string& key, const std::string& value); + void AddAttributeUnlessEmpty( + const std::string& key, const std::string& value); + static std::string WindowsCodepageToUtf8(const std::string& value); private: |