Prechádzať zdrojové kódy

CPackDeb: Enable the DEB generator on Windows

While some features require external Unix tools the
generator is mostly portable.

By enabling it on Windows it can be used for cross platform
packaging.
Nils Gladitz 8 rokov pred
rodič
commit
5299141320

+ 7 - 0
Help/release/dev/deb-on-windows.rst

@@ -0,0 +1,7 @@
+deb-on-windows
+--------------
+
+* The CPack ``DEB`` generator, configured by the :module:`CPackDeb` module,
+  was enabled on Windows.  While not fully featured (due to the lack of
+  external UNIX tools) this will allow building basic cross-platform Debian
+  packages.

+ 10 - 4
Modules/CPackDeb.cmake

@@ -497,6 +497,16 @@
 #
 #
 #    This value is not interpreted. It is possible to pass an optional
 #    This value is not interpreted. It is possible to pass an optional
 #    revision number of the referenced source package as well.
 #    revision number of the referenced source package as well.
+#
+# Building Debian packages on Windows
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+#
+# To communicate UNIX file permissions from the install stage
+# to the CPack DEB generator the "cmake_mode_t" NTFS
+# alternate data stream (ADT) is used.
+#
+# When a filesystem without ADT support is used only owner read/write
+# permissions can be preserved.
 
 
 # CPack script for creating Debian package
 # CPack script for creating Debian package
 # Author: Mathieu Malaterre
 # Author: Mathieu Malaterre
