summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorNils Gladitz <nilsgladitz@gmail.com>2013-11-19 20:38:09 (GMT)
committerNils Gladitz <nilsgladitz@gmail.com>2013-11-26 21:15:57 (GMT)
commit7b390f75e82ad79f6759656c52825c89e5c92902 (patch)
treef02ef0344b42aee09438326adf4cd5b6bb116bde /Source
parent1da77bf1ee4f3ba315ebb00da2eaeac474614cad (diff)
downloadCMake-7b390f75e82ad79f6759656c52825c89e5c92902.zip
CMake-7b390f75e82ad79f6759656c52825c89e5c92902.tar.gz
CMake-7b390f75e82ad79f6759656c52825c89e5c92902.tar.bz2
CPackWiX: add CPack component support
Creates a hierarchy of WiX features from CPack components and component groups. Switch to the FeatureTree UI in case components have been defined. Handles the component REQUIRE and HIDDEN options and the component group EXPANDED option.
Diffstat (limited to 'Source')
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx306
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h31
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx9
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h3
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: