CPackWIX: refactor and cleanup

Extract addtional classes and functions which are getting unsightly large.
Use some of the coding conventions more consistently.
This commit is contained in:
Nils Gladitz 2014-02-24 23:21:12 +01:00
parent c859d176a1
commit 6fcd835c07
18 changed files with 848 additions and 536 deletions

View File

@ -562,7 +562,11 @@ if(WIN32)
set(CPACK_SRCS ${CPACK_SRCS}
CPack/WiX/cmCPackWIXGenerator.cxx
CPack/WiX/cmWIXSourceWriter.cxx
CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
CPack/WiX/cmWIXFeaturesSourceWriter.cxx
CPack/WiX/cmWIXFilesSourceWriter.cxx
CPack/WiX/cmWIXRichTextFormatWriter.cxx
CPack/WiX/cmWIXPatch.cxx
CPack/WiX/cmWIXPatchParser.cxx
)
endif()

View File

@ -1,6 +1,6 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2013 Kitware, Inc., Insight Software Consortium
Copyright 2000-2014 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
@ -19,6 +19,9 @@
#include <CPack/cmCPackComponentGroup.h>
#include "cmWIXSourceWriter.h"
#include "cmWIXDirectoriesSourceWriter.h"
#include "cmWIXFeaturesSourceWriter.h"
#include "cmWIXFilesSourceWriter.h"
#include "cmWIXRichTextFormatWriter.h"
#include <cmsys/SystemTools.hxx>
@ -28,11 +31,9 @@
#include <rpc.h> // for GUID generation
#include <sys/types.h>
#include <sys/stat.h>
cmCPackWIXGenerator::cmCPackWIXGenerator():
HasDesktopShortcuts(false)
HasDesktopShortcuts(false),
Patch(Logger)
{
}
@ -44,15 +45,9 @@ int cmCPackWIXGenerator::InitializeInternal()
return this->Superclass::InitializeInternal();
}
bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
bool cmCPackWIXGenerator::RunWiXCommand(std::string const& command)
{
std::string cpackTopLevel;
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
{
return false;
}
std::string logFileName = cpackTopLevel + "/wix.log";
std::string logFileName = this->CPackTopLevel + "/wix.log";
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Running WiX command: " << command << std::endl);
@ -81,7 +76,7 @@ bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
}
bool cmCPackWIXGenerator::RunCandleCommand(
const std::string& sourceFile, const std::string& objectFile)
std::string const& sourceFile, std::string const& objectFile)
{
std::string executable;
if(!RequireOption("CPACK_WIX_CANDLE_EXECUTABLE", executable))
@ -108,7 +103,7 @@ bool cmCPackWIXGenerator::RunCandleCommand(
return RunWiXCommand(command.str());
}
bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles)
bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
{
std::string executable;
if(!RequireOption("CPACK_WIX_LIGHT_EXECUTABLE", executable))
@ -121,8 +116,8 @@ bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles)
command << " -nologo";
command << " -out " << QuotePath(packageFileNames.at(0));
for(extension_set_t::const_iterator i = LightExtensions.begin();
i != LightExtensions.end(); ++i)
for(extension_set_t::const_iterator i = this->LightExtensions.begin();
i != this->LightExtensions.end(); ++i)
{
command << " -ext " << QuotePath(*i);
}
@ -182,15 +177,14 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
"you might want to set this explicitly." << std::endl);
}
std::string cpackTopLevel;
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", this->CPackTopLevel))
{
return false;
}
if(GetOption("CPACK_WIX_LICENSE_RTF") == 0)
{
std::string licenseFilename = cpackTopLevel + "/License.rtf";
std::string licenseFilename = this->CPackTopLevel + "/License.rtf";
SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str());
if(!CreateLicenseFile())
@ -213,7 +207,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
{
std::string defaultRef = "WixUI_InstallDir";
if(Components.size())
if(this->Components.size())
{
defaultRef = "WixUI_FeatureTree";
}
@ -221,17 +215,17 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
SetOption("CPACK_WIX_UI_REF", defaultRef.c_str());
}
CollectExtensions("CPACK_WIX_EXTENSIONS", CandleExtensions);
CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", CandleExtensions);
CollectExtensions("CPACK_WIX_EXTENSIONS", this->CandleExtensions);
CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", this->CandleExtensions);
LightExtensions.insert("WixUIExtension");
CollectExtensions("CPACK_WIX_EXTENSIONS", LightExtensions);
CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", LightExtensions);
this->LightExtensions.insert("WixUIExtension");
CollectExtensions("CPACK_WIX_EXTENSIONS", this->LightExtensions);
CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", this->LightExtensions);
const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if(patchFilePath)
{
LoadPatchFragments(patchFilePath);
this->Patch.LoadFragments(patchFilePath);
}
return true;
@ -244,10 +238,7 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
return false;
}
if(!CreateWiXVariablesIncludeFile())
{
return false;
}
CreateWiXVariablesIncludeFile();
if(!CreateWiXSourceFiles())
{
@ -257,9 +248,9 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
AppendUserSuppliedExtraSources();
std::stringstream objectFiles;
for(size_t i = 0; i < WixSources.size(); ++i)
for(size_t i = 0; i < this->WixSources.size(); ++i)
{
const std::string& sourceFilename = WixSources[i];
std::string const& sourceFilename = this->WixSources[i];
std::string objectFilename =
cmSystemTools::GetFilenameWithoutExtension(sourceFilename) + ".wixobj";
@ -282,7 +273,7 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraSources()
const char *cpackWixExtraSources = GetOption("CPACK_WIX_EXTRA_SOURCES");
if(!cpackWixExtraSources) return;
cmSystemTools::ExpandListArgument(cpackWixExtraSources, WixSources);
cmSystemTools::ExpandListArgument(cpackWixExtraSources, this->WixSources);
}
void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
@ -297,22 +288,18 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
for(size_t i = 0; i < expandedExtraObjects.size(); ++i)
{
stream << " " << QuotePath(expandedExtraObjects[i]);
stream << " " << QuotePath(expandedExtraObjects[i]);
}
}
bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
{
std::string cpackTopLevel;
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
{
return false;
}
std::string includeFilename =
cpackTopLevel + "/cpack_variables.wxi";
this->CPackTopLevel + "/cpack_variables.wxi";
cmWIXSourceWriter includeFile(
this->Logger, includeFilename, true);
cmWIXSourceWriter includeFile(Logger, includeFilename, true);
CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_GUID");
CopyDefinition(includeFile, "CPACK_WIX_UPGRADE_GUID");
CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR");
@ -326,12 +313,10 @@ bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
GetOption("CPACK_PACKAGE_NAME"));
CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
CopyDefinition(includeFile, "CPACK_WIX_UI_REF");
return true;
}
void cmCPackWIXGenerator::CopyDefinition(
cmWIXSourceWriter &source, const std::string &name)
cmWIXSourceWriter &source, std::string const& name)
{
const char* value = GetOption(name.c_str());
if(value)
@ -341,7 +326,7 @@ void cmCPackWIXGenerator::CopyDefinition(
}
void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source,
const std::string& name, const std::string& value)
std::string const& name, std::string const& value)
{
std::stringstream tmp;
tmp << name << "=\"" << value << '"';
@ -352,81 +337,47 @@ void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source,
bool cmCPackWIXGenerator::CreateWiXSourceFiles()
{
std::string cpackTopLevel;
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
std::string directoryDefinitionsFilename =
this->CPackTopLevel + "/directories.wxs";
this->WixSources.push_back(directoryDefinitionsFilename);
cmWIXDirectoriesSourceWriter directoryDefinitions(
this->Logger, directoryDefinitionsFilename);
directoryDefinitions.BeginElement("Fragment");
std::string installRoot;
if(!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", installRoot))
{
return false;
}
std::string directoryDefinitionsFilename =
cpackTopLevel + "/directories.wxs";
WixSources.push_back(directoryDefinitionsFilename);
cmWIXSourceWriter directoryDefinitions(Logger, directoryDefinitionsFilename);
directoryDefinitions.BeginElement("Fragment");
directoryDefinitions.BeginElement("Directory");
directoryDefinitions.AddAttribute("Id", "TARGETDIR");
directoryDefinitions.AddAttribute("Name", "SourceDir");
directoryDefinitions.BeginElement("Directory");
if(GetArchitecture() == "x86")
{
directoryDefinitions.AddAttribute("Id", "ProgramFilesFolder");
}
else
{
directoryDefinitions.AddAttribute("Id", "ProgramFiles64Folder");
}
std::vector<std::string> install_root;
std::string tmp;
if(!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", tmp))
{
return false;
}
cmSystemTools::SplitPath(tmp.c_str(), install_root);
if(!install_root.empty() && install_root.back().empty())
{
install_root.pop_back();
}
for(size_t i = 1; i < install_root.size(); ++i)
{
directoryDefinitions.BeginElement("Directory");
if(i == install_root.size() - 1)
{
directoryDefinitions.AddAttribute("Id", "INSTALL_ROOT");
}
else
{
std::stringstream ss;
ss << "INSTALL_PREFIX_" << i;
directoryDefinitions.AddAttribute("Id", ss.str());
}
directoryDefinitions.AddAttribute("Name", install_root[i]);
}
size_t installRootSize =
directoryDefinitions.BeginInstallationPrefixDirectory(
GetProgramFilesFolderId(), installRoot);
std::string fileDefinitionsFilename =
cpackTopLevel + "/files.wxs";
this->CPackTopLevel + "/files.wxs";
WixSources.push_back(fileDefinitionsFilename);
this->WixSources.push_back(fileDefinitionsFilename);
cmWIXFilesSourceWriter fileDefinitions(
this->Logger, fileDefinitionsFilename);
cmWIXSourceWriter fileDefinitions(Logger, fileDefinitionsFilename);
fileDefinitions.BeginElement("Fragment");
std::string featureDefinitionsFilename =
cpackTopLevel +"/features.wxs";
this->CPackTopLevel +"/features.wxs";
WixSources.push_back(featureDefinitionsFilename);
this->WixSources.push_back(featureDefinitionsFilename);
cmWIXFeaturesSourceWriter featureDefinitions(
this->Logger, featureDefinitionsFilename);
cmWIXSourceWriter featureDefinitions(Logger, featureDefinitionsFilename);
featureDefinitions.BeginElement("Fragment");
featureDefinitions.BeginElement("Feature");
@ -439,13 +390,15 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
{
return false;
}
featureDefinitions.AddAttribute("Title", cpackPackageName);
featureDefinitions.AddAttribute("Title", cpackPackageName);
featureDefinitions.AddAttribute("Level", "1");
if(!CreateCMakePackageRegistryEntry(featureDefinitions))
const char* package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY");
if(package)
{
return false;
featureDefinitions.CreateCMakePackageRegistryEntry(
package, GetOption("CPACK_WIX_UPGRADE_GUID"));
}
if(!CreateFeatureHierarchy(featureDefinitions))
@ -471,7 +424,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
else
{
for(std::map<std::string, cmCPackComponent>::const_iterator
i = Components.begin(); i != Components.end(); ++i)
i = this->Components.begin(); i != this->Components.end(); ++i)
{
cmCPackComponent const& component = i->second;
@ -513,31 +466,51 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
featureDefinitions.EndElement("Fragment");
fileDefinitions.EndElement("Fragment");
for(size_t i = 1; i < install_root.size(); ++i)
{
directoryDefinitions.EndElement("Directory");
}
directoryDefinitions.EndElement("Directory");
directoryDefinitions.EndInstallationPrefixDirectory(
installRootSize);
if(hasShortcuts)
{
CreateStartMenuFolder(directoryDefinitions);
directoryDefinitions.EmitStartMenuFolder(
GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"));
}
if(this->HasDesktopShortcuts)
{
CreateDesktopFolder(directoryDefinitions);
directoryDefinitions.EmitDesktopFolder();
}
directoryDefinitions.EndElement("Directory");
directoryDefinitions.EndElement("Fragment");
if(!GenerateMainSourceFileFromTemplate())
{
return false;
}
return this->Patch.CheckForUnappliedFragments();
}
std::string cmCPackWIXGenerator::GetProgramFilesFolderId() const
{
if(GetArchitecture() == "x86")
{
return "ProgramFilesFolder";
}
else
{
return "ProgramFiles64Folder";
}
}
bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate()
{
std::string wixTemplate = FindTemplate("WIX.template.in");
if(GetOption("CPACK_WIX_TEMPLATE") != 0)
{
wixTemplate = GetOption("CPACK_WIX_TEMPLATE");
}
if(wixTemplate.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
@ -545,7 +518,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
return false;
}
std::string mainSourceFilePath = cpackTopLevel + "/main.wxs";
std::string mainSourceFilePath = this->CPackTopLevel + "/main.wxs";
if(!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath .c_str()))
{
@ -556,68 +529,13 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
return false;
}
WixSources.push_back(mainSourceFilePath);
std::string fragmentList;
for(cmWIXPatchParser::fragment_map_t::const_iterator
i = Fragments.begin(); i != Fragments.end(); ++i)
{
if(!fragmentList.empty())
{
fragmentList += ", ";
}
fragmentList += "'";
fragmentList += i->first;
fragmentList += "'";
}
if(fragmentList.size())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Some XML patch fragments did not have matching IDs: " <<
fragmentList << std::endl);
return false;
}
return true;
}
bool cmCPackWIXGenerator::CreateCMakePackageRegistryEntry(
cmWIXSourceWriter& featureDefinitions)
{
const char* package = GetOption("CPACK_WIX_CMAKE_PACKAGE_REGISTRY");
if(!package)
{
return true;
}
featureDefinitions.BeginElement("Component");
featureDefinitions.AddAttribute("Id", "CM_PACKAGE_REGISTRY");
featureDefinitions.AddAttribute("Directory", "TARGETDIR");
featureDefinitions.AddAttribute("Guid", "*");
std::string registryKey =
std::string("Software\\Kitware\\CMake\\Packages\\") + package;
std::string upgradeGuid = GetOption("CPACK_WIX_UPGRADE_GUID");
featureDefinitions.BeginElement("RegistryValue");
featureDefinitions.AddAttribute("Root", "HKLM");
featureDefinitions.AddAttribute("Key", registryKey);
featureDefinitions.AddAttribute("Name", upgradeGuid);
featureDefinitions.AddAttribute("Type", "string");
featureDefinitions.AddAttribute("Value", "[INSTALL_ROOT]");
featureDefinitions.AddAttribute("KeyPath", "yes");
featureDefinitions.EndElement("RegistryValue");
featureDefinitions.EndElement("Component");
this->WixSources.push_back(mainSourceFilePath);
return true;
}
bool cmCPackWIXGenerator::CreateFeatureHierarchy(
cmWIXSourceWriter& featureDefinitions)
cmWIXFeaturesSourceWriter& featureDefinitions)
{
for(std::map<std::string, cmCPackComponentGroup>::const_iterator
i = ComponentGroups.begin(); i != ComponentGroups.end(); ++i)
@ -625,105 +543,30 @@ bool cmCPackWIXGenerator::CreateFeatureHierarchy(
cmCPackComponentGroup const& group = i->second;
if(group.ParentGroup == 0)
{
if(!EmitFeatureForComponentGroup(featureDefinitions, group))
{
return false;
}
featureDefinitions.EmitFeatureForComponentGroup(group);
}
}
for(std::map<std::string, cmCPackComponent>::const_iterator
i = Components.begin(); i != Components.end(); ++i)
i = this->Components.begin(); i != this->Components.end(); ++i)
{
cmCPackComponent const& component = i->second;
if(!component.Group)
{
if(!EmitFeatureForComponent(featureDefinitions, component))
{
return false;
}
featureDefinitions.EmitFeatureForComponent(component);
}
}
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,
cmWIXDirectoriesSourceWriter& directoryDefinitions,
cmWIXFilesSourceWriter& fileDefinitions,
cmWIXFeaturesSourceWriter& featureDefinitions,
shortcut_map_t& shortcutMap)
{
featureDefinitions.BeginElement("FeatureRef");
@ -768,8 +611,8 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
std::string const& cpackComponentName,
std::string const& featureId,
shortcut_map_t& shortcutMap,
cmWIXSourceWriter& fileDefinitions,
cmWIXSourceWriter& featureDefinitions)
cmWIXFilesSourceWriter& fileDefinitions,
cmWIXFeaturesSourceWriter& featureDefinitions)
{
bool thisHasDesktopShortcuts = false;
@ -799,6 +642,7 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
fileDefinitions.BeginElement("DirectoryRef");
fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
fileDefinitions.BeginElement("Component");
fileDefinitions.AddAttribute("Id", componentId);
fileDefinitions.AddAttribute("Guid", "*");
@ -809,63 +653,34 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
std::string const& id = i->first;
cmWIXShortcut const& shortcut = i->second;
std::string shortcutId = std::string("CM_S") + id;
std::string fileId = std::string("CM_F") + id;
fileDefinitions.EmitShortcut(id, shortcut, false);
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");
if (shortcut.desktop)
if(shortcut.desktop)
{
thisHasDesktopShortcuts = true;
thisHasDesktopShortcuts = true;
}
}
if(cpackComponentName.empty())
{
CreateUninstallShortcut(cpackPackageName, fileDefinitions);
fileDefinitions.EmitUninstallShortcut(cpackPackageName);
}
fileDefinitions.BeginElement("RemoveFolder");
fileDefinitions.AddAttribute("Id",
fileDefinitions.EmitRemoveFolder(
"CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix);
fileDefinitions.AddAttribute("On", "uninstall");
fileDefinitions.EndElement("RemoveFolder");
std::string registryKey =
std::string("Software\\") + cpackVendor + "\\" + cpackPackageName;
fileDefinitions.BeginElement("RegistryValue");
fileDefinitions.AddAttribute("Root", "HKCU");
fileDefinitions.AddAttribute("Key", registryKey);
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");
fileDefinitions.EndElement("RegistryValue");
fileDefinitions.EmitStartMenuShortcutRegistryValue(
registryKey, cpackComponentName);
fileDefinitions.EndElement("Component");
fileDefinitions.EndElement("DirectoryRef");
featureDefinitions.BeginElement("ComponentRef");
featureDefinitions.AddAttribute("Id", componentId);
featureDefinitions.EndElement("ComponentRef");
featureDefinitions.EmitComponentRef(componentId);
if (thisHasDesktopShortcuts)
if(thisHasDesktopShortcuts)
{
this->HasDesktopShortcuts = true;
componentId = "CM_DESKTOP_SHORTCUT" + idSuffix;
@ -876,7 +691,7 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
fileDefinitions.AddAttribute("Id", componentId);
fileDefinitions.AddAttribute("Guid", "*");
for (shortcut_map_t::const_iterator
for(shortcut_map_t::const_iterator
i = shortcutMap.begin(); i != shortcutMap.end(); ++i)
{
std::string const& id = i->first;
@ -885,34 +700,16 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
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.EmitShortcut(id, shortcut, true);
}
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.EmitDesktopShortcutRegistryValue(
registryKey, cpackComponentName);
fileDefinitions.EndElement("Component");
fileDefinitions.EndElement("DirectoryRef");
featureDefinitions.BeginElement("ComponentRef");
featureDefinitions.AddAttribute("Id", componentId);
featureDefinitions.EndElement("ComponentRef");
featureDefinitions.EmitComponentRef(componentId);
}
featureDefinitions.EndElement("FeatureRef");
@ -920,19 +717,6 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
return true;
}
void cmCPackWIXGenerator::CreateUninstallShortcut(
std::string const& packageName,
cmWIXSourceWriter& fileDefinitions)
{
fileDefinitions.BeginElement("Shortcut");
fileDefinitions.AddAttribute("Id", "UNINSTALL");
fileDefinitions.AddAttribute("Name", "Uninstall " + packageName);
fileDefinitions.AddAttribute("Description", "Uninstalls " + packageName);
fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe");
fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]");
fileDefinitions.EndElement("Shortcut");
}
bool cmCPackWIXGenerator::CreateLicenseFile()
{
std::string licenseSourceFilename;
@ -981,11 +765,11 @@ bool cmCPackWIXGenerator::CreateLicenseFile()
}
void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
const std::string& topdir,
const std::string& directoryId,
cmWIXSourceWriter& directoryDefinitions,
cmWIXSourceWriter& fileDefinitions,
cmWIXSourceWriter& featureDefinitions,
std::string const& topdir,
std::string const& directoryId,
cmWIXDirectoriesSourceWriter& directoryDefinitions,
cmWIXFilesSourceWriter& fileDefinitions,
cmWIXFeaturesSourceWriter& featureDefinitions,
const std::vector<std::string>& packageExecutables,
const std::vector<std::string>& desktopExecutables,
shortcut_map_t& shortcutMap)
@ -1026,44 +810,15 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
desktopExecutables,
shortcutMap);
ApplyPatchFragment(subDirectoryId, directoryDefinitions);
this->Patch.ApplyFragment(subDirectoryId, directoryDefinitions);
directoryDefinitions.EndElement("Directory");
}
else
{
std::string componentId = std::string("CM_C") + id;
std::string fileId = std::string("CM_F") + id;
std::string componentId = fileDefinitions.EmitComponentFile(
directoryId, id, fullPath, this->Patch);
fileDefinitions.BeginElement("DirectoryRef");
fileDefinitions.AddAttribute("Id", directoryId);
fileDefinitions.BeginElement("Component");
fileDefinitions.AddAttribute("Id", componentId);
fileDefinitions.AddAttribute("Guid", "*");
fileDefinitions.BeginElement("File");
fileDefinitions.AddAttribute("Id", fileId);
fileDefinitions.AddAttribute("Source", fullPath);
fileDefinitions.AddAttribute("KeyPath", "yes");
mode_t fileMode = 0;
cmSystemTools::GetPermissions(fullPath.c_str(), fileMode);
if(!(fileMode & S_IWRITE))
{
fileDefinitions.AddAttribute("ReadOnly", "yes");
}
ApplyPatchFragment(fileId, fileDefinitions);
fileDefinitions.EndElement("File");
ApplyPatchFragment(componentId, fileDefinitions);
fileDefinitions.EndElement("Component");
fileDefinitions.EndElement("DirectoryRef");
featureDefinitions.BeginElement("ComponentRef");
featureDefinitions.AddAttribute("Id", componentId);
featureDefinitions.EndElement("ComponentRef");
featureDefinitions.EmitComponentRef(componentId);
for(size_t j = 0; j < packageExecutables.size(); ++j)
{
@ -1092,7 +847,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
}
bool cmCPackWIXGenerator::RequireOption(
const std::string& name, std::string &value) const
std::string const& name, std::string &value) const
{
const char* tmp = GetOption(name.c_str());
if(tmp)
@ -1140,13 +895,13 @@ std::string cmCPackWIXGenerator::GenerateGUID()
return cmSystemTools::UpperCase(result);
}
std::string cmCPackWIXGenerator::QuotePath(const std::string& path)
std::string cmCPackWIXGenerator::QuotePath(std::string const& path)
{
return std::string("\"") + path + '"';
}
std::string cmCPackWIXGenerator::GetRightmostExtension(
const std::string& filename)
std::string const& filename)
{
std::string extension;
@ -1159,7 +914,7 @@ std::string cmCPackWIXGenerator::GetRightmostExtension(
return cmSystemTools::LowerCase(extension);
}
std::string cmCPackWIXGenerator::PathToId(const std::string& path)
std::string cmCPackWIXGenerator::PathToId(std::string const& path)
{
id_map_t::const_iterator i = PathToIdMap.find(path);
if(i != PathToIdMap.end()) return i->second;
@ -1168,7 +923,7 @@ std::string cmCPackWIXGenerator::PathToId(const std::string& path)
return id;
}
std::string cmCPackWIXGenerator::CreateNewIdForPath(const std::string& path)
std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
{
std::vector<std::string> components;
cmSystemTools::SplitPath(path.c_str(), components, false);
@ -1222,7 +977,7 @@ std::string cmCPackWIXGenerator::CreateNewIdForPath(const std::string& path)
}
std::string cmCPackWIXGenerator::CreateHashedId(
const std::string& path, const std::string& normalizedFilename)
std::string const& path, std::string const& normalizedFilename)
{
cmsys::auto_ptr<cmCryptoHash> sha1 = cmCryptoHash::New("SHA1");
std::string hash = sha1->HashString(path.c_str());
@ -1245,7 +1000,7 @@ std::string cmCPackWIXGenerator::CreateHashedId(
}
std::string cmCPackWIXGenerator::NormalizeComponentForId(
const std::string& component, size_t& replacementCount)
std::string const& component, size_t& replacementCount)
{
std::string result;
result.resize(component.size());
@ -1276,7 +1031,7 @@ bool cmCPackWIXGenerator::IsLegalIdCharacter(char c)
}
void cmCPackWIXGenerator::CollectExtensions(
const std::string& variableName, extension_set_t& extensions)
std::string const& variableName, extension_set_t& extensions)
{
const char *variableContent = GetOption(variableName.c_str());
if(!variableContent) return;
@ -1292,7 +1047,7 @@ void cmCPackWIXGenerator::CollectExtensions(
}
void cmCPackWIXGenerator::AddCustomFlags(
const std::string& variableName, std::ostream& stream)
std::string const& variableName, std::ostream& stream)
{
const char *variableContent = GetOption(variableName.c_str());
if(!variableContent) return;
@ -1306,69 +1061,3 @@ 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");
}
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);
parser.ParseFile(patchFilePath.c_str());
}
void cmCPackWIXGenerator::ApplyPatchFragment(
const std::string& id, cmWIXSourceWriter& writer)
{
cmWIXPatchParser::fragment_map_t::iterator i = Fragments.find(id);
if(i == Fragments.end()) return;
const cmWIXPatchElement& fragment = i->second;
for(cmWIXPatchElement::child_list_t::const_iterator
j = fragment.children.begin(); j != fragment.children.end(); ++j)
{
ApplyPatchElement(**j, writer);
}
Fragments.erase(i);
}
void cmCPackWIXGenerator::ApplyPatchElement(
const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
{
writer.BeginElement(element.name);
for(cmWIXPatchElement::attributes_t::const_iterator
i = element.attributes.begin(); i != element.attributes.end(); ++i)
{
writer.AddAttribute(i->first, i->second);
}
for(cmWIXPatchElement::child_list_t::const_iterator
i = element.children.begin(); i != element.children.end(); ++i)
{
ApplyPatchElement(**i, writer);
}
writer.EndElement(element.name);
}

View File

@ -13,25 +13,18 @@
#ifndef cmCPackWIXGenerator_h
#define cmCPackWIXGenerator_h
#include "cmWIXPatchParser.h"
#include "cmWIXPatch.h"
#include "cmWIXShortcut.h"
#include <CPack/cmCPackGenerator.h>
#include <string>
#include <map>
struct cmWIXShortcut
{
cmWIXShortcut()
:desktop(false)
{}
std::string textLabel;
std::string workingDirectoryId;
bool desktop;
};
class cmWIXSourceWriter;
class cmWIXDirectoriesSourceWriter;
class cmWIXFilesSourceWriter;
class cmWIXFeaturesSourceWriter;
/** \class cmCPackWIXGenerator
* \brief A generator for WIX files
@ -78,48 +71,37 @@ private:
bool PackageFilesImpl();
bool CreateWiXVariablesIncludeFile();
void CreateWiXVariablesIncludeFile();
void CopyDefinition(
cmWIXSourceWriter &source, const std::string &name);
cmWIXSourceWriter &source, std::string const& name);
void AddDefinition(cmWIXSourceWriter& source,
const std::string& name, const std::string& value);
std::string const& name, std::string const& value);
bool CreateWiXSourceFiles();
bool CreateCMakePackageRegistryEntry(
cmWIXSourceWriter& featureDefinitions);
std::string GetProgramFilesFolderId() const;
bool GenerateMainSourceFileFromTemplate();
bool CreateFeatureHierarchy(
cmWIXSourceWriter& featureDefinitions);
bool EmitFeatureForComponentGroup(
cmWIXSourceWriter& featureDefinitions,
cmCPackComponentGroup const& group);
bool EmitFeatureForComponent(
cmWIXSourceWriter& featureDefinitions,
cmCPackComponent const& component);
cmWIXFeaturesSourceWriter& featureDefinitions);
bool AddComponentsToFeature(
std::string const& rootPath,
std::string const& featureId,
cmWIXSourceWriter& directoryDefinitions,
cmWIXSourceWriter& fileDefinitions,
cmWIXSourceWriter& featureDefinitions,
cmWIXDirectoriesSourceWriter& directoryDefinitions,
cmWIXFilesSourceWriter& fileDefinitions,
cmWIXFeaturesSourceWriter& 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(
std::string const& packageName,
cmWIXSourceWriter& fileDefinitions);
cmWIXFilesSourceWriter& fileDefinitions,
cmWIXFeaturesSourceWriter& featureDefinitions);
void AppendUserSuppliedExtraSources();
@ -127,60 +109,49 @@ private:
bool CreateLicenseFile();
bool RunWiXCommand(const std::string& command);
bool RunWiXCommand(std::string const& command);
bool RunCandleCommand(
const std::string& sourceFile, const std::string& objectFile);
std::string const& sourceFile, std::string const& objectFile);
bool RunLightCommand(const std::string& objectFiles);
bool RunLightCommand(std::string const& objectFiles);
void AddDirectoryAndFileDefinitons(const std::string& topdir,
const std::string& directoryId,
cmWIXSourceWriter& directoryDefinitions,
cmWIXSourceWriter& fileDefinitions,
cmWIXSourceWriter& featureDefinitions,
void AddDirectoryAndFileDefinitons(std::string const& topdir,
std::string const& directoryId,
cmWIXDirectoriesSourceWriter& directoryDefinitions,
cmWIXFilesSourceWriter& fileDefinitions,
cmWIXFeaturesSourceWriter& 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;
bool RequireOption(std::string const& name, std::string& value) const;
std::string GetArchitecture() const;
static std::string GenerateGUID();
static std::string QuotePath(const std::string& path);
static std::string QuotePath(std::string const& path);
static std::string GetRightmostExtension(const std::string& filename);
static std::string GetRightmostExtension(std::string const& filename);
std::string PathToId(const std::string& path);
std::string PathToId(std::string const& path);
std::string CreateNewIdForPath(const std::string& path);
std::string CreateNewIdForPath(std::string const& path);
static std::string CreateHashedId(
const std::string& path, const std::string& normalizedFilename);
std::string const& path, std::string const& normalizedFilename);
std::string NormalizeComponentForId(
const std::string& component, size_t& replacementCount);
std::string const& component, size_t& replacementCount);
static bool IsLegalIdCharacter(char c);
void CollectExtensions(
const std::string& variableName, extension_set_t& extensions);
std::string const& variableName, extension_set_t& extensions);
void AddCustomFlags(
const std::string& variableName, std::ostream& stream);
void CreateStartMenuFolder(cmWIXSourceWriter& directoryDefinitions);
void CreateDesktopFolder(cmWIXSourceWriter& directoryDefinitions);
void LoadPatchFragments(const std::string& patchFilePath);
void ApplyPatchFragment(const std::string& id, cmWIXSourceWriter& writer);
void ApplyPatchElement(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer);
std::string const& variableName, std::ostream& stream);
std::vector<std::string> WixSources;
id_map_t PathToIdMap;
@ -189,9 +160,11 @@ private:
extension_set_t CandleExtensions;
extension_set_t LightExtensions;
cmWIXPatchParser::fragment_map_t Fragments;
bool HasDesktopShortcuts;
std::string CPackTopLevel;
cmWIXPatch Patch;
};
#endif

View File

@ -0,0 +1,87 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmWIXDirectoriesSourceWriter.h"
cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter(cmCPackLog* logger,
std::string const& filename):
cmWIXSourceWriter(logger, filename)
{
}
void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
std::string const& startMenuFolder)
{
BeginElement("Directory");
AddAttribute("Id", "ProgramMenuFolder");
BeginElement("Directory");
AddAttribute("Id", "PROGRAM_MENU_FOLDER");
AddAttribute("Name", startMenuFolder);
EndElement("Directory");
EndElement("Directory");
}
void cmWIXDirectoriesSourceWriter::EmitDesktopFolder()
{
BeginElement("Directory");
AddAttribute("Id", "DesktopFolder");
AddAttribute("Name", "Desktop");
EndElement("Directory");
}
size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
std::string const& programFilesFolderId,
std::string const& installRootString)
{
BeginElement("Directory");
AddAttribute("Id", programFilesFolderId);
std::vector<std::string> installRoot;
cmSystemTools::SplitPath(installRootString.c_str(), installRoot);
if(!installRoot.empty() && installRoot.back().empty())
{
installRoot.pop_back();
}
for(size_t i = 1; i < installRoot.size(); ++i)
{
BeginElement("Directory");
if(i == installRoot.size() - 1)
{
AddAttribute("Id", "INSTALL_ROOT");
}
else
{
std::stringstream tmp;
tmp << "INSTALL_PREFIX_" << i;
AddAttribute("Id", tmp.str());
}
AddAttribute("Name", installRoot[i]);
}
return installRoot.size();
}
void cmWIXDirectoriesSourceWriter::EndInstallationPrefixDirectory(size_t size)
{
for(size_t i = 0; i < size; ++i)
{
EndElement("Directory");
}
}

View File

@ -0,0 +1,42 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmWIXDirectoriesSourceWriter_h
#define cmWIXDirectoriesSourceWriter_h
#include "cmWIXSourceWriter.h"
#include <CPack/cmCPackGenerator.h>
#include <string>
/** \class cmWIXDirectoriesSourceWriter
* \brief Helper class to generate directories.wxs
*/
class cmWIXDirectoriesSourceWriter : public cmWIXSourceWriter
{
public:
cmWIXDirectoriesSourceWriter(cmCPackLog* logger,
std::string const& filename);
void EmitStartMenuFolder(std::string const& startMenuFolder);
void EmitDesktopFolder();
size_t BeginInstallationPrefixDirectory(
std::string const& programFilesFolderId,
std::string const& installRootString);
void EndInstallationPrefixDirectory(size_t size);
};
#endif

View File

@ -0,0 +1,102 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmWIXFeaturesSourceWriter.h"
cmWIXFeaturesSourceWriter::cmWIXFeaturesSourceWriter(cmCPackLog* logger,
std::string const& filename):
cmWIXSourceWriter(logger, filename)
{
}
void cmWIXFeaturesSourceWriter::CreateCMakePackageRegistryEntry(
std::string const& package,
std::string const& upgradeGuid)
{
BeginElement("Component");
AddAttribute("Id", "CM_PACKAGE_REGISTRY");
AddAttribute("Directory", "TARGETDIR");
AddAttribute("Guid", "*");
std::string registryKey =
std::string("Software\\Kitware\\CMake\\Packages\\") + package;
BeginElement("RegistryValue");
AddAttribute("Root", "HKLM");
AddAttribute("Key", registryKey);
AddAttribute("Name", upgradeGuid);
AddAttribute("Type", "string");
AddAttribute("Value", "[INSTALL_ROOT]");
AddAttribute("KeyPath", "yes");
EndElement("RegistryValue");
EndElement("Component");
}
void cmWIXFeaturesSourceWriter::EmitFeatureForComponentGroup(
cmCPackComponentGroup const& group)
{
BeginElement("Feature");
AddAttribute("Id", "CM_G_" + group.Name);
if(group.IsExpandedByDefault)
{
AddAttribute("Display", "expand");
}
AddAttributeUnlessEmpty("Title", group.DisplayName);
AddAttributeUnlessEmpty("Description", group.Description);
for(std::vector<cmCPackComponentGroup*>::const_iterator
i = group.Subgroups.begin(); i != group.Subgroups.end(); ++i)
{
EmitFeatureForComponentGroup(**i);
}
for(std::vector<cmCPackComponent*>::const_iterator
i = group.Components.begin(); i != group.Components.end(); ++i)
{
EmitFeatureForComponent(**i);
}
EndElement("Feature");
}
void cmWIXFeaturesSourceWriter::EmitFeatureForComponent(
cmCPackComponent const& component)
{
BeginElement("Feature");
AddAttribute("Id", "CM_C_" + component.Name);
AddAttributeUnlessEmpty("Title", component.DisplayName);
AddAttributeUnlessEmpty("Description", component.Description);
if(component.IsRequired)
{
AddAttribute("Absent", "disallow");
}
if(component.IsHidden)
{
AddAttribute("Display", "hidden");
}
EndElement("Feature");
}
void cmWIXFeaturesSourceWriter::EmitComponentRef(std::string const& id)
{
BeginElement("ComponentRef");
AddAttribute("Id", id);
EndElement("ComponentRef");
}

View File

@ -0,0 +1,39 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmWIXFeaturesSourceWriter_h
#define cmWIXFeaturesSourceWriter_h
#include "cmWIXSourceWriter.h"
#include <CPack/cmCPackGenerator.h>
/** \class cmWIXFeaturesSourceWriter
* \brief Helper class to generate features.wxs
*/
class cmWIXFeaturesSourceWriter : public cmWIXSourceWriter
{
public:
cmWIXFeaturesSourceWriter(cmCPackLog* logger,
std::string const& filename);
void CreateCMakePackageRegistryEntry(
std::string const& package,
std::string const& upgradeGuid);
void EmitFeatureForComponentGroup(const cmCPackComponentGroup& group);
void EmitFeatureForComponent(const cmCPackComponent& component);
void EmitComponentRef(std::string const& id);
};
#endif

View File

@ -0,0 +1,149 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmWIXFilesSourceWriter.h"
#include <sys/types.h>
#include <sys/stat.h>
cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
std::string const& filename):
cmWIXSourceWriter(logger, filename)
{
}
void cmWIXFilesSourceWriter::EmitShortcut(
std::string const& id,
cmWIXShortcut const& shortcut,
bool desktop)
{
std::string shortcutId;
if(desktop)
{
shortcutId = "CM_DS";
}
else
{
shortcutId = "CM_S";
}
shortcutId += id;
std::string fileId = std::string("CM_F") + id;
BeginElement("Shortcut");
AddAttribute("Id", shortcutId);
AddAttribute("Name", shortcut.textLabel);
std::string target = "[#" + fileId + "]";
AddAttribute("Target", target);
AddAttribute("WorkingDirectory", shortcut.workingDirectoryId);
EndElement("Shortcut");
}
void cmWIXFilesSourceWriter::EmitRemoveFolder(std::string const& id)
{
BeginElement("RemoveFolder");
AddAttribute("Id", id);
AddAttribute("On", "uninstall");
EndElement("RemoveFolder");
}
void cmWIXFilesSourceWriter::EmitStartMenuShortcutRegistryValue(
std::string const& registryKey,
std::string const& cpackComponentName)
{
EmitInstallRegistryValue(registryKey, cpackComponentName, std::string());
}
void cmWIXFilesSourceWriter::EmitDesktopShortcutRegistryValue(
std::string const& registryKey,
std::string const& cpackComponentName)
{
EmitInstallRegistryValue(registryKey, cpackComponentName, "_desktop");
}
void cmWIXFilesSourceWriter::EmitInstallRegistryValue(
std::string const& registryKey,
std::string const& cpackComponentName,
std::string const& suffix)
{
std::string valueName;
if(!cpackComponentName.empty())
{
valueName = cpackComponentName + "_";
}
valueName += "installed";
valueName += suffix;
BeginElement("RegistryValue");
AddAttribute("Root", "HKCU");
AddAttribute("Key", registryKey);
AddAttribute("Name", valueName);
AddAttribute("Type", "integer");
AddAttribute("Value", "1");
AddAttribute("KeyPath", "yes");
EndElement("RegistryValue");
}
void cmWIXFilesSourceWriter::EmitUninstallShortcut(
std::string const& packageName)
{
BeginElement("Shortcut");
AddAttribute("Id", "UNINSTALL");
AddAttribute("Name", "Uninstall " + packageName);
AddAttribute("Description", "Uninstalls " + packageName);
AddAttribute("Target", "[SystemFolder]msiexec.exe");
AddAttribute("Arguments", "/x [ProductCode]");
EndElement("Shortcut");
}
std::string cmWIXFilesSourceWriter::EmitComponentFile(
std::string const& directoryId,
std::string const& id,
std::string const& filePath,
cmWIXPatch &patch)
{
std::string componentId = std::string("CM_C") + id;
std::string fileId = std::string("CM_F") + id;
BeginElement("DirectoryRef");
AddAttribute("Id", directoryId);
BeginElement("Component");
AddAttribute("Id", componentId);
AddAttribute("Guid", "*");
BeginElement("File");
AddAttribute("Id", fileId);
AddAttribute("Source", filePath);
AddAttribute("KeyPath", "yes");
mode_t fileMode = 0;
cmSystemTools::GetPermissions(filePath.c_str(), fileMode);
if(!(fileMode & S_IWRITE))
{
AddAttribute("ReadOnly", "yes");
}
patch.ApplyFragment(fileId, *this);
EndElement("File");
patch.ApplyFragment(componentId, *this);
EndElement("Component");
EndElement("DirectoryRef");
return componentId;
}