@@ -507,10 +517,6 @@ if(CMAKE_BINARY_DIR)
   message(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.")
   message(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.")
 endif()
 endif()
 
 
-if(NOT UNIX)
-  message(FATAL_ERROR "CPackDeb.cmake may only be used under UNIX.")
-endif()
-
 function(cpack_deb_variable_fallback OUTPUT_VAR_NAME)
 function(cpack_deb_variable_fallback OUTPUT_VAR_NAME)
   set(FALLBACK_VAR_NAMES ${ARGN})
   set(FALLBACK_VAR_NAMES ${ARGN})
 
 

+ 1 - 1
Source/CMakeLists.txt

@@ -874,6 +874,7 @@ set(CPACK_SRCS
   CPack/cmCPackTarCompressGenerator.cxx
   CPack/cmCPackTarCompressGenerator.cxx
   CPack/cmCPackZIPGenerator.cxx
   CPack/cmCPackZIPGenerator.cxx
   CPack/cmCPack7zGenerator.cxx
   CPack/cmCPack7zGenerator.cxx
+  CPack/cmCPackDebGenerator.cxx
   )
   )
 # CPack IFW generator
 # CPack IFW generator
 set(CPACK_SRCS ${CPACK_SRCS}
 set(CPACK_SRCS ${CPACK_SRCS}
@@ -900,7 +901,6 @@ option(CPACK_ENABLE_FREEBSD_PKG "Add FreeBSD pkg(8) generator to CPack." OFF)
 
 
 if(UNIX)
 if(UNIX)
   set(CPACK_SRCS ${CPACK_SRCS}
   set(CPACK_SRCS ${CPACK_SRCS}
-    CPack/cmCPackDebGenerator.cxx
     CPack/cmCPackRPMGenerator.cxx
     CPack/cmCPackRPMGenerator.cxx
     )
     )
 
 

+ 23 - 5
Source/CPack/cmCPackDebGenerator.cxx

@@ -479,6 +479,25 @@ int cmCPackDebGenerator::createDeb()
       cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \""
       cmCPackLogger(cmCPackLog::LOG_DEBUG, "RELATIVEDIR: \""
                       << relativeDir << "\"" << std::endl);
                       << relativeDir << "\"" << std::endl);
 
 
+#ifdef WIN32
+      std::string mode_t_adt_filename = *fileIt + ":cmake_mode_t";
+      cmsys::ifstream permissionStream(mode_t_adt_filename.c_str());
+
+      mode_t permissions = 0;
+
+      if (permissionStream) {
+        permissionStream >> std::oct >> permissions;
+      }
+
+      if (permissions != 0) {
+        data_tar.SetPermissions(permissions);
+      } else if (cmSystemTools::FileIsDirectory(*fileIt)) {
+        data_tar.SetPermissions(0755);
+      } else {
+        data_tar.ClearPermissions();
+      }
+#endif
+
       // do not recurse because the loop will do it
       // do not recurse because the loop will do it
       if (!data_tar.Add(*fileIt, topLevelLength, ".", false)) {
       if (!data_tar.Add(*fileIt, topLevelLength, ".", false)) {
         cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem adding file to tar:"
         cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem adding file to tar:"
@@ -553,8 +572,8 @@ int cmCPackDebGenerator::createDeb()
     and
     and
     https://lintian.debian.org/tags/control-file-has-bad-permissions.html
     https://lintian.debian.org/tags/control-file-has-bad-permissions.html
     */
     */
-    const mode_t permission644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
-    const mode_t permissionExecute = S_IXUSR | S_IXGRP | S_IXOTH;
+    const mode_t permission644 = 0644;
+    const mode_t permissionExecute = 0111;
     const mode_t permission755 = permission644 | permissionExecute;
     const mode_t permission755 = permission644 | permissionExecute;
 
 
     // for md5sum and control (that we have generated here), we use 644
     // for md5sum and control (that we have generated here), we use 644
@@ -831,7 +850,7 @@ static int copy_ar(CF* cfp, off_t size)
                        ? static_cast<size_t>(sz)
                        ? static_cast<size_t>(sz)
                        : sizeof(buf),
                        : sizeof(buf),
                      from)) > 0) {
                      from)) > 0) {
-    sz -= nr;
+    sz -= static_cast<off_t>(nr);
     for (size_t off = 0; off < nr; nr -= off, off += nw) {
     for (size_t off = 0; off < nr; nr -= off, off += nw) {
       if ((nw = fwrite(buf + off, 1, nr, to)) < nr) {
       if ((nw = fwrite(buf + off, 1, nr, to)) < nr) {
         return -1;
         return -1;
@@ -854,7 +873,6 @@ static int copy_ar(CF* cfp, off_t size)
 static int put_arobj(CF* cfp, struct stat* sb)
 static int put_arobj(CF* cfp, struct stat* sb)
 {
 {
   int result = 0;
   int result = 0;
-  struct ar_hdr* hdr;
 
 
   /* If passed an sb structure, reading a file from disk.  Get stat(2)
   /* If passed an sb structure, reading a file from disk.  Get stat(2)
    * information, build a name and construct a header.  (Files are named
    * information, build a name and construct a header.  (Files are named
@@ -873,7 +891,7 @@ static int put_arobj(CF* cfp, struct stat* sb)
   if (gid > USHRT_MAX) {
   if (gid > USHRT_MAX) {
     gid = USHRT_MAX;
     gid = USHRT_MAX;
   }
   }
-  if (lname > sizeof(hdr->ar_name) || strchr(name, ' ')) {
+  if (lname > sizeof(ar_hdr().ar_name) || strchr(name, ' ')) {
     (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname, (long int)sb->st_mtime,
     (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname, (long int)sb->st_mtime,
                   (unsigned)uid, (unsigned)gid, (unsigned)sb->st_mode,
                   (unsigned)uid, (unsigned)gid, (unsigned)sb->st_mode,
                   (long long)sb->st_size + lname, ARFMAG);
                   (long long)sb->st_size + lname, ARFMAG);

+ 5 - 5
Source/CPack/cmCPackGeneratorFactory.cxx

@@ -12,6 +12,7 @@
 #ifdef HAVE_FREEBSD_PKG
 #ifdef HAVE_FREEBSD_PKG
 #include "cmCPackFreeBSDGenerator.h"
 #include "cmCPackFreeBSDGenerator.h"
 #endif
 #endif
+#include "cmCPackDebGenerator.h"
 #include "cmCPackGenerator.h"
 #include "cmCPackGenerator.h"
 #include "cmCPackLog.h"
 #include "cmCPackLog.h"
 #include "cmCPackNSISGenerator.h"
 #include "cmCPackNSISGenerator.h"
@@ -37,7 +38,6 @@
 
 
 #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) &&         \
 #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) &&         \
   !defined(__HAIKU__)
   !defined(__HAIKU__)
-#include "cmCPackDebGenerator.h"
 #include "cmCPackRPMGenerator.h"
 #include "cmCPackRPMGenerator.h"
 #endif
 #endif
 
 
@@ -102,6 +102,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
     this->RegisterGenerator("TZ", "Tar Compress compression",
     this->RegisterGenerator("TZ", "Tar Compress compression",
                             cmCPackTarCompressGenerator::CreateGenerator);
                             cmCPackTarCompressGenerator::CreateGenerator);
   }
   }
+  if (cmCPackDebGenerator::CanGenerate()) {
+    this->RegisterGenerator("DEB", "Debian packages",
+                            cmCPackDebGenerator::CreateGenerator);
+  }
 #ifdef __APPLE__
 #ifdef __APPLE__
   if (cmCPackDragNDropGenerator::CanGenerate()) {
   if (cmCPackDragNDropGenerator::CanGenerate()) {
     this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop",
     this->RegisterGenerator("DragNDrop", "Mac OSX Drag And Drop",
@@ -126,10 +130,6 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
 #endif
 #endif
 #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) &&         \
 #if !defined(_WIN32) && !defined(__QNXNTO__) && !defined(__BEOS__) &&         \
   !defined(__HAIKU__)
   !defined(__HAIKU__)
-  if (cmCPackDebGenerator::CanGenerate()) {
-    this->RegisterGenerator("DEB", "Debian packages",
-                            cmCPackDebGenerator::CreateGenerator);
-  }
   if (cmCPackRPMGenerator::CanGenerate()) {
   if (cmCPackRPMGenerator::CanGenerate()) {
     this->RegisterGenerator("RPM", "RPM packages",
     this->RegisterGenerator("RPM", "RPM packages",
                             cmCPackRPMGenerator::CreateGenerator);
                             cmCPackRPMGenerator::CreateGenerator);

+ 28 - 13
Source/cmFileCommand.cxx

@@ -55,14 +55,14 @@ class cmSystemToolsFileTime;
 static mode_t mode_owner_read = S_IREAD;
 static mode_t mode_owner_read = S_IREAD;
 static mode_t mode_owner_write = S_IWRITE;
 static mode_t mode_owner_write = S_IWRITE;
 static mode_t mode_owner_execute = S_IEXEC;
 static mode_t mode_owner_execute = S_IEXEC;
-static mode_t mode_group_read = 0;
-static mode_t mode_group_write = 0;
-static mode_t mode_group_execute = 0;
-static mode_t mode_world_read = 0;
-static mode_t mode_world_write = 0;
-static mode_t mode_world_execute = 0;
-static mode_t mode_setuid = 0;
-static mode_t mode_setgid = 0;
+static mode_t mode_group_read = 040;
+static mode_t mode_group_write = 020;
+static mode_t mode_group_execute = 010;
+static mode_t mode_world_read = 04;
+static mode_t mode_world_write = 02;
+static mode_t mode_world_execute = 01;
+static mode_t mode_setuid = 04000;
+static mode_t mode_setgid = 02000;
 #else
 #else
 static mode_t mode_owner_read = S_IRUSR;
 static mode_t mode_owner_read = S_IRUSR;
 static mode_t mode_owner_write = S_IWUSR;
 static mode_t mode_owner_write = S_IWUSR;
@@ -1076,11 +1076,26 @@ protected:
 
 
   bool SetPermissions(const char* toFile, mode_t permissions)
   bool SetPermissions(const char* toFile, mode_t permissions)
   {
   {
-    if (permissions && !cmSystemTools::SetPermissions(toFile, permissions)) {
-      std::ostringstream e;
-      e << this->Name << " cannot set permissions on \"" << toFile << "\"";
-      this->FileCommand->SetError(e.str());
-      return false;
+    if (permissions) {
+#ifdef WIN32
+      if (Makefile->IsOn("CMAKE_CROSSCOMPILING")) {
+        std::string mode_t_adt_filename =
+          std::string(toFile) + ":cmake_mode_t";
+
+        cmsys::ofstream permissionStream(mode_t_adt_filename.c_str());
+
+        if (permissionStream) {
+          permissionStream << std::oct << permissions << std::endl;
+        }
+      }
+#endif
+
+      if (!cmSystemTools::SetPermissions(toFile, permissions)) {
+        std::ostringstream e;
+        e << this->Name << " cannot set permissions on \"" << toFile << "\"";
+        this->FileCommand->SetError(e.str());
+        return false;
+      }
     }
     }
     return true;
     return true;
   }
   }

+ 13 - 0
Source/cmLocalGenerator.cxx

@@ -451,6 +451,19 @@ void cmLocalGenerator::GenerateInstallRules()
     /* clang-format on */
     /* clang-format on */
   }
   }
 
 
+  // Copy cmake cross compile state to install code.
+  if (const char* crosscompiling =
+        this->Makefile->GetDefinition("CMAKE_CROSSCOMPILING")) {
+    /* clang-format off */
+    fout <<
+      "# Is this installation the result of a crosscompile?\n"
+      "if(NOT DEFINED CMAKE_CROSSCOMPILING)\n"
+      "  set(CMAKE_CROSSCOMPILING \"" << crosscompiling << "\")\n"
+      "endif()\n"
+      "\n";
+    /* clang-format on */
+  }
+
   // Ask each install generator to write its code.
   // Ask each install generator to write its code.
   std::vector<cmInstallGenerator*> const& installers =
   std::vector<cmInstallGenerator*> const& installers =
     this->Makefile->GetInstallGenerators();
     this->Makefile->GetInstallGenerators();

+ 5 - 0
Source/cm_sys_stat.h

@@ -7,6 +7,11 @@
 typedef unsigned short mode_t;
 typedef unsigned short mode_t;
 #endif
 #endif
 
 
+#if defined(WIN32)
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+#endif
+
 #include <sys/types.h>
 #include <sys/types.h>
 // include sys/stat.h after sys/types.h
 // include sys/stat.h after sys/types.h
 #include <sys/stat.h>
 #include <sys/stat.h>