[Cmake-commits] CMake branch, next, updated. v2.8.10.2-1185-g27334cf

David Cole david.cole at kitware.com
Mon Dec 3 11:05:14 EST 2012


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  27334cf954e87ed2df3b6f2f72a3d6c8b80e8701 (commit)
       via  85baac1503c638756211ba07c4c25128e6d3d845 (commit)
      from  655896e293009d6e62c94914cef3369ce363dfb2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=27334cf954e87ed2df3b6f2f72a3d6c8b80e8701
commit 27334cf954e87ed2df3b6f2f72a3d6c8b80e8701
Merge: 655896e 85baac1
Author:     David Cole <david.cole at kitware.com>
AuthorDate: Mon Dec 3 11:04:57 2012 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Dec 3 11:04:57 2012 -0500

    Merge topic 'fix-11575-add-wix-support-to-cpack' into next
    
    85baac1 CPack: Add a WiX Generator (#11575)


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=85baac1503c638756211ba07c4c25128e6d3d845
commit 85baac1503c638756211ba07c4c25128e6d3d845
Author:     Nils Gladitz <gladitz at scivis.de>
AuthorDate: Wed Oct 3 16:08:49 2012 +0200
Commit:     David Cole <david.cole at kitware.com>
CommitDate: Mon Dec 3 11:00:31 2012 -0500

    CPack: Add a WiX Generator (#11575)
    
    This new CPack generator produces an *.msi installer file.
    Requires having the WiX Toolset installed in order to work
    properly.
    
    Download the WiX Toolset installer "WiX36.exe" here:
    
      http://wix.codeplex.com/releases/view/93929

diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
index 3a72eaa..47dad49 100644
--- a/CMakeCPackOptions.cmake.in
+++ b/CMakeCPackOptions.cmake.in
@@ -51,3 +51,27 @@ if("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
     set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr")
   endif()
 endif()
+
+if("${CPACK_GENERATOR}" STREQUAL "WIX")
+  # Reset CPACK_PACKAGE_VERSION to deal with WiX restriction.
+  # But the file names still use the full CMake_VERSION value:
+  set(CPACK_PACKAGE_FILE_NAME
+    "${CPACK_PACKAGE_NAME}- at CMake_VERSION@-${CPACK_SYSTEM_NAME}")
+  set(CPACK_SOURCE_PACKAGE_FILE_NAME
+    "${CPACK_PACKAGE_NAME}- at CMake_VERSION@-Source")
+
+  if(NOT CPACK_WIX_SIZEOF_VOID_P)
+    set(CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@")
+  endif()
+
+  set(CPACK_PACKAGE_VERSION
+    "@CMake_VERSION_MAJOR at .@CMake_VERSION_MINOR at .@CMake_VERSION_PATCH@")
+  # WIX installers require at most a 4 component version number, where
+  # each component is an integer between 0 and 65534 inclusive
+  set(tweak "@CMake_VERSION_TWEAK@")
+  if(tweak MATCHES "^[0-9]+$")
+    if(tweak GREATER 0 AND tweak LESS 65535)
+      set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${tweak}")
+    endif()
+  endif()
+endif()
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 6886ed9..42d3c0c 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -438,6 +438,7 @@ if(NOT CPACK_GENERATOR)
     endif()
   else()
     option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
+    option(CPACK_BINARY_WIX  "Enable to build WiX packages" OFF)
     option(CPACK_BINARY_ZIP  "Enable to build ZIP packages" OFF)
   endif()
 
@@ -453,6 +454,7 @@ if(NOT CPACK_GENERATOR)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TGZ          TGZ)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TBZ2         TBZ2)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_TZ           TZ)
+  cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_WIX          WIX)
   cpack_optional_append(CPACK_GENERATOR  CPACK_BINARY_ZIP          ZIP)
 
 endif()
@@ -483,7 +485,7 @@ endif()
 mark_as_advanced(CPACK_BINARY_CYGWIN CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_OSXX11
                  CPACK_BINARY_STGZ   CPACK_BINARY_TGZ          CPACK_BINARY_TBZ2
                  CPACK_BINARY_DEB    CPACK_BINARY_RPM          CPACK_BINARY_TZ
-                 CPACK_BINARY_NSIS CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE
+                 CPACK_BINARY_NSIS CPACK_BINARY_WIX CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE
                  CPACK_SOURCE_CYGWIN CPACK_SOURCE_TBZ2 CPACK_SOURCE_TGZ
                  CPACK_SOURCE_TZ CPACK_SOURCE_ZIP CPACK_BINARY_DRAGNDROP)
 
