summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2024-03-19 23:41:34 (GMT)
committerBrad King <brad.king@kitware.com>2024-03-24 19:26:39 (GMT)
commit03884f4f3230f150af26ae1c503d4a43e612323c (patch)
tree611ee842f6098c2fdffb4c90baff5b454360d23c
parentcfe5bbdc54d59833047689ad416466d7fd9073f1 (diff)
downloadCMake-03884f4f3230f150af26ae1c503d4a43e612323c.zip
CMake-03884f4f3230f150af26ae1c503d4a43e612323c.tar.gz
CMake-03884f4f3230f150af26ae1c503d4a43e612323c.tar.bz2
CPack/WIX: Add support for WiX Toolset v4
Add a `CPACK_WIX_VERSION` option to specify version WiX for which the project is configured. Fixes: #23910
-rw-r--r--.gitlab/ci/configure_windows_wix_common.cmake3
-rwxr-xr-x.gitlab/ci/env_windows_arm64_vs2022_ninja.ps11
-rwxr-xr-x.gitlab/ci/env_windows_vs2022_x64_ninja.ps11
-rw-r--r--Help/cpack_gen/wix.rst99
-rw-r--r--Help/release/dev/cpack-wix.rst5
-rw-r--r--Modules/Internal/CPack/CPackWIX.cmake28
-rw-r--r--Modules/Internal/CPack/WIX.template.in53
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx157
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h5
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx45
-rw-r--r--Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h14
-rw-r--r--Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx11
-rw-r--r--Source/CPack/WiX/cmWIXFeaturesSourceWriter.h3
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx5
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.h3
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx30
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h8
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-check.cmake1
-rw-r--r--Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-stdout.txt11
-rw-r--r--Tests/RunCMake/CPack_WIX/4-AppWiX-verify-stdout.txt34
-rw-r--r--Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake8
22 files changed, 446 insertions, 82 deletions
diff --git a/.gitlab/ci/configure_windows_wix_common.cmake b/.gitlab/ci/configure_windows_wix_common.cmake
index faf2464..4219c41 100644
--- a/.gitlab/ci/configure_windows_wix_common.cmake
+++ b/.gitlab/ci/configure_windows_wix_common.cmake
@@ -1,2 +1,5 @@
get_filename_component(wix3_dir "${CMAKE_CURRENT_LIST_DIR}/../wix3" ABSOLUTE)
set(CMake_TEST_CPACK_WIX3 "${wix3_dir}" CACHE PATH "")
+
+get_filename_component(wix4_dir "${CMAKE_CURRENT_LIST_DIR}/../wix4" ABSOLUTE)
+set(CMake_TEST_CPACK_WIX4 "${wix4_dir}" CACHE PATH "")
diff --git a/.gitlab/ci/env_windows_arm64_vs2022_ninja.ps1 b/.gitlab/ci/env_windows_arm64_vs2022_ninja.ps1
index b0085d2..eb7bf6e 100755
--- a/.gitlab/ci/env_windows_arm64_vs2022_ninja.ps1
+++ b/.gitlab/ci/env_windows_arm64_vs2022_ninja.ps1
@@ -1 +1,2 @@
& "$pwsh" -File .gitlab/ci/wix3.ps1
+& "$pwsh" -File .gitlab/ci/wix4.ps1
diff --git a/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1 b/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1
index 9dde3a2..ae4a058 100755
--- a/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1
+++ b/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1
@@ -5,3 +5,4 @@ if ("$env:CMAKE_CI_NIGHTLY" -eq "true") {
}
& "$pwsh" -File .gitlab/ci/wix3.ps1
+& "$pwsh" -File .gitlab/ci/wix4.ps1
diff --git a/Help/cpack_gen/wix.rst b/Help/cpack_gen/wix.rst
index 4b627e7..dfa3434 100644
--- a/Help/cpack_gen/wix.rst
+++ b/Help/cpack_gen/wix.rst
@@ -9,8 +9,68 @@ Use the `WiX Toolset`_ to produce a Windows Installer ``.msi`` database.
The :variable:`CPACK_COMPONENT_<compName>_DISABLED` variable is now
supported.
+WiX Toolsets
+^^^^^^^^^^^^
+
+CPack selects one of the following variants of the WiX Toolset
+based on the :variable:`CPACK_WIX_VERSION` variable:
+
+* `WiX .NET Tools`_
+* `WiX Toolset v3`_
+
+WiX .NET Tools
+""""""""""""""
+
+Packaging is performed using the following tools:
+
+``wix build``
+ Build WiX source files directly into a Windows Installer ``.msi`` database.
+
+ Invocations may be customized using tool-specific variables:
+
+ * :variable:`CPACK_WIX_BUILD_EXTENSIONS <CPACK_WIX_<TOOL>_EXTENSIONS>`
+ * :variable:`CPACK_WIX_BUILD_EXTRA_FLAGS <CPACK_WIX_<TOOL>_EXTRA_FLAGS>`
+
+WiX extensions must be named with the form ``WixToolset.<Name>.wixext``.
+
+CPack expects the ``wix`` .NET tool to be available for command-line use
+with any required WiX extensions already installed. Be sure the ``wix``
+version is compatible with :variable:`CPACK_WIX_VERSION`, and that WiX
+extension versions match the ``wix`` tool version. For example:
+
+1. Install the ``wix`` command-line tool using ``dotnet``.
+
+ To install ``wix`` globally for the current user:
+
+ .. code-block:: bat
+
+ dotnet tool install --global wix --version 4.0.4
+
+ This places ``wix.exe`` in ``%USERPROFILE%\.dotnet\tools`` and adds
+ the directory to the current user's ``PATH`` environment variable.
+
+ Or, to install ``wix`` in a specific path, e.g., in ``c:\WiX``:
+
+ .. code-block:: bat
+
+ dotnet tool install --tool-path c:\WiX wix --version 4.0.4
+
+ This places ``wix.exe`` in ``c:\WiX``, but does *not* add it to the
+ current user's ``PATH`` environment variable. The ``WIX`` environment
+ variable may be set to tell CPack where to find the tool,
+ e.g., ``set WIX=c:\WiX``.
+
+2. Add the WiX ``UI`` extension, needed by CPack's default WiX template:
+
+ .. code-block:: bat
+
+ wix extension add --global WixToolset.UI.wixext/4.0.4
+
+ Extensions added globally are stored in ``%USERPROFILE%\.wix``, or if the
+ ``WIX_EXTENSIONS`` environment variable is set, in ``%WIX_EXTENSIONS%\.wix``.
+
WiX Toolset v3
-^^^^^^^^^^^^^^
+""""""""""""""
Packaging is performed using the following tools:
@@ -45,6 +105,19 @@ Variables specific to CPack WIX generator
The following variables are specific to the installers built on
Windows using WiX.
+.. variable:: CPACK_WIX_VERSION
+
+ .. versionadded:: 3.30
+
+ Specify the version of WiX Toolset for which the configuration
+ is written. The value must be one of
+
+ ``4``
+ Package using `WiX .NET Tools`_.
+
+ ``3``
+ Package using `WiX Toolset v3`_. This is the default.
+
.. variable:: CPACK_WIX_UPGRADE_GUID
Upgrade GUID (``Product/@UpgradeCode``)
@@ -101,8 +174,13 @@ Windows using WiX.
.. variable:: CPACK_WIX_UI_REF
- Specify the WiX ``UI`` extension's dialog set.
- This is the Id of the ``<UIRef>`` element in the default WiX template.
+ Specify the WiX ``UI`` extension's dialog set:
+
+ * With `WiX .NET Tools`_, this is the Id of the
+ ``<ui:WixUI>`` element in the default WiX template.
+
+ * With `WiX Toolset v3`_, this is the Id of the
+ ``<UIRef>`` element in the default WiX template.
The default is ``WixUI_InstallDir`` in case no CPack components have
been defined and ``WixUI_FeatureTree`` otherwise.
@@ -234,7 +312,7 @@ Windows using WiX.
.. variable:: CPACK_WIX_EXTRA_OBJECTS
- Extra WiX object files or libraries.
+ Extra WiX object files or libraries to use with `WiX Toolset v3`_.
This variable provides an optional list of extra WiX object (``.wixobj``)
and/or WiX library (``.wixlib``) files. The paths must be absolute.
@@ -242,17 +320,17 @@ Windows using WiX.
.. variable:: CPACK_WIX_EXTENSIONS
Specify a list of additional extensions for WiX tools.
- See `WiX Toolset v3`_ for extension naming patterns.
+ See `WiX Toolsets`_ for extension naming patterns.
.. variable:: CPACK_WIX_<TOOL>_EXTENSIONS
Specify a list of additional extensions for a specific WiX tool.
- See `WiX Toolset v3`_ for possible ``<TOOL>`` names.
+ See `WiX Toolsets`_ for possible ``<TOOL>`` names.
.. variable:: CPACK_WIX_<TOOL>_EXTRA_FLAGS
Specify a list of additional command-line flags for a specific WiX tool.
- See `WiX Toolset v3`_ for possible ``<TOOL>`` names.
+ See `WiX Toolsets`_ for possible ``<TOOL>`` names.
Use it at your own risk.
Future versions of CPack may generate flags which may be in conflict
@@ -356,8 +434,8 @@ Windows using WiX.
.. versionadded:: 3.23
If this variable is set to true, the default inclusion of the WiX ``UI``
- extension is skipped, i.e., the ``-ext WixUIExtension`` flag is not
- passed to WiX tools.
+ extension is skipped, i.e., the ``-ext WixUIExtension`` or
+ ``-ext WixToolset.UI.wixext`` flag is not passed to WiX tools.
.. variable:: CPACK_WIX_ARCHITECTURE
@@ -386,6 +464,9 @@ Windows using WiX.
``NONE``
Create an installer without any ``InstallScope`` attribute.
+ This is not supported if :variable:`CPACK_WIX_VERSION` is set
+ to any value other than ``3``.
+
.. deprecated:: 3.29
This value is only for compatibility with the inconsistent behavior used
diff --git a/Help/release/dev/cpack-wix.rst b/Help/release/dev/cpack-wix.rst
new file mode 100644
index 0000000..020dfeb
--- /dev/null
+++ b/Help/release/dev/cpack-wix.rst
@@ -0,0 +1,5 @@
+cpack-wix
+---------
+
+* The :cpack_gen:`CPack WIX Generator` gained support for WiX Toolset v4.
+ See the :variable:`CPACK_WIX_VERSION` variable.
diff --git a/Modules/Internal/CPack/CPackWIX.cmake b/Modules/Internal/CPack/CPackWIX.cmake
index 5fe772e..103d21c 100644
--- a/Modules/Internal/CPack/CPackWIX.cmake
+++ b/Modules/Internal/CPack/CPackWIX.cmake
@@ -5,18 +5,24 @@ if(NOT CPACK_WIX_ROOT)
string(REPLACE "\\" "/" CPACK_WIX_ROOT "$ENV{WIX}")
endif()
-find_program(CPACK_WIX_CANDLE_EXECUTABLE candle
- PATHS "${CPACK_WIX_ROOT}" PATH_SUFFIXES "bin")
+if(CPACK_WIX_VERSION VERSION_GREATER_EQUAL 4)
+ find_program(CPACK_WIX_EXECUTABLE NAMES wix
+ PATHS "${CPACK_WIX_ROOT}" PATH_SUFFIXES "bin")
+ if(NOT CPACK_WIX_EXECUTABLE)
+ message(FATAL_ERROR "Could not find the 'wix' executable.")
+ endif()
+else()
+ find_program(CPACK_WIX_CANDLE_EXECUTABLE candle
+ PATHS "${CPACK_WIX_ROOT}" PATH_SUFFIXES "bin")
+ if(NOT CPACK_WIX_CANDLE_EXECUTABLE)
+ message(FATAL_ERROR "Could not find the WiX candle executable.")
+ endif()
-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}" PATH_SUFFIXES "bin")
-
-if(NOT CPACK_WIX_LIGHT_EXECUTABLE)
- message(FATAL_ERROR "Could not find the WiX light executable.")
+ find_program(CPACK_WIX_LIGHT_EXECUTABLE light
+ PATHS "${CPACK_WIX_ROOT}" PATH_SUFFIXES "bin")
+ if(NOT CPACK_WIX_LIGHT_EXECUTABLE)
+ message(FATAL_ERROR "Could not find the WiX light executable.")
+ endif()
endif()
if(NOT DEFINED CPACK_WIX_INSTALL_SCOPE)
diff --git a/Modules/Internal/CPack/WIX.template.in b/Modules/Internal/CPack/WIX.template.in
new file mode 100644
index 0000000..7cad186
--- /dev/null
+++ b/Modules/Internal/CPack/WIX.template.in
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?include "cpack_variables.wxi"?>
+
+<Wix
+ xmlns="http://wixtoolset.org/schemas/v4/wxs"@CPACK_WIX_CUSTOM_XMLNS_EXPANDED@
+ RequiredVersion="4.0"
+ >
+
+ <Package
+ Name="$(var.CPACK_PACKAGE_NAME)"
+ Version="$(var.CPACK_PACKAGE_VERSION)"
+ Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
+ UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)"
+ ProductCode="$(var.CPACK_WIX_PRODUCT_GUID)"
+ Scope="$(var.CPACK_WIX_INSTALL_SCOPE)"
+ InstallerVersion="500"
+ Language="1033"
+ 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"/>
+
+ <?ifdef CPACK_WIX_PRODUCT_ICON?>
+ <Property Id="ARPPRODUCTICON" Value="ProductIcon.ico" />
+ <Icon Id="ProductIcon.ico" SourceFile="$(var.CPACK_WIX_PRODUCT_ICON)"/>
+ <?endif?>
+
+ <?ifdef CPACK_WIX_UI_BANNER?>
+ <WixVariable Id="WixUIBannerBmp" Value="$(var.CPACK_WIX_UI_BANNER)"/>
+ <?endif?>
+
+ <?ifdef CPACK_WIX_UI_DIALOG?>
+ <WixVariable Id="WixUIDialogBmp" Value="$(var.CPACK_WIX_UI_DIALOG)"/>
+ <?endif?>
+
+ <FeatureRef Id="ProductFeature"/>
+
+ <ui:WixUI Id="$(var.CPACK_WIX_UI_REF)" />
+ <UIRef Id="WixUI_ErrorProgressText" />
+
+ <?include "properties.wxi"?>
+ <?include "product_fragment.wxi"?>
+ </Package>
+</Wix>
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index b1bb0ca..8532b3e 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -166,6 +166,16 @@ int cmCPackWIXGenerator::PackageFiles()
bool cmCPackWIXGenerator::InitializeWiXConfiguration()
{
+ if (cmValue wixVersion = GetOption("CPACK_WIX_VERSION")) {
+ if (!cmStrToULong(*wixVersion, &this->WixVersion) ||
+ this->WixVersion < 3 || this->WixVersion > 4) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_WIX_VERSION has unknown value '"
+ << *wixVersion << "'" << std::endl);
+ return false;
+ }
+ }
+
if (!ReadListFile("Internal/CPack/CPackWIX.cmake")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while executing CPackWIX.cmake" << std::endl);
@@ -232,14 +242,22 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
SetOption("CPACK_WIX_PROPERTY_ARPCONTACT", packageContact);
}
- CollectExtensions("CPACK_WIX_EXTENSIONS", this->CandleExtensions);
- CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", this->CandleExtensions);
+ if (this->WixVersion >= 4) {
+ CollectExtensions("CPACK_WIX_EXTENSIONS", this->WixExtensions);
+ if (!GetOption("CPACK_WIX_SKIP_WIX_UI_EXTENSION").IsOn()) {
+ this->WixExtensions.insert("WixToolset.UI.wixext");
+ }
+ } else {
+ CollectExtensions("CPACK_WIX_EXTENSIONS", this->CandleExtensions);
+ CollectExtensions("CPACK_WIX_CANDLE_EXTENSIONS", this->CandleExtensions);
- if (!GetOption("CPACK_WIX_SKIP_WIX_UI_EXTENSION").IsOn()) {
- this->LightExtensions.insert("WixUIExtension");
+ if (!GetOption("CPACK_WIX_SKIP_WIX_UI_EXTENSION").IsOn()) {
+ this->LightExtensions.insert("WixUIExtension");
+ }
+ CollectExtensions("CPACK_WIX_EXTENSIONS", this->LightExtensions);
+ CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", this->LightExtensions);
}
- CollectExtensions("CPACK_WIX_EXTENSIONS", this->LightExtensions);
- CollectExtensions("CPACK_WIX_LIGHT_EXTENSIONS", this->LightExtensions);
+
CollectXmlNamespaces("CPACK_WIX_CUSTOM_XMLNS", this->CustomXmlNamespaces);
cmValue patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
@@ -278,6 +296,53 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
AppendUserSuppliedExtraSources();
+ return this->WixVersion >= 4 ? this->PackageWithWix()
+ : this->PackageWithWix3();
+}
+
+bool cmCPackWIXGenerator::PackageWithWix()
+{
+ std::string wixExecutable;
+ if (!RequireOption("CPACK_WIX_EXECUTABLE", wixExecutable)) {
+ return false;
+ }
+
+ std::string arch;
+ if (cmValue archOpt = GetOption("CPACK_WIX_ARCHITECTURE")) {
+ arch = *archOpt;
+ } else {
+ arch = GetArchitecture();
+ cmCPackLogger(
+ cmCPackLog::LOG_VERBOSE,
+ "CPACK_WIX_ARCHITECTURE was not set. Invoking WiX with architecture "
+ << arch << ". " << std::endl);
+ }
+
+ std::ostringstream command;
+ command << QuotePath(wixExecutable) << " build"
+ << " -arch " << arch << " -out "
+ << QuotePath(CMakeToWixPath(packageFileNames.at(0)));
+
+ for (std::string const& ext : this->WixExtensions) {
+ command << " -ext " << QuotePath(ext);
+ }
+
+ cmList cultures{ GetOption("CPACK_WIX_CULTURES") };
+ for (std::string const& culture : cultures) {
+ command << " -culture \"" << culture << "\"";
+ }
+
+ AddCustomFlags("CPACK_WIX_BUILD_EXTRA_FLAGS", command);
+
+ for (std::string const& sourceFilename : this->WixSources) {
+ command << " -src " << QuotePath(CMakeToWixPath(sourceFilename));
+ }
+
+ return RunWiXCommand(command.str());
+}
+
+bool cmCPackWIXGenerator::PackageWithWix3()
+{
std::set<std::string> usedBaseNames;
std::ostringstream objectFiles;
@@ -341,8 +406,8 @@ void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
std::string includeFilename =
cmStrCat(this->CPackTopLevel, "/cpack_variables.wxi");
- cmWIXSourceWriter includeFile(this->Logger, includeFilename,
- this->ComponentGuidType,
+ cmWIXSourceWriter includeFile(this->WixVersion, this->Logger,
+ includeFilename, this->ComponentGuidType,
cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);
InjectXmlNamespaces(includeFile);
@@ -367,8 +432,8 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
std::string includeFilename =
cmStrCat(this->CPackTopLevel, "/properties.wxi");
- cmWIXSourceWriter includeFile(this->Logger, includeFilename,
- this->ComponentGuidType,
+ cmWIXSourceWriter includeFile(this->WixVersion, this->Logger,
+ includeFilename, this->ComponentGuidType,
cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);
InjectXmlNamespaces(includeFile);
@@ -417,8 +482,8 @@ void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
std::string includeFilename =
cmStrCat(this->CPackTopLevel, "/product_fragment.wxi");
- cmWIXSourceWriter includeFile(this->Logger, includeFilename,
- this->ComponentGuidType,
+ cmWIXSourceWriter includeFile(this->WixVersion, this->Logger,
+ includeFilename, this->ComponentGuidType,
cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);
InjectXmlNamespaces(includeFile);
@@ -459,7 +524,8 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
this->WixSources.push_back(directoryDefinitionsFilename);
cmWIXDirectoriesSourceWriter directoryDefinitions(
- this->Logger, directoryDefinitionsFilename, this->ComponentGuidType);
+ this->WixVersion, this->Logger, directoryDefinitionsFilename,
+ this->ComponentGuidType);
InjectXmlNamespaces(directoryDefinitions);
directoryDefinitions.BeginElement("Fragment");
@@ -468,11 +534,13 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
return false;
}
- directoryDefinitions.BeginElement("Directory");
- directoryDefinitions.AddAttribute("Id", "TARGETDIR");
- directoryDefinitions.AddAttribute("Name", "SourceDir");
+ if (this->WixVersion == 3) {
+ directoryDefinitions.BeginElement("Directory");
+ directoryDefinitions.AddAttribute("Id", "TARGETDIR");
+ directoryDefinitions.AddAttribute("Name", "SourceDir");
+ }
- size_t installRootSize =
+ auto installationPrefixDirectory =
directoryDefinitions.BeginInstallationPrefixDirectory(GetRootFolderId(),
installRoot);
@@ -481,7 +549,8 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
this->WixSources.push_back(fileDefinitionsFilename);
- cmWIXFilesSourceWriter fileDefinitions(this->Logger, fileDefinitionsFilename,
+ cmWIXFilesSourceWriter fileDefinitions(this->WixVersion, this->Logger,
+ fileDefinitionsFilename,
this->ComponentGuidType);
InjectXmlNamespaces(fileDefinitions);
@@ -492,8 +561,9 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
this->WixSources.push_back(featureDefinitionsFilename);
- cmWIXFeaturesSourceWriter featureDefinitions(
- this->Logger, featureDefinitionsFilename, this->ComponentGuidType);
+ cmWIXFeaturesSourceWriter featureDefinitions(this->WixVersion, this->Logger,
+ featureDefinitionsFilename,
+ this->ComponentGuidType);
InjectXmlNamespaces(featureDefinitions);
featureDefinitions.BeginElement("Fragment");
@@ -501,7 +571,11 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
featureDefinitions.BeginElement("Feature");
featureDefinitions.AddAttribute("Id", "ProductFeature");
featureDefinitions.AddAttribute("Display", "expand");
- featureDefinitions.AddAttribute("Absent", "disallow");
+ if (this->WixVersion >= 4) {
+ featureDefinitions.AddAttribute("AllowAbsent", "no");
+ } else {
+ featureDefinitions.AddAttribute("Absent", "disallow");
+ }
featureDefinitions.AddAttribute("ConfigurableDirectory", "INSTALL_ROOT");
std::string cpackPackageName;
@@ -583,7 +657,8 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
featureDefinitions.EndElement("Fragment");
fileDefinitions.EndElement("Fragment");
- directoryDefinitions.EndInstallationPrefixDirectory(installRootSize);
+ directoryDefinitions.EndInstallationPrefixDirectory(
+ installationPrefixDirectory);
if (emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) !=
emittedShortcutTypes.end()) {
@@ -601,7 +676,9 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
directoryDefinitions.EmitStartupFolder();
}
- directoryDefinitions.EndElement("Directory");
+ if (this->WixVersion == 3) {
+ directoryDefinitions.EndElement("Directory");
+ }
directoryDefinitions.EndElement("Fragment");
if (!GenerateMainSourceFileFromTemplate()) {
@@ -613,15 +690,19 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
std::string cmCPackWIXGenerator::GetRootFolderId() const
{
+ std::string result;
+
if (GetOption("CPACK_WIX_SKIP_PROGRAM_FOLDER").IsOn()) {
- return "";
+ return result;
}
- std::string result = "ProgramFiles<64>Folder";
-
cmValue rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID");
if (rootFolderId) {
result = *rootFolderId;
+ } else if (this->WixVersion >= 4) {
+ result = "ProgramFiles6432Folder";
+ } else {
+ result = "ProgramFiles<64>Folder";
}
if (GetArchitecture() == "x86"_s) {
@@ -640,7 +721,9 @@ bool cmCPackWIXGenerator::GenerateMainSourceFileFromTemplate()
wixTemplate = *wixtpl;
} else {
cm::optional<cm::string_view> alt;
- alt = "WIX-v3/"_s;
+ if (this->WixVersion == 3) {
+ alt = "WIX-v3/"_s;
+ }
wixTemplate = FindTemplate("WIX.template.in"_s, alt);
}
@@ -768,21 +851,31 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
cmWIXFeaturesSourceWriter& featureDefinitions)
{
std::string directoryId;
+ std::string directoryRef = "DirectoryRef";
switch (type) {
case cmWIXShortcuts::START_MENU: {
cmValue cpackWixProgramMenuFolder =
GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER");
if (cpackWixProgramMenuFolder && cpackWixProgramMenuFolder == "."_s) {
directoryId = "ProgramMenuFolder";
+ if (this->WixVersion >= 4) {
+ directoryRef = "StandardDirectory";
+ }
} else {
directoryId = "PROGRAM_MENU_FOLDER";
}
} break;
case cmWIXShortcuts::DESKTOP:
directoryId = "DesktopFolder";
+ if (this->WixVersion >= 4) {
+ directoryRef = "StandardDirectory";
+ }
break;
case cmWIXShortcuts::STARTUP:
directoryId = "StartupFolder";
+ if (this->WixVersion >= 4) {
+ directoryRef = "StandardDirectory";
+ }
break;
default:
return false;
@@ -814,7 +907,7 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
componentId += idSuffix;
- fileDefinitions.BeginElement("DirectoryRef");
+ fileDefinitions.BeginElement(directoryRef);
fileDefinitions.AddAttribute("Id", directoryId);
fileDefinitions.BeginElement("Component");
@@ -844,7 +937,7 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
}
fileDefinitions.EndElement("Component");
- fileDefinitions.EndElement("DirectoryRef");
+ fileDefinitions.EndElement(directoryRef);
featureDefinitions.EmitComponentRef(componentId);
featureDefinitions.EndElement("FeatureRef");
@@ -1199,6 +1292,12 @@ void cmCPackWIXGenerator::CollectXmlNamespaces(std::string const& variableName,
}
}
std::string xmlns;
+ if (this->WixVersion >= 4 &&
+ cm::contains(this->WixExtensions, "WixToolset.UI.wixext") &&
+ !cm::contains(namespaces, "ui")) {
+ xmlns = cmStrCat(
+ xmlns, "\n xmlns:ui=\"http://wixtoolset.org/schemas/v4/wxs/ui\"");
+ }
for (auto& ns : namespaces) {
xmlns = cmStrCat(xmlns, "\n xmlns:", ns.first, "=\"",
cmWIXSourceWriter::EscapeAttributeValue(ns.second), '"');
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index 8609cf3..63530d4 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -59,6 +59,8 @@ private:
bool InitializeWiXConfiguration();
bool PackageFilesImpl();
+ bool PackageWithWix();
+ bool PackageWithWix3();
void CreateWiXVariablesIncludeFile();
@@ -160,6 +162,7 @@ private:
id_map_t PathToIdMap;
ambiguity_map_t IdAmbiguityCounter;
+ extension_set_t WixExtensions;
extension_set_t CandleExtensions;
extension_set_t LightExtensions;
xmlns_map_t CustomXmlNamespaces;
@@ -168,5 +171,7 @@ private:
std::unique_ptr<cmWIXPatch> Patch;
+ unsigned long WixVersion = 3;
+
cmWIXSourceWriter::GuidType ComponentGuidType;
};
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
index a655d86..b1e7bd2 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
@@ -5,15 +5,16 @@
#include <cmext/string_view>
cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter(
- cmCPackLog* logger, std::string const& filename, GuidType componentGuidType)
- : cmWIXSourceWriter(logger, filename, componentGuidType)
+ unsigned long wixVersion, cmCPackLog* logger, std::string const& filename,
+ GuidType componentGuidType)
+ : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
{
}
void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
std::string const& startMenuFolder)
{
- BeginElement("Directory");
+ BeginElement_StandardDirectory();
AddAttribute("Id", "ProgramMenuFolder");
if (startMenuFolder != "."_s) {
@@ -23,34 +24,39 @@ void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
EndElement("Directory");
}
- EndElement("Directory");
+ EndElement_StandardDirectory();
}
void cmWIXDirectoriesSourceWriter::EmitDesktopFolder()
{
- BeginElement("Directory");
+ BeginElement_StandardDirectory();
AddAttribute("Id", "DesktopFolder");
- AddAttribute("Name", "Desktop");
- EndElement("Directory");
+ if (this->WixVersion == 3) {
+ AddAttribute("Name", "Desktop");
+ }
+ EndElement_StandardDirectory();
}
void cmWIXDirectoriesSourceWriter::EmitStartupFolder()
{
- BeginElement("Directory");
+ BeginElement_StandardDirectory();
AddAttribute("Id", "StartupFolder");
- AddAttribute("Name", "Startup");
- EndElement("Directory");
+ if (this->WixVersion == 3) {
+ AddAttribute("Name", "Startup");
+ }
+ EndElement_StandardDirectory();
}
-size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
+cmWIXDirectoriesSourceWriter::InstallationPrefixDirectory
+cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
std::string const& programFilesFolderId,
std::string const& installRootString)
{
- size_t offset = 1;
+ InstallationPrefixDirectory installationPrefixDirectory;
if (!programFilesFolderId.empty()) {
- BeginElement("Directory");
+ installationPrefixDirectory.HasStandardDirectory = true;
+ this->BeginElement_StandardDirectory();
AddAttribute("Id", programFilesFolderId);
- offset = 0;
}
std::vector<std::string> installRoot;
@@ -62,6 +68,7 @@ size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
}
for (size_t i = 1; i < installRoot.size(); ++i) {
+ ++installationPrefixDirectory.Depth;
BeginElement("Directory");
if (i == installRoot.size() - 1) {
@@ -75,12 +82,16 @@ size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
AddAttribute("Name", installRoot[i]);
}
- return installRoot.size() - offset;
+ return installationPrefixDirectory;
}
-void cmWIXDirectoriesSourceWriter::EndInstallationPrefixDirectory(size_t size)
+void cmWIXDirectoriesSourceWriter::EndInstallationPrefixDirectory(
+ InstallationPrefixDirectory installationPrefixDirectory)
{
- for (size_t i = 0; i < size; ++i) {
+ for (size_t i = 0; i < installationPrefixDirectory.Depth; ++i) {
EndElement("Directory");
}
+ if (installationPrefixDirectory.HasStandardDirectory) {
+ this->EndElement_StandardDirectory();
+ }
}
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
index 0af3094..b0aa1e2 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
@@ -13,7 +13,8 @@
class cmWIXDirectoriesSourceWriter : public cmWIXSourceWriter
{
public:
- cmWIXDirectoriesSourceWriter(cmCPackLog* logger, std::string const& filename,
+ cmWIXDirectoriesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
+ std::string const& filename,
GuidType componentGuidType);
void EmitStartMenuFolder(std::string const& startMenuFolder);
@@ -22,9 +23,16 @@ public:
void EmitStartupFolder();
- size_t BeginInstallationPrefixDirectory(
+ struct InstallationPrefixDirectory
+ {
+ bool HasStandardDirectory = false;
+ size_t Depth = 0;
+ };
+
+ InstallationPrefixDirectory BeginInstallationPrefixDirectory(
std::string const& programFilesFolderId,
std::string const& installRootString);
- void EndInstallationPrefixDirectory(size_t size);
+ void EndInstallationPrefixDirectory(
+ InstallationPrefixDirectory installationPrefixDirectory);
};
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
index 78c2208..0d2e6e8 100644
--- a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.cxx
@@ -5,8 +5,9 @@
#include "cmStringAlgorithms.h"
cmWIXFeaturesSourceWriter::cmWIXFeaturesSourceWriter(
- cmCPackLog* logger, std::string const& filename, GuidType componentGuidType)
- : cmWIXSourceWriter(logger, filename, componentGuidType)
+ unsigned long wixVersion, cmCPackLog* logger, std::string const& filename,
+ GuidType componentGuidType)
+ : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
{
}
@@ -69,7 +70,11 @@ void cmWIXFeaturesSourceWriter::EmitFeatureForComponent(
AddAttributeUnlessEmpty("Description", component.Description);
if (component.IsRequired) {
- AddAttribute("Absent", "disallow");
+ if (this->WixVersion >= 4) {
+ AddAttribute("AllowAbsent", "no");
+ } else {
+ AddAttribute("Absent", "disallow");
+ }
}
if (component.IsHidden) {
diff --git a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
index 0facf97..95de8fe 100644
--- a/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFeaturesSourceWriter.h
@@ -12,7 +12,8 @@
class cmWIXFeaturesSourceWriter : public cmWIXSourceWriter
{
public:
- cmWIXFeaturesSourceWriter(cmCPackLog* logger, std::string const& filename,
+ cmWIXFeaturesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
+ std::string const& filename,
GuidType componentGuidType);
void CreateCMakePackageRegistryEntry(std::string const& package,
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index b4085d5..87ac6ac 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -15,10 +15,11 @@
#include "cmUuid.h"
#include "cmWIXAccessControlList.h"
-cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
+cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(unsigned long wixVersion,
+ cmCPackLog* logger,
std::string const& filename,
GuidType componentGuidType)
- : cmWIXSourceWriter(logger, filename, componentGuidType)
+ : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
{
}
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
index 60dddd4..f560304 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -13,7 +13,8 @@
class cmWIXFilesSourceWriter : public cmWIXSourceWriter
{
public:
- cmWIXFilesSourceWriter(cmCPackLog* logger, std::string const& filename,
+ cmWIXFilesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
+ std::string const& filename,
GuidType componentGuidType);
void EmitShortcut(std::string const& id, cmWIXShortcut const& shortcut,
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index ef6712a..33e8a70 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -8,11 +8,13 @@
#include "cmCryptoHash.h"
#include "cmUuid.h"
-cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
+cmWIXSourceWriter::cmWIXSourceWriter(unsigned long wixVersion,
+ cmCPackLog* logger,
std::string const& filename,
GuidType componentGuidType,
RootElementType rootElementType)
- : Logger(logger)
+ : WixVersion(wixVersion)
+ , Logger(logger)
, File(filename.c_str())
, State(DEFAULT)
, SourceFilename(filename)
@@ -26,7 +28,11 @@ cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
BeginElement("Wix");
}
- AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi");
+ if (this->WixVersion >= 4) {
+ AddAttribute("xmlns", "http://wixtoolset.org/schemas/v4/wxs");
+ } else {
+ AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi");
+ }
}
cmWIXSourceWriter::~cmWIXSourceWriter()
@@ -42,6 +48,24 @@ cmWIXSourceWriter::~cmWIXSourceWriter()
EndElement(Elements.back());
}
+void cmWIXSourceWriter::BeginElement_StandardDirectory()
+{
+ if (this->WixVersion >= 4) {
+ BeginElement("StandardDirectory");
+ } else {
+ BeginElement("Directory");
+ }
+}
+
+void cmWIXSourceWriter::EndElement_StandardDirectory()
+{
+ if (this->WixVersion >= 4) {
+ EndElement("StandardDirectory");
+ } else {
+ EndElement("Directory");
+ }
+}
+
void cmWIXSourceWriter::BeginElement(std::string const& name)
{
if (State == BEGIN) {
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index f643acd..1089cf5 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -27,12 +27,15 @@ public:
INCLUDE_ELEMENT_ROOT
};
- cmWIXSourceWriter(cmCPackLog* logger, std::string const& filename,
- GuidType componentGuidType,
+ cmWIXSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
+ std::string const& filename, GuidType componentGuidType,
RootElementType rootElementType = WIX_ELEMENT_ROOT);
~cmWIXSourceWriter();
+ void BeginElement_StandardDirectory();
+ void EndElement_StandardDirectory();
+
void BeginElement(std::string const& name);
void EndElement(std::string const& name);
@@ -52,6 +55,7 @@ public:
static std::string EscapeAttributeValue(std::string const& value);
protected:
+ unsigned long WixVersion;
cmCPackLog* Logger;
private:
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index ec05b90..575a321 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -1100,9 +1100,10 @@ endif()
add_RunCMake_test_group(CPack "${cpack_tests}")
-if(CMake_TEST_CPACK_WIX3)
+if(CMake_TEST_CPACK_WIX3 OR CMake_TEST_CPACK_WIX4)
add_RunCMake_test(CPack_WIX
-DCMake_TEST_CPACK_WIX3=${CMake_TEST_CPACK_WIX3}
+ -DCMake_TEST_CPACK_WIX4=${CMake_TEST_CPACK_WIX4}
)
endif()
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-check.cmake b/Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-check.cmake
new file mode 100644
index 0000000..a7a28ae
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-check.cmake
@@ -0,0 +1 @@
+include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-stdout.txt b/Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-stdout.txt
new file mode 100644
index 0000000..51f06ca
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-cpack-WIX-stdout.txt
@@ -0,0 +1,11 @@
+CPack: Create package using WIX
+CPack: Install projects
+CPack: - Install project: CPackWiXGenerator \[Release\]
+CPack: - Install component: applications
+CPack: - Install component: applications2
+CPack: - Install component: extras
+CPack: - Install component: headers
+CPack: - Install component: libraries
+CPack: Create package
+CPack: - package: [^
+]*/Tests/RunCMake/CPack_WIX/4-AppWiX-build/MyLib-1\.0\.0-(win64|windows-arm64)\.msi generated\.
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-verify-stdout.txt b/Tests/RunCMake/CPack_WIX/4-AppWiX-verify-stdout.txt
new file mode 100644
index 0000000..a379859
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-verify-stdout.txt
@@ -0,0 +1,34 @@
+-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi
+Component: 'CM_CP_applications.bin.my_libapp.exe' 'CM_DP_applications.bin'
+Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER'
+Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder'
+Component: 'CM_CP_applications2.bin.my_other_app.exe' 'CM_DP_applications2.bin'
+Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER'
+Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder'
+Component: 'CM_C_EMPTY_CM_DP_extras.extras.empty' 'CM_DP_extras.extras.empty'
+Component: 'CM_CP_headers.include.file_with_spaces.h' 'CM_DP_headers.include'
+Component: 'CM_CP_headers.include.mylib.h' 'CM_DP_headers.include'
+Component: 'CM_CP_libraries.lib.mylib.lib' 'CM_DP_libraries.lib'
+Directory: 'INSTALL_ROOT' 'ProgramFiles6432Folder' '[^']*\|CPack Component Example'
+Directory: 'CM_DP_applications.bin' 'INSTALL_ROOT' 'bin'
+Directory: 'CM_DP_applications2.bin' 'INSTALL_ROOT' 'bin'
+Directory: 'CM_DP_extras.extras.empty' 'CM_DP_extras.extras' 'empty'
+Directory: 'CM_DP_extras.extras' 'INSTALL_ROOT' 'extras'
+Directory: 'CM_DP_headers.include' 'INSTALL_ROOT' 'include'
+Directory: 'CM_DP_libraries.lib' 'INSTALL_ROOT' 'lib'
+Directory: 'ProgramFiles6432Folder' 'ProgramFiles64Folder' '.'
+Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib'
+Directory: 'ProgramMenuFolder' 'TARGETDIR' 'PMenu'
+Directory: 'ProgramFiles64Folder' 'TARGETDIR' 'PFiles64'
+Directory: 'TARGETDIR' '' 'SourceDir'
+Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop'
+File: 'CM_FP_applications.bin.my_libapp.exe' 'CM_CP_applications.bin.my_libapp.exe' '[^']*\|my-libapp.exe'
+File: 'CM_FP_applications2.bin.my_other_app.exe' 'CM_CP_applications2.bin.my_other_app.exe' '[^']*\|my-other-app.exe'
+File: 'CM_FP_headers.include.file_with_spaces.h' 'CM_CP_headers.include.file_with_spaces.h' '[^']*\|file with spaces.h'
+File: 'CM_FP_headers.include.mylib.h' 'CM_CP_headers.include.mylib.h' 'mylib.h'
+File: 'CM_FP_libraries.lib.mylib.lib' 'CM_CP_libraries.lib.mylib.lib' 'mylib.lib'
+Shortcut: 'CM_SP_applications.bin.my_libapp.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications'
+Shortcut: 'CM_DSP_applications.bin.my_libapp.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications'
+Shortcut: 'CM_SP_applications2.bin.my_other_app.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2'
+Shortcut: 'CM_DSP_applications2.bin.my_other_app.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2'
+--
diff --git a/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake b/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
index cf14d7d..816d949 100644
--- a/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
@@ -7,6 +7,7 @@ set(RunCPack_GLOB *.msi)
set(RunCPack_VERIFY powershell -ExecutionPolicy Bypass -File ${CMAKE_CURRENT_LIST_DIR}/print-msi.ps1)
function(run_cpack_wix v)
+ set(RunCMake_TEST_OPTIONS -DCPACK_WIX_VERSION=${v})
run_cpack(${v}-AppWiX SAMPLE AppWiX BUILD)
endfunction()
@@ -14,3 +15,10 @@ if(CMake_TEST_CPACK_WIX3)
set(ENV{PATH} "${CMake_TEST_CPACK_WIX3};${env_PATH}")
run_cpack_wix(3)
endif()
+
+if(CMake_TEST_CPACK_WIX4)
+ set(ENV{PATH} "${CMake_TEST_CPACK_WIX4};${env_PATH}")
+ set(ENV{WIX_EXTENSIONS} "${CMake_TEST_CPACK_WIX4}")
+ run_cpack_wix(4)
+ unset(ENV{WIX_EXTENSIONS})
+endif()