View File

@ -0,0 +1,62 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmWIXFilesSourceWriter_h
#define cmWIXFilesSourceWriter_h
#include "cmWIXSourceWriter.h"
#include "cmWIXShortcut.h"
#include "cmWIXPatch.h"
#include <CPack/cmCPackGenerator.h>
/** \class cmWIXFilesSourceWriter
* \brief Helper class to generate files.wxs
*/
class cmWIXFilesSourceWriter : public cmWIXSourceWriter
{
public:
cmWIXFilesSourceWriter(cmCPackLog* logger,
std::string const& filename);
void EmitShortcut(
std::string const& id,
cmWIXShortcut const& shortcut,
bool desktop);
void EmitRemoveFolder(std::string const& id);
void EmitStartMenuShortcutRegistryValue(
std::string const& registryKey,
std::string const& cpackComponentName);
void EmitDesktopShortcutRegistryValue(
std::string const& registryKey,
std::string const& cpackComponentName);
void EmitUninstallShortcut(std::string const& packageName);
std::string EmitComponentFile(
std::string const& directoryId,
std::string const& id,
std::string const& filePath,
cmWIXPatch &patch);
private:
void EmitInstallRegistryValue(
std::string const& registryKey,
std::string const& cpackComponentName,
std::string const& suffix);
};
#endif