@@ -522,6 +524,9 @@ cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
 cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "")
 cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "")
 
+# WiX specific variables
+cpack_set_if_not_set(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
+
 if(DEFINED CPACK_COMPONENTS_ALL)
   if(CPACK_MONOLITHIC_INSTALL)
     message("CPack warning: both CPACK_COMPONENTS_ALL and CPACK_MONOLITHIC_INSTALL have been set.\nDefaulting to a monolithic installation.")
diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake
new file mode 100644
index 0000000..f278953
--- /dev/null
+++ b/Modules/CPackWIX.cmake
@@ -0,0 +1,83 @@
+##section Variables specific to CPack WiX generator
+##end
+##module
+# - CPack WiX generator specific options
+#
+# The following variables are specific to the installers built
+# on Windows using WiX.
+##end
+##variable
+#  CPACK_WIX_UPGRADE_GUID - Upgrade GUID (Product/@UpgradeCode)
+#
+# Will be automatically generated unless explicitly provided.
+#
+# It should be explicitly set to a constant generated
+# gloabally unique identifier (GUID) to allow your installers
+# to replace existing installations that use the same GUID.
+#
+# You may for example explicitly set this variable in
+# your CMakeLists.txt to the value that has been generated per default.
+# You should not use GUIDs that you did not generate yourself or which may
+# belong to other projects.
+#
+# A GUID shall have the following fixed length syntax:
+# XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
+#  (each X represents an uppercase hexadecimal digit)
+##end
+##variable
+#  CPACK_WIX_PRODUCT_GUID - Product GUID (Product/@Id)
+#
+# Will be automatically generated unless explicitly provided.
+#
+# If explicitly provided this will set the Product Id of your installer.
+#
+# The installer will abort if it detects a pre-existing installation that uses
+# the same GUID.
+#
+# The GUID shall use the syntax described for CPACK_WIX_UPGRADE_GUID.
+##end
+##variable
+#  CPACK_WIX_LICENSE_RTF - RTF License File
+#
+# If CPACK_RESOURCE_FILE_LICENSE has an .rtf extension
+# it is used as-is.
+#
+# If CPACK_RESOURCE_FILE_LICENSE has an .txt extension
+# it is implicitly converted to RTF by the WiX Generator.
+#
+# With CPACK_WIX_LICENSE_RTF you can override the license file used
+# by the WiX Generator in case CPACK_RESOURCE_FILE_LICENSE
+# is in an unsupported format or the .txt -> .rtf
+# conversion does not work as expected.
+##end
+
+#=============================================================================
+# Copyright 2012 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.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+if(NOT CPACK_WIX_ROOT)
+  file(TO_CMAKE_PATH "$ENV{WIX}" CPACK_WIX_ROOT)
+endif()
+
+find_program(CPACK_WIX_CANDLE_EXECUTABLE candle
+  PATHS "${CPACK_WIX_ROOT}/bin")
+
+if(NOT CPACK_WIX_CANDLE_EXECUTABLE)
+  message(FATAL_ERROR "Could not find the WiX candle executable.")
+endif()
+
+find_program(CPACK_WIX_LIGHT_EXECUTABLE light
+  PATHS "${CPACK_WIX_ROOT}/bin")
+
+if(NOT CPACK_WIX_LIGHT_EXECUTABLE)
+  message(FATAL_ERROR "Could not find the WiX light executable.")
+endif()
diff --git a/Modules/WIX.template.in b/Modules/WIX.template.in
new file mode 100644
index 0000000..63fad7c
--- /dev/null
+++ b/Modules/WIX.template.in
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?include "cpack_variables.wxi"?>
+
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
+    RequiredVersion="3.6.3303.0">
+
+    <Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
+        Name="$(var.CPACK_PACKAGE_NAME)"
+        Language="1033"
+        Version="$(var.CPACK_PACKAGE_VERSION)"
+        Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
+        UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
+
+        <Package InstallerVersion="301" Compressed="yes"/>
+
+        <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+
+        <MajorUpgrade
+            Schedule="afterInstallInitialize"
+            AllowSameVersionUpgrades="yes"
+            DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."/>
+
+        <WixVariable Id="WixUILicenseRtf" Value="$(var.CPACK_WIX_LICENSE_RTF)"/>
+        <Property Id="WIXUI_INSTALLDIR" Value="INSTALL_ROOT"/>
+
+        <FeatureRef Id="ProductFeature"/>
+
+        <UIRef Id="WixUI_InstallDir" />
+    </Product>
+</Wix>
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 4de20c9..675f576 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -499,6 +499,14 @@ if(UNIX)
     )
 endif()
 
