Browse Source

Merge topic 'cpack-wix-cygwin'

e1409101 cpack wix: support WiX generator on Cygwin
e258fe03 cpack wix: fix path error on cygwin

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1367
Brad King 8 years ago
parent
commit
9de7ae6e5e

+ 1 - 1
Modules/CPackWIX.cmake

@@ -289,7 +289,7 @@
 #
 
 if(NOT CPACK_WIX_ROOT)
-  file(TO_CMAKE_PATH "$ENV{WIX}" CPACK_WIX_ROOT)
+  string(REPLACE "\\" "/" CPACK_WIX_ROOT "$ENV{WIX}")
 endif()
 
 find_program(CPACK_WIX_CANDLE_EXECUTABLE candle

+ 12 - 2
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})

+ 39 - 0
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

+ 12 - 0
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

+ 31 - 10
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);
 }

+ 8 - 1
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);

+ 3 - 1
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;

+ 2 - 2
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);

+ 85 - 0
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()