diff options
author | Stephen Sorley <ssorley@monetra.com> | 2017-10-09 11:39:29 -0400 |
---|---|---|
committer | Stephen Sorley <ssorley@monetra.com> | 2017-10-13 13:07:37 -0400 |
commit | e1409101c99f7a3487990e9927e8bd0e275f564f (patch) | |
tree | e5c0ecb010bc9bbfc11aeea8a2e65bbe9eafd14a | |
parent | e258fe03968d27871d6a57e3f4571bc8fbba6b9b (diff) | |
download | cmake-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.txt | 14 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCMakeToWixPath.cxx | 39 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCMakeToWixPath.h | 12 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.cxx | 41 | ||||
-rw-r--r-- | Source/CPack/WiX/cmCPackWIXGenerator.h | 9 | ||||
-rw-r--r-- | Source/CPack/WiX/cmWIXFilesSourceWriter.cxx | 4 | ||||
-rw-r--r-- | Source/CPack/cmCPackGeneratorFactory.cxx | 4 | ||||
-rw-r--r-- | Source/Modules/FindLibUUID.cmake | 85 |
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() |