+if(WIN32)
+  set(CPACK_SRCS ${CPACK_SRCS}
+    CPack/WiX/cmCPackWIXGenerator.cxx
+    CPack/WiX/cmWIXSourceWriter.cxx
+    CPack/WiX/cmWIXRichTextFormatWriter.cxx
+  )
+endif()
+
 if(APPLE)
   set(CPACK_SRCS ${CPACK_SRCS}
     CPack/cmCPackBundleGenerator.cxx
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
new file mode 100644
index 0000000..6e8c5ea
--- /dev/null
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -0,0 +1,568 @@
+/*============================================================================
+  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";
+  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(std::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");
+
+  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(std::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 tmp;
+      tmp << "INSTALL_PREFIX_" << i;
+      directoryDefinitions.AddAttribute("Id", tmp.str());
+      }
+
+    directoryDefinitions.AddAttribute("Name", install_root[i]);
+  }
+
+  std::size_t directoryCounter = 0;
+  std::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");
+
+  AddDirectoryAndFileDefinitons(
+    toplevel, "INSTALL_ROOT",
+    directoryDefinitions, fileDefinitions, featureDefinitions,
+    directoryCounter, fileCounter);
+
+  featureDefinitions.EndElement();
+  featureDefinitions.EndElement();
+  fileDefinitions.EndElement();
+
+  for(std::size_t i = 1; i < install_root.size(); ++i)
+    {
+    directoryDefinitions.EndElement();
+    }
+
+  directoryDefinitions.EndElement();
+  directoryDefinitions.EndElement();
+  directoryDefinitions.EndElement();
+
+  std::string wixTemplate = FindTemplate("WIX.template.in");
+  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,
+  std::size_t& directoryCounter,
+  std::size_t& fileCounter)
+{
+  cmsys::Directory dir;
+  dir.Load(topdir.c_str());
+
+  for(std::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);
+
+      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();
+      }
+    }
+}
+
+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);
+
+  RPC_CSTR tmp = 0;
+  UuidToStringA(&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);
+}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
new file mode 100644
index 0000000..9fc9093
--- /dev/null
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -0,0 +1,101 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 cmCPackWIXGenerator_h
+#define cmCPackWIXGenerator_h
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <string>
+#include <map>
+
+class cmWIXSourceWriter;
+
+/** \class cmCPackWIXGenerator
+ * \brief A generator for WIX files
+ */
+class cmCPackWIXGenerator : public cmCPackGenerator
+{
+public:
+  cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
+
+protected:
+  virtual int InitializeInternal();
+
+  virtual int PackageFiles();
+
+  virtual const char* GetOutputExtension()
+    {
+    return ".msi";
+    }
+
+  virtual enum CPackSetDestdirSupport SupportsSetDestdir() const
+    {
+    return SETDESTDIR_UNSUPPORTED;
+    }
+
+  virtual bool SupportsAbsoluteDestination() const
+    {
+    return false;
+    }
+
+  virtual bool SupportsComponentInstallation() const
+    {
+    return false;
+    }
+
+private:
+  bool InitializeWiXConfiguration();
+
+  bool PackageFilesImpl();
+
+  bool CreateWiXVariablesIncludeFile();
+
+  void CopyDefinition(
+    cmWIXSourceWriter &source, const std::string &name);
+
+  void AddDefinition(cmWIXSourceWriter& source,
+    const std::string& name, const std::string& value);
+
+  bool CreateWiXSourceFiles();
+
+  bool CreateLicenseFile();
+
+  bool RunWiXCommand(const std::string& command);
+
+  bool RunCandleCommand(
+    const std::string& sourceFile, const std::string& objectFile);
+
+  bool RunLightCommand(const std::string& objectFiles);
+
+  void AddDirectoryAndFileDefinitons(const std::string& topdir,
+    const std::string& directoryId,
+    cmWIXSourceWriter& directoryDefinitions,
+    cmWIXSourceWriter& fileDefinitions,
+    cmWIXSourceWriter& featureDefinitions,
+    std::size_t& directoryCounter,
+    std::size_t& fileCounter);
+
+  bool RequireOption(const std::string& name, std::string& value) const;
+
+  std::string GetArchitecture() const;
+
+  static std::string GenerateGUID();
+
+  static std::string QuotePath(const std::string& path);
+
+  static std::string GetRightmostExtension(const std::string& filename);
+
+  std::vector<std::string> wixSources;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
new file mode 100644
index 0000000..0763344
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
@@ -0,0 +1,137 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 "cmWIXRichTextFormatWriter.h"
+
+#include <cmVersion.h>
+
+cmWIXRichTextFormatWriter::cmWIXRichTextFormatWriter(
+  const std::string& filename):
+    file(filename.c_str(), std::ios::binary)
+{
+  StartGroup();
+  WriteHeader();
+  WriteDocumentPrefix();
+}
+
+cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter()
+{
+  EndGroup();
+
+  /* I haven't seen this in the RTF spec but
+   *  wordpad terminates its RTF like this */
+  file << "\r\n";
+  file.put(0);
+}
+
+void cmWIXRichTextFormatWriter::AddText(const std::string& text)
+{
+  typedef unsigned char rtf_byte_t;
+
+  for(std::size_t i = 0; i < text.size(); ++i)
+    {
+    rtf_byte_t c = rtf_byte_t(text[i]);
+
+    switch(c)
+      {
+    case '\\':
+      file << "\\\\";
+      break;
+    case '{':
+      file << "\\{";
+      break;
+    case '}':
+      file << "\\}";
+      break;
+    case '\n':
+      file << "\\par\r\n";
+      break;
+    case '\r':
+      continue;
+    default:
+        {
+        if(c <= 0x7F)
+          {
+          file << c;
+          }
+        else
+          {
+          file << "[NON-ASCII-" << int(c) << "]";
+          }
+        }
+      break;
+      }
+    }
+}
+
+void cmWIXRichTextFormatWriter::WriteHeader()
+{
+  ControlWord("rtf1");
+  ControlWord("ansi");
+  ControlWord("ansicpg1252");
+  ControlWord("deff0");
+  ControlWord("deflang1031");
+
+  WriteFontTable();
+  WriteGenerator();
+}
+
+void cmWIXRichTextFormatWriter::WriteFontTable()
+{
+  StartGroup();
+  ControlWord("fonttbl");
+
+  StartGroup();
+  ControlWord("f0");
+  ControlWord("fswiss");
+  ControlWord("fcharset0 Arial;");
+  EndGroup();
+
+  EndGroup();
+}
+
+void cmWIXRichTextFormatWriter::WriteGenerator()
+{
+  StartGroup();
+  NewControlWord("generator");
+  file << " CPack WiX Generator (" << cmVersion::GetCMakeVersion() << ");";
+  EndGroup();
+}
+
+void cmWIXRichTextFormatWriter::WriteDocumentPrefix()
+{
+  ControlWord("viewkind4");
+  ControlWord("uc1");
+  ControlWord("pard");
+  ControlWord("f0");
+  ControlWord("fs20");
+}
+
+void cmWIXRichTextFormatWriter::ControlWord(const std::string& keyword)
+{
+  file << "\\" << keyword;
+}
+
+void cmWIXRichTextFormatWriter::NewControlWord(const std::string& keyword)
+{
+  file << "\\*\\" << keyword;
+}
+
+void cmWIXRichTextFormatWriter::StartGroup()
+{
+  file.put('{');
+}
+
+void cmWIXRichTextFormatWriter::EndGroup()
+{
+  file.put('}');
+}
diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
new file mode 100644
index 0000000..10b67c3
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h
@@ -0,0 +1,46 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2012 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 cmWIXRichTextFormatWriter_h
+#define cmWIXRichTextFormatWriter_h
+
+#include <fstream>
+
+/** \class cmWIXRichtTextFormatWriter
+ * \brief Helper class to generate Rich Text Format (RTF) documents
+ * from plain text (e.g. for license and welcome text)
+ */
+class cmWIXRichTextFormatWriter
+{
+public:
+  cmWIXRichTextFormatWriter(const std::string& filename);
+  ~cmWIXRichTextFormatWriter();
+
+  void AddText(const std::string& text);
+
+private:
+  void WriteHeader();
+  void WriteFontTable();
+  void WriteGenerator();
+
+  void WriteDocumentPrefix();
+
+  void ControlWord(const std::string& keyword);
+  void NewControlWord(const std::string& keyword);
+
+  void StartGroup();
+  void EndGroup();
+
+  std::ofstream file;
+};
+
+#endif
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
new file mode 100644
index 0000000..cc00e57
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -0,0 +1,188 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2012 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 "cmWIXSourceWriter.h"
+
+#include <CPack/cmCPackGenerator.h>
+
+#include <windows.h>
+
+cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
+  const std::string& filename,
+  bool isIncludeFile):
+    Logger(logger),
+    file(filename.c_str()),
+    state(DEFAULT)
+{
+  WriteXMLDeclaration();
+
+  if(isIncludeFile)
+    {
+    BeginElement("Include");
+    }
+  else
+    {
+    BeginElement("Wix");
+    }
+
+  AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi");
+}
+
+cmWIXSourceWriter::~cmWIXSourceWriter()
+{
+  while(elements.size())
+    {
+    EndElement();
+    }
+}
+
+void cmWIXSourceWriter::BeginElement(const std::string& name)
+{
+  if(state == BEGIN)
+    {
+    file << ">";
+    }
+
+  file << "\n";
+  Indent(elements.size());
+  file << "<" << name;
+
+  elements.push_back(name);
+  state = BEGIN;
+}
+
+void cmWIXSourceWriter::EndElement()
+{
+  if(elements.empty())
+    {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+      "can not end WiX element with no open elements" << std::endl);
+    return;
+    }
+
+  if(state == DEFAULT)
+    {
+    file << "\n";
+    Indent(elements.size()-1);
+    file << "</" << elements.back() << ">";
+    }
+  else
+    {
+    file << "/>";
+    }
+
+  elements.pop_back();
+  state = DEFAULT;
+}
+
+void cmWIXSourceWriter::AddProcessingInstruction(
+  const std::string& target, const std::string& content)
+{
+  if(state == BEGIN)
+    {
+    file << ">";
+    }
+
+  file << "\n";
+  Indent(elements.size());
+  file << "<?" << target << " " << content << "?>";
+
+  state = DEFAULT;
+}
+
+void cmWIXSourceWriter::AddAttribute(
+  const std::string& key, const std::string& value)
+{
+  std::string utf8 = WindowsCodepageToUtf8(value);
+
+  file << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"';
+}
+
+std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value)
+{
+  if(value.empty())
+    {
+    return std::string();
+    }
+
+  int characterCount = MultiByteToWideChar(
+    CP_ACP, 0, value.c_str(), value.size(), 0, 0);
+
+  if(characterCount == 0)
+    {
+    return std::string();
+    }
+
+  std::vector<wchar_t> utf16(characterCount);
+
+  MultiByteToWideChar(
+    CP_ACP, 0, value.c_str(), value.size(), &utf16[0], utf16.size());
+
+  int utf8ByteCount =
+    WideCharToMultiByte(CP_UTF8, 0, &utf16[0], utf16.size(), 0, 0, 0, 0);
+
+  if(utf8ByteCount == 0)
+    {
+    return std::string();
+    }
+
+  std::vector<char> utf8(utf8ByteCount);
+
+  WideCharToMultiByte(CP_UTF8, 0, &utf16[0], utf16.size(),
+    &utf8[0], utf8.size(), 0, 0);
+
+  return std::string(&utf8[0], utf8.size());
+}
+
+
+void cmWIXSourceWriter::WriteXMLDeclaration()
+{
+  file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
+}
+
+void cmWIXSourceWriter::Indent(std::size_t count)
+{
+  for(std::size_t i = 0; i < count; ++i)
+    {
+    file << "    ";
+    }
+}
+
+std::string cmWIXSourceWriter::EscapeAttributeValue(
+  const std::string& value)
+{
+  std::string result;
+  result.reserve(value.size());
+
+  char c = 0;
+  for(std::size_t i = 0 ; i < value.size(); ++i)
+    {
+    c = value[i];
+    switch(c)
+      {
+    case '<':
+      result += "&lt;";
+      break;
+    case '&':
+      result +="&amp;";
+      break;
+    case '"':
+      result += "&quot;";
+      break;
+    default:
+      result += c;
+      break;
+      }
+    }
+
+  return result;
+}
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
new file mode 100644
index 0000000..582554d
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -0,0 +1,67 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2012 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 cmWIXSourceWriter_h
+#define cmWIXSourceWriter_h
+
+#include <vector>
+#include <string>
+#include <fstream>
+
+#include <CPack/cmCPackLog.h>
+
+/** \class cmWIXSourceWriter
+ * \brief Helper class to generate XML WiX source files
+ */
+class cmWIXSourceWriter
+{
+public:
+  cmWIXSourceWriter(cmCPackLog* logger,
+    const std::string& filename, bool isIncludeFile = false);
+
+  ~cmWIXSourceWriter();
+
+  void BeginElement(const std::string& name);
+
+  void EndElement();
+
+  void AddProcessingInstruction(
+    const std::string& target, const std::string& content);
+
+  void AddAttribute(
+    const std::string& key, const std::string& value);
+
+  static std::string WindowsCodepageToUtf8(const std::string& value);
+
+private:
+  enum State
+  {
+    DEFAULT,
+    BEGIN
+  };
+
+  void WriteXMLDeclaration();
+
+  void Indent(std::size_t count);
+
+  static std::string EscapeAttributeValue(const std::string& value);
+
+  std::ofstream file;
+
+  std::vector<std::string> elements;
+
+  State state;
+
+  cmCPackLog* Logger;
+};
+
+#endif
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index eba1ef9..5577673 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -19,6 +19,7 @@
 #include "cmCPackZIPGenerator.h"
 #include "cmCPackSTGZGenerator.h"
 #include "cmCPackNSISGenerator.h"