View File

@ -0,0 +1,91 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmWIXPatch.h"
#include <CPack/cmCPackGenerator.h>
cmWIXPatch::cmWIXPatch(cmCPackLog* logger):
Logger(logger)
{
}
void cmWIXPatch::LoadFragments(std::string const& patchFilePath)
{
cmWIXPatchParser parser(Fragments, Logger);
parser.ParseFile(patchFilePath.c_str());
}
void cmWIXPatch::ApplyFragment(
std::string const& id, cmWIXSourceWriter& writer)
{
cmWIXPatchParser::fragment_map_t::iterator i = Fragments.find(id);
if(i == Fragments.end()) return;
const cmWIXPatchElement& fragment = i->second;
for(cmWIXPatchElement::child_list_t::const_iterator
j = fragment.children.begin(); j != fragment.children.end(); ++j)
{
ApplyElement(**j, writer);
}
Fragments.erase(i);
}
void cmWIXPatch::ApplyElement(
const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
{
writer.BeginElement(element.name);
for(cmWIXPatchElement::attributes_t::const_iterator
i = element.attributes.begin(); i != element.attributes.end(); ++i)
{
writer.AddAttribute(i->first, i->second);
}
for(cmWIXPatchElement::child_list_t::const_iterator
i = element.children.begin(); i != element.children.end(); ++i)
{
ApplyElement(**i, writer);
}
writer.EndElement(element.name);
}
bool cmWIXPatch::CheckForUnappliedFragments()
{
std::string fragmentList;
for(cmWIXPatchParser::fragment_map_t::const_iterator
i = Fragments.begin(); i != Fragments.end(); ++i)
{
if(!fragmentList.empty())
{
fragmentList += ", ";
}
fragmentList += "'";
fragmentList += i->first;
fragmentList += "'";
}
if(fragmentList.size())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Some XML patch fragments did not have matching IDs: " <<
fragmentList << std::endl);
return false;
}
return true;
}

