WiX provides a lot of functionality for installers that cannot be supported (easily) in the default WIX.template.in file. For most users, the default template should be fine. However if users want to produce merge modules, include custom actions, etc, this new option allows for a hook into how the wxs is produced.
689 lines
19 KiB
C++
689 lines
19 KiB
C++
/*============================================================================
|
|
CMake - Cross Platform Makefile Generator
|
|
Copyright 2000-2012 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 "cmCPackWIXGenerator.h"
|
|
|
|
#include <cmSystemTools.h>
|
|
#include <cmGeneratedFileStream.h>
|
|
#include <CPack/cmCPackLog.h>
|
|
#include <CPack/cmCPackComponentGroup.h>
|
|
|
|
#include "cmWIXSourceWriter.h"
|
|
#include "cmWIXRichTextFormatWriter.h"
|
|
|
|
#include <cmsys/SystemTools.hxx>
|
|
#include <cmsys/Directory.hxx>
|
|
|
|
#include <rpc.h> // for GUID generation
|
|
|
|
int cmCPackWIXGenerator::InitializeInternal()
|
|
{
|
|
componentPackageMethod = ONE_PACKAGE;
|
|
|
|
return this->Superclass::InitializeInternal();
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command)
|
|
{
|
|
std::string cpackTopLevel;
|
|
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::string logFileName = cpackTopLevel + "/wix.log";
|
|
|
|
cmCPackLogger(cmCPackLog::LOG_DEBUG,
|
|
"Running WiX command: " << command << std::endl);
|
|
|
|
std::string output;
|
|
|
|
int returnValue = 0;
|
|
bool status = cmSystemTools::RunSingleCommand(command.c_str(), &output,
|
|
&returnValue, 0, cmSystemTools::OUTPUT_NONE);
|
|
|
|
std::ofstream logFile(logFileName.c_str(), std::ios::app);
|
|
logFile << command << std::endl;
|
|
logFile << output;
|
|
logFile.close();
|
|
|
|
if(!status || returnValue)
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"Problem running WiX candle. "
|
|
"Please check '" << logFileName << "' for errors." << std::endl);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::RunCandleCommand(
|
|
const std::string& sourceFile, const std::string& objectFile)
|
|
{
|
|
std::string executable;
|
|
if(!RequireOption("CPACK_WIX_CANDLE_EXECUTABLE", executable))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::stringstream command;
|
|
command << QuotePath(executable);
|
|
command << " -nologo";
|
|
command << " -arch " << GetArchitecture();
|
|
command << " -out " << QuotePath(objectFile);
|
|
command << " " << QuotePath(sourceFile);
|
|
|
|
return RunWiXCommand(command.str());
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles)
|
|
{
|
|
std::string executable;
|
|
if(!RequireOption("CPACK_WIX_LIGHT_EXECUTABLE", executable))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::stringstream command;
|
|
command << QuotePath(executable);
|
|
command << " -nologo";
|
|
command << " -out " << QuotePath(packageFileNames.at(0));
|
|
command << " -ext WixUIExtension";
|
|
const char* const cultures = GetOption("CPACK_WIX_CULTURES");
|
|
if(cultures)
|
|
{
|
|
command << " -cultures:" << cultures;
|
|
}
|
|
command << " " << objectFiles;
|
|
|
|
return RunWiXCommand(command.str());
|
|
}
|
|
|
|
int cmCPackWIXGenerator::PackageFiles()
|
|
{
|
|
if(!PackageFilesImpl() || cmSystemTools::GetErrorOccuredFlag())
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"Fatal WiX Generator Error" << std::endl);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::InitializeWiXConfiguration()
|
|
{
|
|
if(!ReadListFile("CPackWIX.cmake"))
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"Error while executing CPackWIX.cmake" << std::endl);
|
|
return false;
|
|
}
|
|
|
|
if(GetOption("CPACK_WIX_PRODUCT_GUID") == 0)
|
|
{
|
|
std::string guid = GenerateGUID();
|
|
SetOption("CPACK_WIX_PRODUCT_GUID", guid.c_str());
|
|
|
|
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
|
|
"CPACK_WIX_PRODUCT_GUID implicitly set to " << guid << " . "
|
|
<< std::endl);
|
|
}
|
|
|
|
if(GetOption("CPACK_WIX_UPGRADE_GUID") == 0)
|
|
{
|
|
std::string guid = GenerateGUID();
|
|
SetOption("CPACK_WIX_UPGRADE_GUID", guid.c_str());
|
|
|
|
cmCPackLogger(cmCPackLog::LOG_WARNING,
|
|
"CPACK_WIX_UPGRADE_GUID implicitly set to " << guid << " . "
|
|
"Please refer to the documentation on how and why "
|
|
"you might want to set this explicitly." << std::endl);
|
|
}
|
|
|
|
std::string cpackTopLevel;
|
|
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(GetOption("CPACK_WIX_LICENSE_RTF") == 0)
|
|
{
|
|
std::string licenseFilename = cpackTopLevel + "/License.rtf";
|
|
SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str());
|
|
|
|
if(!CreateLicenseFile())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::PackageFilesImpl()
|
|
{
|
|
if(!InitializeWiXConfiguration())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(!CreateWiXVariablesIncludeFile())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(!CreateWiXSourceFiles())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::stringstream objectFiles;
|
|
for(size_t i = 0; i < wixSources.size(); ++i)
|
|
{
|
|
const std::string& sourceFilename = wixSources[i];
|
|
|
|
std::string objectFilename =
|
|
cmSystemTools::GetFilenameWithoutExtension(sourceFilename) + ".wixobj";
|
|
|
|
if(!RunCandleCommand(sourceFilename, objectFilename))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
objectFiles << " " << QuotePath(objectFilename);
|
|
}
|
|
|
|
return RunLightCommand(objectFiles.str());
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
|
|
{
|
|
std::string cpackTopLevel;
|
|
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::string includeFilename =
|
|
cpackTopLevel + "/cpack_variables.wxi";
|
|
|
|
cmWIXSourceWriter includeFile(Logger, includeFilename, true);
|
|
CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_GUID");
|
|
CopyDefinition(includeFile, "CPACK_WIX_UPGRADE_GUID");
|
|
CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR");
|
|
CopyDefinition(includeFile, "CPACK_PACKAGE_NAME");
|
|
CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION");
|
|
CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF");
|
|
CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON");
|
|
CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER");
|
|
CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG");
|
|
SetOptionIfNotSet("CPACK_WIX_PROGRAM_MENU_FOLDER",
|
|
GetOption("CPACK_PACKAGE_NAME"));
|
|
CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
|
|
|
|
return true;
|
|
}
|
|
|
|
void cmCPackWIXGenerator::CopyDefinition(
|
|
cmWIXSourceWriter &source, const std::string &name)
|
|
{
|
|
const char* value = GetOption(name.c_str());
|
|
if(value)
|
|
{
|
|
AddDefinition(source, name, value);
|
|
}
|
|
}
|
|
|
|
void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source,
|
|
const std::string& name, const std::string& value)
|
|
{
|
|
std::stringstream tmp;
|
|
tmp << name << "=\"" << value << '"';
|
|
|
|
source.AddProcessingInstruction("define",
|
|
cmWIXSourceWriter::WindowsCodepageToUtf8(tmp.str()));
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::CreateWiXSourceFiles()
|
|
{
|
|
std::string cpackTopLevel;
|
|
if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel))
|
|
{
|
|
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 directoryCounter = 0;
|
|
size_t fileCounter = 0;
|
|
|
|
std::string fileDefinitionsFilename =
|
|
cpackTopLevel + "/files.wxs";
|
|
|
|
wixSources.push_back(fileDefinitionsFilename);
|
|
|
|
cmWIXSourceWriter fileDefinitions(Logger, fileDefinitionsFilename);
|
|
fileDefinitions.BeginElement("Fragment");
|
|
|
|
std::string featureDefinitionsFilename =
|
|
cpackTopLevel +"/features.wxs";
|
|
|
|
wixSources.push_back(featureDefinitionsFilename);
|
|
|
|
cmWIXSourceWriter featureDefinitions(Logger, featureDefinitionsFilename);
|
|
featureDefinitions.BeginElement("Fragment");
|
|
|
|
featureDefinitions.BeginElement("Feature");
|
|
featureDefinitions.AddAttribute("Id", "ProductFeature");
|
|
featureDefinitions.AddAttribute("Title", Name);
|
|
featureDefinitions.AddAttribute("Level", "1");
|
|
featureDefinitions.EndElement();
|
|
|
|
featureDefinitions.BeginElement("FeatureRef");
|
|
featureDefinitions.AddAttribute("Id", "ProductFeature");
|
|
|
|
const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
|
|
std::vector<std::string> cpackPkgExecutables;
|
|
std::string regKey;
|
|
if ( cpackPackageExecutables )
|
|
{
|
|
cmSystemTools::ExpandListArgument(cpackPackageExecutables,
|
|
cpackPkgExecutables);
|
|
if ( cpackPkgExecutables.size() % 2 != 0 )
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
|
|
"<icon name>." << std::endl);
|
|
cpackPkgExecutables.clear();
|
|
}
|
|
|
|
const char *cpackVendor = GetOption("CPACK_PACKAGE_VENDOR");
|
|
const char *cpackPkgName = GetOption("CPACK_PACKAGE_NAME");
|
|
if (!cpackVendor || !cpackPkgName)
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_PACKAGE_VENDOR and "
|
|
"CPACK_PACKAGE_NAME must be defined for shortcut creation" << std::endl);
|
|
cpackPkgExecutables.clear();
|
|
}
|
|
else
|
|
{
|
|
regKey = std::string("Software/") + cpackVendor + "/" + cpackPkgName;
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> dirIdExecutables;
|
|
AddDirectoryAndFileDefinitons(
|
|
toplevel, "INSTALL_ROOT",
|
|
directoryDefinitions, fileDefinitions, featureDefinitions,
|
|
directoryCounter, fileCounter, cpackPkgExecutables, dirIdExecutables);
|
|
|
|
directoryDefinitions.EndElement();
|
|
directoryDefinitions.EndElement();
|
|
|
|
if (dirIdExecutables.size() > 0 && dirIdExecutables.size() % 3 == 0)
|
|
{
|
|
fileDefinitions.BeginElement("DirectoryRef");
|
|
fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
|
|
fileDefinitions.BeginElement("Component");
|
|
fileDefinitions.AddAttribute("Id", "SHORTCUT");
|
|
fileDefinitions.AddAttribute("Guid", "*");
|
|
|
|
std::vector<std::string>::iterator it;
|
|
for ( it = dirIdExecutables.begin() ;
|
|
it != dirIdExecutables.end();
|
|
++it)
|
|
{
|
|
std::string fileName = *it++;
|
|
std::string iconName = *it++;
|
|
std::string directoryId = *it;
|
|
|
|
fileDefinitions.BeginElement("Shortcut");
|
|
std::string shortcutName = fileName; // the iconName is mor likely to contain blanks early on
|
|
std::string::size_type const dotPos = shortcutName.find('.');
|
|
if(std::string::npos == dotPos)
|
|
{ shortcutName = shortcutName.substr(0, dotPos); }
|
|
fileDefinitions.AddAttribute("Id", "SHORTCUT_" + shortcutName);
|
|
fileDefinitions.AddAttribute("Name", iconName);
|
|
std::string target = "[" + directoryId + "]" + fileName;
|
|
fileDefinitions.AddAttribute("Target", target);
|
|
fileDefinitions.AddAttribute("WorkingDirectory", directoryId);
|
|
fileDefinitions.EndElement();
|
|
}
|
|
fileDefinitions.BeginElement("Shortcut");
|
|
fileDefinitions.AddAttribute("Id", "UNINSTALL");
|
|
std::string pkgName = GetOption("CPACK_PACKAGE_NAME");
|
|
fileDefinitions.AddAttribute("Name", "Uninstall " + pkgName);
|
|
fileDefinitions.AddAttribute("Description", "Uninstalls " + pkgName);
|
|
fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe");
|
|
fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]");
|
|
fileDefinitions.EndElement();
|
|
fileDefinitions.BeginElement("RemoveFolder");
|
|
fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
|
|
fileDefinitions.AddAttribute("On", "uninstall");
|
|
fileDefinitions.EndElement();
|
|
fileDefinitions.BeginElement("RegistryValue");
|
|
fileDefinitions.AddAttribute("Root", "HKCU");
|
|
fileDefinitions.AddAttribute("Key", regKey);
|
|
fileDefinitions.AddAttribute("Name", "installed");
|
|
fileDefinitions.AddAttribute("Type", "integer");
|
|
fileDefinitions.AddAttribute("Value", "1");
|
|
fileDefinitions.AddAttribute("KeyPath", "yes");
|
|
|
|
featureDefinitions.BeginElement("ComponentRef");
|
|
featureDefinitions.AddAttribute("Id", "SHORTCUT");
|
|
featureDefinitions.EndElement();
|
|
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);
|
|
}
|
|
|
|
featureDefinitions.EndElement();
|
|
featureDefinitions.EndElement();
|
|
fileDefinitions.EndElement();
|
|
directoryDefinitions.EndElement();
|
|
|
|
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,
|
|
"Could not find CPack WiX template file WIX.template.in" << std::endl);
|
|
return false;
|
|
}
|
|
|
|
std::string mainSourceFilePath = cpackTopLevel + "/main.wxs";
|
|
|
|
if(!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath .c_str()))
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"Failed creating '" << mainSourceFilePath <<
|
|
"'' from template." << std::endl);
|
|
|
|
return false;
|
|
}
|
|
|
|
wixSources.push_back(mainSourceFilePath);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::CreateLicenseFile()
|
|
{
|
|
std::string licenseSourceFilename;
|
|
if(!RequireOption("CPACK_RESOURCE_FILE_LICENSE", licenseSourceFilename))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::string licenseDestinationFilename;
|
|
if(!RequireOption("CPACK_WIX_LICENSE_RTF", licenseDestinationFilename))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
std::string extension = GetRightmostExtension(licenseSourceFilename);
|
|
|
|
if(extension == ".rtf")
|
|
{
|
|
cmSystemTools::CopyAFile(
|
|
licenseSourceFilename.c_str(),
|
|
licenseDestinationFilename.c_str());
|
|
}
|
|
else if(extension == ".txt")
|
|
{
|
|
cmWIXRichTextFormatWriter rtfWriter(licenseDestinationFilename);
|
|
|
|
std::ifstream licenseSource(licenseSourceFilename.c_str());
|
|
|
|
std::string line;
|
|
while(std::getline(licenseSource, line))
|
|
{
|
|
rtfWriter.AddText(line);
|
|
rtfWriter.AddText("\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"unsupported WiX License file extension '" <<
|
|
extension << "'" << std::endl);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
|
|
const std::string& topdir,
|
|
const std::string& directoryId,
|
|
cmWIXSourceWriter& directoryDefinitions,
|
|
cmWIXSourceWriter& fileDefinitions,
|
|
cmWIXSourceWriter& featureDefinitions,
|
|
size_t& directoryCounter,
|
|
size_t& fileCounter,
|
|
const std::vector<std::string>& pkgExecutables,
|
|
std::vector<std::string>& dirIdExecutables)
|
|
{
|
|
cmsys::Directory dir;
|
|
dir.Load(topdir.c_str());
|
|
|
|
for(size_t i = 0; i < dir.GetNumberOfFiles(); ++i)
|
|
{
|
|
std::string fileName = dir.GetFile(static_cast<unsigned long>(i));
|
|
|
|
if(fileName == "." || fileName == "..")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
std::string fullPath = topdir + "/" + fileName;
|
|
|
|
if(cmSystemTools::FileIsDirectory(fullPath.c_str()))
|
|
{
|
|
std::stringstream tmp;
|
|
tmp << "DIR_ID_" << ++directoryCounter;
|
|
std::string subDirectoryId = tmp.str();
|
|
|
|
directoryDefinitions.BeginElement("Directory");
|
|
directoryDefinitions.AddAttribute("Id", subDirectoryId);
|
|
directoryDefinitions.AddAttribute("Name", fileName);
|
|
|
|
AddDirectoryAndFileDefinitons(
|
|
fullPath, subDirectoryId,
|
|
directoryDefinitions,
|
|
fileDefinitions,
|
|
featureDefinitions,
|
|
directoryCounter,
|
|
fileCounter,
|
|
pkgExecutables,
|
|
dirIdExecutables);
|
|
directoryDefinitions.EndElement();
|
|
}
|
|
else
|
|
{
|
|
std::stringstream tmp;
|
|
tmp << "_ID_" << ++fileCounter;
|
|
std::string idSuffix = tmp.str();
|
|
|
|
std::string componentId = std::string("CMP") + idSuffix;
|
|
std::string fileId = std::string("FILE") + idSuffix;
|
|
|
|
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");
|
|
|
|
fileDefinitions.EndElement();
|
|
fileDefinitions.EndElement();
|
|
fileDefinitions.EndElement();
|
|
|
|
featureDefinitions.BeginElement("ComponentRef");
|
|
featureDefinitions.AddAttribute("Id", componentId);
|
|
featureDefinitions.EndElement();
|
|
|
|
std::vector<std::string>::const_iterator it;
|
|
for (it = pkgExecutables.begin() ;
|
|
it != pkgExecutables.end() ;
|
|
++it)
|
|
{
|
|
std::string execName = *it++;
|
|
std::string iconName = *it;
|
|
|
|
if (cmSystemTools::LowerCase(fileName) ==
|
|
cmSystemTools::LowerCase(execName) + ".exe")
|
|
{
|
|
dirIdExecutables.push_back(fileName);
|
|
dirIdExecutables.push_back(iconName);
|
|
dirIdExecutables.push_back(directoryId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool cmCPackWIXGenerator::RequireOption(
|
|
const std::string& name, std::string &value) const
|
|
{
|
|
const char* tmp = GetOption(name.c_str());
|
|
if(tmp)
|
|
{
|
|
value = tmp;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
"Required variable " << name << " not set" << std::endl);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
std::string cmCPackWIXGenerator::GetArchitecture() const
|
|
{
|
|
std::string void_p_size;
|
|
RequireOption("CPACK_WIX_SIZEOF_VOID_P", void_p_size);
|
|
|
|
if(void_p_size == "8")
|
|
{
|
|
return "x64";
|
|
}
|
|
else
|
|
{
|
|
return "x86";
|
|
}
|
|
}
|
|
|
|
std::string cmCPackWIXGenerator::GenerateGUID()
|
|
{
|
|
UUID guid;
|
|
UuidCreate(&guid);
|
|
|
|
unsigned char *tmp = 0;
|
|
UuidToString(&guid, &tmp);
|
|
|
|
std::string result(reinterpret_cast<char*>(tmp));
|
|
RpcStringFree(&tmp);
|
|
|
|
return cmSystemTools::UpperCase(result);
|
|
}
|
|
|
|
std::string cmCPackWIXGenerator::QuotePath(const std::string& path)
|
|
{
|
|
return std::string("\"") + path + '"';
|
|
}
|
|
|
|
std::string cmCPackWIXGenerator::GetRightmostExtension(
|
|
const std::string& filename)
|
|
{
|
|
std::string extension;
|
|
|
|
std::string::size_type i = filename.rfind(".");
|
|
if(i != std::string::npos)
|
|
{
|
|
extension = filename.substr(i);
|
|
}
|
|
|
|
return cmSystemTools::LowerCase(extension);
|
|
}
|