+
 #ifdef __APPLE__
 #  include "cmCPackDragNDropGenerator.h"
 #  include "cmCPackBundleGenerator.h"
@@ -37,6 +38,9 @@
 #  include "cmCPackRPMGenerator.h"
 #endif
 
+#ifdef _WIN32
+#  include "WiX/cmCPackWIXGenerator.h"
+#endif
 
 #include "cmCPackLog.h"
 
@@ -82,6 +86,13 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
     this->RegisterGenerator("ZIP", "ZIP file format",
       cmCPackZIPGenerator::CreateGenerator);
     }
+#ifdef _WIN32
+  if (cmCPackWIXGenerator::CanGenerate())
+    {
+    this->RegisterGenerator("WIX", "MSI file format via WiX tools",
+      cmCPackWIXGenerator::CreateGenerator);
+    }
+#endif
   if (cmCPackTarBZip2Generator::CanGenerate())
     {
     this->RegisterGenerator("TBZ2", "Tar BZip2 compression",
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 7dc2643..2cef2fc 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -697,6 +697,29 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     endif()
   endif()
 
+  # On Windows run the CPackWiXGenerator test
+  # if the WiX Toolset seems to be available
+  if(WIN32)
+    file(TO_CMAKE_PATH "$ENV{WIX}" WIX_ROOT)
+
+    find_program(WIX_LIGHT_EXECUTABLE light
+      PATHS "${WIX_ROOT}/bin"
+      DOC "WiX Toolset light.exe location")
+
+    if(WIX_LIGHT_EXECUTABLE)
+      add_test(CPackWiXGenerator ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator"
+        "${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
+        --build-generator ${CMAKE_TEST_GENERATOR}
+        --build-project CPackWiXGenerator
+        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+        --test-command ${CMAKE_CMAKE_COMMAND}
+          "-DCPackWiXGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
+          -P "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake")
+    endif()
+  endif()
+
   if(CTEST_RUN_CPackComponents)
     set(CPackComponents_EXTRA_OPTIONS)
     if(APPLE)
diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt
new file mode 100644
index 0000000..ce02f11
--- /dev/null
+++ b/Tests/CPackWiXGenerator/CMakeLists.txt
@@ -0,0 +1,73 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(CPackWiXGenerator)
+
+add_library(mylib mylib.cpp)
+
+add_executable(mylibapp mylibapp.cpp)
+target_link_libraries(mylibapp mylib)
+
+install(TARGETS mylib
+  ARCHIVE
+  DESTINATION lib
+  COMPONENT libraries)
+
+install(TARGETS mylibapp
+  RUNTIME
+  DESTINATION bin
+  COMPONENT applications)
+
+install(FILES mylib.h "file with spaces.h"
+  DESTINATION include
+  COMPONENT headers)
+
+set(CPACK_GENERATOR "WIX")
+
+set(CPACK_PACKAGE_NAME "MyLib")
+set(CPACK_PACKAGE_VENDOR "CMake.org")
+set(CPACK_PACKAGE_CONTACT "somebody at cmake.org")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
+  "MyLib - CPack Component Installation Example")
+
+set(CPACK_PACKAGE_VERSION_MAJOR "1")
+set(CPACK_PACKAGE_VERSION_MINOR "0")
+set(CPACK_PACKAGE_VERSION_PATCH "0")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
+
+set(CPACK_WIX_UPGRADE_GUID "BF20CE5E-7F7C-401D-8F7C-AB45E8D170E6")
+
+include(CPack)
+
+cpack_add_install_type(Full DISPLAY_NAME "Everything")
+cpack_add_install_type(Developer)
+
+cpack_add_component_group(Runtime)
+
+cpack_add_component_group(Development
+  EXPANDED
+  DESCRIPTION "All of the tools you'll ever need to develop software")
+
+cpack_add_component(applications
+  DISPLAY_NAME "MyLib Application"
+  DESCRIPTION "An extremely useful application that makes use of MyLib"
+  GROUP Runtime
+  INSTALL_TYPES Full)
+
+cpack_add_component(documentation
+  DISPLAY_NAME "MyLib Documentation"
+  DESCRIPTION "The extensive suite of MyLib Application documentation files"
+  GROUP Runtime
+  INSTALL_TYPES Full)
+
+cpack_add_component(libraries
+  DISPLAY_NAME "Libraries"
+  DESCRIPTION "Static libraries used to build programs with MyLib"
+  GROUP Development
+  INSTALL_TYPES Developer Full)
+
+cpack_add_component(headers
+  DISPLAY_NAME "C++ Headers"
+  DESCRIPTION "C/C++ header files for use with MyLib"
+  GROUP Development
+  DEPENDS libraries
+  INSTALL_TYPES Developer Full)
diff --git a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
new file mode 100644
index 0000000..30e33cf
--- /dev/null
+++ b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
@@ -0,0 +1,72 @@
+message(STATUS "=============================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackWiXGenerator_BINARY_DIR)
+  message(FATAL_ERROR "CPackWiXGenerator_BINARY_DIR not set")
+endif()
+
+message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
+message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}")
+message(STATUS "CPackWiXGenerator_BINARY_DIR: ${CPackWiXGenerator_BINARY_DIR}")
+
+execute_process(COMMAND "${CMAKE_CPACK_COMMAND}"
+  RESULT_VARIABLE CPack_result
+  OUTPUT_VARIABLE CPack_output
+  ERROR_VARIABLE CPack_error
+  WORKING_DIRECTORY "${CPackWiXGenerator_BINARY_DIR}")
+
+if(CPack_result)
+  message(FATAL_ERROR "CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+else ()
+  message(STATUS "CPack_output=${CPack_output}")
+endif()
+
+set(expected_file_mask "*.msi")
+file(GLOB installer_file "${expected_file_mask}")
+
+message(STATUS "installer_file='${installer_file}'")
+message(STATUS "expected_file_mask='${expected_file_mask}'")
+
+if(NOT installer_file)
+  message(FATAL_ERROR "installer_file does not exist.")
+endif()
+
+function(run_wix_command command)
+  file(TO_CMAKE_PATH "$ENV{WIX}" WIX_ROOT)
+  set(WIX_PROGRAM "${WIX_ROOT}/bin/${command}.exe")
+
+  if(NOT EXISTS "${WIX_PROGRAM}")
+    message(FATAL_ERROR "Failed to find WiX Tool: ${WIX_PROGRAM}")
+  endif()
+
+  message(STATUS "Running WiX Tool: ${command} ${ARGN}")
+
+  execute_process(COMMAND "${WIX_PROGRAM}" ${ARGN}
+    RESULT_VARIABLE WIX_result
+    OUTPUT_VARIABLE WIX_output
+    ERROR_VARIABLE WIX_output
+    WORKING_DIRECTORY "${CPackWiXGenerator_BINARY_DIR}")
+
+  message(STATUS "${command} Output: \n${WIX_output}")
+
+  if(WIX_result)
+    message(FATAL_ERROR "WiX ${command} failed: ${WIX_result}")
+  endif()
+endfunction()
+
+file(GLOB WXS_SOURCE_FILES
+  "${CPackWiXGenerator_BINARY_DIR}/_CPack_Packages/*/WIX/*.wxs")
+
+if(NOT WXS_SOURCE_FILES)
+  message(FATAL_ERROR "Failed finding WiX source files to validate.")
+endif()
+
+foreach(WXS_SOURCE_FILE IN LISTS WXS_SOURCE_FILES)
+  run_wix_command(wixcop "${WXS_SOURCE_FILE}")
+endforeach()
+
+# error SMOK1076 : ICE61: This product should remove only older
+# versions of itself. The Maximum version is not less
+# than the current product. (1.0.0 1.0.0)
+run_wix_command(smoke -nologo -wx -sw1076 "${installer_file}")
diff --git a/Tests/CPackWiXGenerator/file with spaces.h b/Tests/CPackWiXGenerator/file with spaces.h
new file mode 100644
index 0000000..e69de29
diff --git a/Tests/CPackWiXGenerator/mylib.cpp b/Tests/CPackWiXGenerator/mylib.cpp
new file mode 100644
index 0000000..8ddac19
--- /dev/null
+++ b/Tests/CPackWiXGenerator/mylib.cpp
@@ -0,0 +1,7 @@
+#include "mylib.h"
+#include "stdio.h"
+
+void mylib_function()
+{
+  printf("This is mylib");
+}
diff --git a/Tests/CPackWiXGenerator/mylib.h b/Tests/CPackWiXGenerator/mylib.h
new file mode 100644
index 0000000..5d0a822
--- /dev/null
+++ b/Tests/CPackWiXGenerator/mylib.h
@@ -0,0 +1 @@
+void mylib_function();
diff --git a/Tests/CPackWiXGenerator/mylibapp.cpp b/Tests/CPackWiXGenerator/mylibapp.cpp
new file mode 100644
index 0000000..a438ac7
--- /dev/null
+++ b/Tests/CPackWiXGenerator/mylibapp.cpp
@@ -0,0 +1,6 @@
+#include "mylib.h"
+
+int main()
+{
+  mylib_function();
+}

-----------------------------------------------------------------------

Summary of changes:
 CMakeCPackOptions.cmake.in                         |   24 +
 Modules/CPack.cmake                                |    7 +-
 Modules/CPackWIX.cmake                             |   83 +++
 Modules/WIX.template.in                            |   31 ++
 Source/CMakeLists.txt                              |    8 +
 Source/CPack/WiX/cmCPackWIXGenerator.cxx           |  568 ++++++++++++++++++++
 Source/CPack/WiX/cmCPackWIXGenerator.h             |  101 ++++
 Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx     |  137 +++++
 Source/CPack/WiX/cmWIXRichTextFormatWriter.h       |   46 ++
 Source/CPack/WiX/cmWIXSourceWriter.cxx             |  188 +++++++
 Source/CPack/WiX/cmWIXSourceWriter.h               |   67 +++
 Source/CPack/cmCPackGeneratorFactory.cxx           |   11 +
 Tests/CMakeLists.txt                               |   23 +
 Tests/CPackWiXGenerator/CMakeLists.txt             |   73 +++
 Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake |   72 +++
 .../CPackWiXGenerator/file with spaces.h           |    0
 .../mylib.cpp                                      |    0
 .../{CPackComponents => CPackWiXGenerator}/mylib.h |    0
 .../mylibapp.cpp                                   |    0
 19 files changed, 1438 insertions(+), 1 deletions(-)
 create mode 100644 Modules/CPackWIX.cmake
 create mode 100644 Modules/WIX.template.in
 create mode 100644 Source/CPack/WiX/cmCPackWIXGenerator.cxx
 create mode 100644 Source/CPack/WiX/cmCPackWIXGenerator.h
 create mode 100644 Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx
 create mode 100644 Source/CPack/WiX/cmWIXRichTextFormatWriter.h
 create mode 100644 Source/CPack/WiX/cmWIXSourceWriter.cxx
 create mode 100644 Source/CPack/WiX/cmWIXSourceWriter.h
 create mode 100644 Tests/CPackWiXGenerator/CMakeLists.txt
 create mode 100644 Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake
 copy Modules/IntelVSImplicitPath/hello.f => Tests/CPackWiXGenerator/file with spaces.h (100%)
 copy Tests/{CPackComponents => CPackWiXGenerator}/mylib.cpp (100%)
 copy Tests/{CPackComponents => CPackWiXGenerator}/mylib.h (100%)
 copy Tests/{CPackComponents => CPackWiXGenerator}/mylibapp.cpp (100%)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list