View File

@ -0,0 +1,45 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmWIXPatch_h
#define cmWIXPatch_h
#include "cmWIXSourceWriter.h"
#include "cmWIXPatchParser.h"
#include <string>
/** \class cmWIXPatch
* \brief Class that maintains and applies patch fragments
*/
class cmWIXPatch
{
public:
cmWIXPatch(cmCPackLog* logger);
void LoadFragments(std::string const& patchFilePath);
void ApplyFragment(std::string const& id, cmWIXSourceWriter& writer);
bool CheckForUnappliedFragments();
private:
void ApplyElement(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer);
cmCPackLog* Logger;
cmWIXPatchParser::fragment_map_t Fragments;
};
#endif

View File

@ -132,7 +132,7 @@ void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
Valid = false;
}
void cmWIXPatchParser::ReportValidationError(const std::string& message)
void cmWIXPatchParser::ReportValidationError(std::string const& message)
{
ReportError(XML_GetCurrentLineNumber(Parser),
XML_GetCurrentColumnNumber(Parser),

View File

@ -50,7 +50,7 @@ private:
virtual void EndElement(const char *name);
virtual void ReportError(int line, int column, const char* msg);
void ReportValidationError(const std::string& message);
void ReportValidationError(std::string const& message);
bool IsValid() const;

View File

@ -15,7 +15,7 @@
#include <cmVersion.h>
cmWIXRichTextFormatWriter::cmWIXRichTextFormatWriter(
const std::string& filename):
std::string const& filename):
File(filename.c_str(), std::ios::binary)
{
StartGroup();
@ -33,7 +33,7 @@ cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter()
File.put(0);
}
void cmWIXRichTextFormatWriter::AddText(const std::string& text)
void cmWIXRichTextFormatWriter::AddText(std::string const& text)
{
typedef unsigned char rtf_byte_t;
@ -167,12 +167,12 @@ void cmWIXRichTextFormatWriter::WriteDocumentPrefix()
ControlWord("fs20");
}
void cmWIXRichTextFormatWriter::ControlWord(const std::string& keyword)
void cmWIXRichTextFormatWriter::ControlWord(std::string const& keyword)
{
File << "\\" << keyword;
}
void cmWIXRichTextFormatWriter::NewControlWord(const std::string& keyword)
void cmWIXRichTextFormatWriter::NewControlWord(std::string const& keyword)
{
File << "\\*\\" << keyword;
}

View File

@ -22,10 +22,10 @@
class cmWIXRichTextFormatWriter
{
public:
cmWIXRichTextFormatWriter(const std::string& filename);
cmWIXRichTextFormatWriter(std::string const& filename);
~cmWIXRichTextFormatWriter();
void AddText(const std::string& text);
void AddText(std::string const& text);
private:
void WriteHeader();
@ -35,8 +35,8 @@ private:
void WriteDocumentPrefix();
void ControlWord(const std::string& keyword);
void NewControlWord(const std::string& keyword);
void ControlWord(std::string const& keyword);
void NewControlWord(std::string const& keyword);
void StartGroup();
void EndGroup();

View File

@ -0,0 +1,29 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2014 Kitware, Inc.
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmWIXFilesShortcut_h
#define cmWIXFilesShortcut_h
#include <string>
struct cmWIXShortcut
{
cmWIXShortcut()
:desktop(false)
{}
std::string textLabel;
std::string workingDirectoryId;
bool desktop;
};
#endif

View File

@ -17,7 +17,7 @@
#include <windows.h>
cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
const std::string& filename,
std::string const& filename,
bool isIncludeFile):
Logger(logger),
File(filename.c_str()),
@ -51,7 +51,7 @@ cmWIXSourceWriter::~cmWIXSourceWriter()
EndElement(Elements.back());
}
void cmWIXSourceWriter::BeginElement(const std::string& name)
void cmWIXSourceWriter::BeginElement(std::string const& name)
{
if(State == BEGIN)
{
@ -101,7 +101,7 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
}
void cmWIXSourceWriter::AddProcessingInstruction(
const std::string& target, const std::string& content)
std::string const& target, std::string const& content)
{
if(State == BEGIN)
{
@ -116,7 +116,7 @@ void cmWIXSourceWriter::AddProcessingInstruction(
}
void cmWIXSourceWriter::AddAttribute(
const std::string& key, const std::string& value)
std::string const& key, std::string const& value)
{
std::string utf8 = WindowsCodepageToUtf8(value);
@ -124,7 +124,7 @@ void cmWIXSourceWriter::AddAttribute(
}
void cmWIXSourceWriter::AddAttributeUnlessEmpty(
const std::string& key, const std::string& value)
std::string const& key, std::string const& value)
{
if(value.size())
{
@ -132,7 +132,7 @@ void cmWIXSourceWriter::AddAttributeUnlessEmpty(
}
}
std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value)
std::string cmWIXSourceWriter::WindowsCodepageToUtf8(std::string const& value)
{
if(value.empty())
{
@ -184,7 +184,7 @@ void cmWIXSourceWriter::Indent(size_t count)
}
std::string cmWIXSourceWriter::EscapeAttributeValue(
const std::string& value)
std::string const& value)
{
std::string result;
result.reserve(value.size());

View File

@ -26,24 +26,24 @@ class cmWIXSourceWriter
{
public:
cmWIXSourceWriter(cmCPackLog* logger,
const std::string& filename, bool isIncludeFile = false);
std::string const& filename, bool isIncludeFile = false);
~cmWIXSourceWriter();
void BeginElement(const std::string& name);
void BeginElement(std::string const& name);
void EndElement(const std::string& name);
void EndElement(std::string const& name);
void AddProcessingInstruction(
const std::string& target, const std::string& content);
std::string const& target, std::string const& content);
void AddAttribute(
const std::string& key, const std::string& value);
std::string const& key, std::string const& value);
void AddAttributeUnlessEmpty(
const std::string& key, const std::string& value);
std::string const& key, std::string const& value);
static std::string WindowsCodepageToUtf8(const std::string& value);
static std::string WindowsCodepageToUtf8(std::string const& value);
private:
enum State
@ -56,7 +56,7 @@ private:
void Indent(size_t count);
static std::string EscapeAttributeValue(const std::string& value);
static std::string EscapeAttributeValue(std::string const& value);
cmCPackLog* Logger;