summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Sorley <ssorley@monetra.com>2017-10-09 11:39:29 -0400
committerStephen Sorley <ssorley@monetra.com>2017-10-13 13:07:37 -0400
commite1409101c99f7a3487990e9927e8bd0e275f564f (patch)
treee5c0ecb010bc9bbfc11aeea8a2e65bbe9eafd14a
parente258fe03968d27871d6a57e3f4571bc8fbba6b9b (diff)
downloadcmake-e1409101c99f7a3487990e9927e8bd0e275f564f.tar.gz
cpack wix: support WiX generator on Cygwin
Cygwin-built CMake now converts paths from Cygwin to Windows form (using cygpath -w) before they're passed to WiX. The Wix generator on Cygwin requires the libuuid-dev package when building CMake. However, the DLL it links to is installed by default as part of Cygwin's core libs, so it does not need to be distributed. If libuuid-dev isn't available, CMake is simply built without Wix support on Cygwin.
-rw-r--r--Source/CMakeLists.txt14
-rw-r--r--Source/CPack/WiX/cmCMakeToWixPath.cxx39
-rw-r--r--Source/CPack/WiX/cmCMakeToWixPath.h12
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx41
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h9
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx4
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx4
-rw-r--r--Source/Modules/FindLibUUID.cmake85
8 files changed, 192 insertions, 16 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index a4dd918602..e1c34bf25a 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -936,8 +936,13 @@ if(UNIX)
endif()
endif()
-if(WIN32)
+if(CYGWIN)
+ find_package(LibUUID)
+endif()
+if(WIN32 OR (CYGWIN AND LibUUID_FOUND))
set(CPACK_SRCS ${CPACK_SRCS}
+ CPack/Wix/cmCMakeToWixPath.cxx
+ CPack/Wix/cmCMakeToWixPath.h
CPack/WiX/cmCPackWIXGenerator.cxx
CPack/WiX/cmCPackWIXGenerator.h
CPack/WiX/cmWIXAccessControlList.cxx
@@ -958,7 +963,7 @@ if(WIN32)
CPack/WiX/cmWIXShortcut.h
CPack/WiX/cmWIXSourceWriter.cxx
CPack/WiX/cmWIXSourceWriter.h
- )
+ )
endif()
if(APPLE)
@@ -991,6 +996,11 @@ if(APPLE)
"See CMakeFiles/CMakeError.log for details of the failure.")
endif()
endif()
+if(CYGWIN AND LibUUID_FOUND)
+ target_link_libraries(CPackLib ${LibUUID_LIBRARIES})
+ include_directories(CPackLib ${LibUUID_INCLUDE_DIRS})
+ set_property(SOURCE CPack/cmCPackGeneratorFactory.cxx PROPERTY COMPILE_DEFINITIONS HAVE_LIBUUID)
+endif()
if(CPACK_ENABLE_FREEBSD_PKG AND FREEBSD_PKG_INCLUDE_DIRS AND FREEBSD_PKG_LIBRARIES)
target_link_libraries(CPackLib ${FREEBSD_PKG_LIBRARIES})
include_directories(${FREEBSD_PKG_INCLUDE_DIRS})
diff --git a/Source/CPack/WiX/cmCMakeToWixPath.cxx b/Source/CPack/WiX/cmCMakeToWixPath.cxx
new file mode 100644
index 0000000000..0b0e42aa92
--- /dev/null
+++ b/Source/CPack/WiX/cmCMakeToWixPath.cxx
@@ -0,0 +1,39 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCMakeToWixPath.h"
+
+#include "cmSystemTools.h"
+
+#include <string>
+#include <vector>
+
+#ifdef __CYGWIN__
+#include <sys/cygwin.h>
+std::string CMakeToWixPath(const std::string& cygpath)
+{
+ std::vector<char> winpath_chars;
+ ssize_t winpath_size;
+
+ // Get the required buffer size.
+ winpath_size =
+ cygwin_conv_path(CCP_POSIX_TO_WIN_A, cygpath.c_str(), nullptr, 0);
+ if (winpath_size <= 0) {
+ return cygpath;
+ }
+
+ winpath_chars.assign(static_cast<size_t>(winpath_size) + 1, '\0');
+
+ winpath_size = cygwin_conv_path(CCP_POSIX_TO_WIN_A, cygpath.c_str(),
+ winpath_chars.data(), winpath_size);
+ if (winpath_size < 0) {
+ return cygpath;
+ }
+
+ return cmSystemTools::TrimWhitespace(winpath_chars.data());
+}
+#else
+std::string CMakeToWixPath(const std::string& path)
+{
+ return path;
+}
+#endif
diff --git a/Source/CPack/WiX/cmCMakeToWixPath.h b/Source/CPack/WiX/cmCMakeToWixPath.h
new file mode 100644
index 0000000000..8bb9e04088
--- /dev/null
+++ b/Source/CPack/WiX/cmCMakeToWixPath.h
@@ -0,0 +1,12 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCMakeToWixPath_h
+#define cmCMakeToWixPath_h
+
+#include "cmConfigure.h" //IWYU pragma: keep
+
+#include <string>
+
+std::string CMakeToWixPath(const std::string& cygpath);
+
+#endif // cmCMakeToWixPath_h
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index ba07d08639..a0bc0eabd4 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -22,7 +22,13 @@
#include "cmsys/FStream.hxx"
#include "cmsys/SystemTools.hxx"
-#include <rpc.h> // for GUID generation
+#ifdef _WIN32
+#include <rpc.h> // for GUID generation (windows only)
+#else
+#include <uuid/uuid.h> // for GUID generation (libuuid)
+#endif
+
+#include "cmCMakeToWixPath.h"
cmCPackWIXGenerator::cmCPackWIXGenerator()
: Patch(0)
@@ -110,7 +116,7 @@ bool cmCPackWIXGenerator::RunLightCommand(std::string const& objectFiles)
std::ostringstream command;
command << QuotePath(executable);
command << " -nologo";
- command << " -out " << QuotePath(packageFileNames.at(0));
+ command << " -out " << QuotePath(CMakeToWixPath(packageFileNames.at(0)));
for (std::string const& ext : this->LightExtensions) {
command << " -ext " << QuotePath(ext);
@@ -270,11 +276,12 @@ bool cmCPackWIXGenerator::PackageFilesImpl()
std::string objectFilename =
this->CPackTopLevel + "/" + uniqueBaseName + ".wixobj";
- if (!RunCandleCommand(sourceFilename, objectFilename)) {
+ if (!RunCandleCommand(CMakeToWixPath(sourceFilename),
+ CMakeToWixPath(objectFilename))) {
return false;
}
- objectFiles << " " << QuotePath(objectFilename);
+ objectFiles << " " << QuotePath(CMakeToWixPath(objectFilename));
}
AppendUserSuppliedExtraObjects(objectFiles);
@@ -320,10 +327,10 @@ void cmCPackWIXGenerator::CreateWiXVariablesIncludeFile()
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");
+ CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF", DefinitionType::PATH);
+ CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON", DefinitionType::PATH);
+ CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER", DefinitionType::PATH);
+ CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG", DefinitionType::PATH);
SetOptionIfNotSet("CPACK_WIX_PROGRAM_MENU_FOLDER",
GetOption("CPACK_PACKAGE_NAME"));
CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
@@ -390,11 +397,16 @@ void cmCPackWIXGenerator::CreateWiXProductFragmentIncludeFile()
}
void cmCPackWIXGenerator::CopyDefinition(cmWIXSourceWriter& source,
- std::string const& name)
+ std::string const& name,
+ DefinitionType type)
{
const char* value = GetOption(name.c_str());
if (value) {
- AddDefinition(source, name, value);
+ if (type == DefinitionType::PATH) {
+ AddDefinition(source, name, CMakeToWixPath(value));
+ } else {
+ AddDefinition(source, name, value);
+ }
}
}
@@ -966,6 +978,7 @@ std::string cmCPackWIXGenerator::GetArchitecture() const
std::string cmCPackWIXGenerator::GenerateGUID()
{
+#ifdef _WIN32
UUID guid;
UuidCreate(&guid);
@@ -975,6 +988,14 @@ std::string cmCPackWIXGenerator::GenerateGUID()
std::string result =
cmsys::Encoding::ToNarrow(reinterpret_cast<wchar_t*>(tmp));
RpcStringFreeW(&tmp);
+#else
+ uuid_t guid;
+ char guid_ch[37] = { 0 };
+
+ uuid_generate(guid);
+ uuid_unparse(guid, guid_ch);
+ std::string result = guid_ch;
+#endif
return cmSystemTools::UpperCase(result);
}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index b2633a7f9a..128a04de88 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -48,6 +48,12 @@ private:
typedef std::map<std::string, size_t> ambiguity_map_t;
typedef std::set<std::string> extension_set_t;
+ enum class DefinitionType
+ {
+ STRING,
+ PATH
+ };
+
bool InitializeWiXConfiguration();
bool PackageFilesImpl();
@@ -58,7 +64,8 @@ private:
void CreateWiXProductFragmentIncludeFile();
- void CopyDefinition(cmWIXSourceWriter& source, std::string const& name);
+ void CopyDefinition(cmWIXSourceWriter& source, std::string const& name,
+ DefinitionType type = DefinitionType::STRING);
void AddDefinition(cmWIXSourceWriter& source, std::string const& name,
std::string const& value);
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index b4cd1a3d66..dd3caf9d3d 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -11,6 +11,8 @@
#include "cm_sys_stat.h"
+#include "cmCMakeToWixPath.h"
+
cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
std::string const& filename,
GuidType componentGuidType)
@@ -139,7 +141,7 @@ std::string cmWIXFilesSourceWriter::EmitComponentFile(
patch.ApplyFragment(componentId, *this);
BeginElement("File");
AddAttribute("Id", fileId);
- AddAttribute("Source", filePath);
+ AddAttribute("Source", CMakeToWixPath(filePath));
AddAttribute("KeyPath", "yes");
mode_t fileMode = 0;
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index 4b81bbc5f9..47e7527072 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -40,7 +40,7 @@
#include "cmCPackRPMGenerator.h"
#endif
-#ifdef _WIN32
+#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID))
#include "WiX/cmCPackWIXGenerator.h"
#endif
@@ -87,7 +87,7 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("7Z", "7-Zip file format",
cmCPack7zGenerator::CreateGenerator);
}
-#ifdef _WIN32
+#if defined(_WIN32) || (defined(__CYGWIN__) && defined(HAVE_LIBUUID))
if (cmCPackWIXGenerator::CanGenerate()) {
this->RegisterGenerator("WIX", "MSI file format via WiX tools",
cmCPackWIXGenerator::CreateGenerator);
diff --git a/Source/Modules/FindLibUUID.cmake b/Source/Modules/FindLibUUID.cmake
new file mode 100644
index 0000000000..17f11c1f5e
--- /dev/null
+++ b/Source/Modules/FindLibUUID.cmake
@@ -0,0 +1,85 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindLibUUID
+------------
+
+Find LibUUID include directory and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+An :ref:`imported target <Imported targets>` named
+``LibUUID::LibUUID`` is provided if LibUUID has been found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``LibUUID_FOUND``
+ True if LibUUID was found, false otherwise.
+``LibUUID_INCLUDE_DIRS``
+ Include directories needed to include LibUUID headers.
+``LibUUID_LIBRARIES``
+ Libraries needed to link to LibUUID.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+This module uses the following cache variables:
+
+``LibUUID_LIBRARY``
+ The location of the LibUUID library file.
+``LibUUID_INCLUDE_DIR``
+ The location of the LibUUID include directory containing ``uuid/uuid.h``.
+
+The cache variables should not be used by project code.
+They may be set by end users to point at LibUUID components.
+#]=======================================================================]
+
+#-----------------------------------------------------------------------------
+if(CYGWIN)
+ # Note: on current version of Cygwin, linking to libuuid.dll.a doesn't
+ # import the right symbols sometimes. Fix this by linking directly
+ # to the DLL that provides the symbols, instead.
+ set(old_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
+ find_library(LibUUID_LIBRARY
+ NAMES cyguuid-1.dll
+ )
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${old_suffixes})
+else()
+ find_library(LibUUID_LIBRARY
+ NAMES uuid
+ )
+endif()
+mark_as_advanced(LibUUID_LIBRARY)
+
+find_path(LibUUID_INCLUDE_DIR
+ NAMES uuid/uuid.h
+ )
+mark_as_advanced(LibUUID_INCLUDE_DIR)
+
+#-----------------------------------------------------------------------------
+include(${CMAKE_CURRENT_LIST_DIR}/../../Modules/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibUUID
+ FOUND_VAR LibUUID_FOUND
+ REQUIRED_VARS LibUUID_LIBRARY LibUUID_INCLUDE_DIR
+ )
+set(LIBUUID_FOUND ${LibUUID_FOUND})
+
+#-----------------------------------------------------------------------------
+# Provide documented result variables and targets.
+if(LibUUID_FOUND)
+ set(LibUUID_INCLUDE_DIRS ${LibUUID_INCLUDE_DIR})
+ set(LibUUID_LIBRARIES ${LibUUID_LIBRARY})
+ if(NOT TARGET LibUUID::LibUUID)
+ add_library(LibUUID::LibUUID UNKNOWN IMPORTED)
+ set_target_properties(LibUUID::LibUUID PROPERTIES
+ IMPORTED_LOCATION "${LibUUID_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${LibUUID_INCLUDE_DIRS}"
+ )
+ endif()
+endif()