فهرست منبع

Merge topic 'CPack-FixDESTDIR-Issue7000'

3178767 Merge 'CPack-FixDESTDIR-Issue7000' from github.com:TheErk/CMake
6a521f8 CPack   Enable better handling of absolute installed files
40dc97d CPack   Backward-compatibly enforce DESTDIR for DEB and RPM
Brad King 15 سال پیش
والد
کامیت
f95074ba70

+ 39 - 8
Modules/CPackRPM.cmake

@@ -83,13 +83,12 @@
 #     May be used to set RPM packages that are obsoleted by this one.
 #  CPACK_RPM_PACKAGE_RELOCATABLE
 #     Mandatory : NO
-#     Default   : -
+#     Default   : CPACK_PACKAGE_RELOCATABLE
 #     If this variable is set to TRUE or ON CPackRPM will try
 #     to build a relocatable RPM package. A relocatable RPM may
 #     be installed using rpm --prefix or --relocate in order to
 #     install it at an alternate place see rpm(8).
-#     Note that currently this may fail if the package contains
-#     files installed with absolute path or CPACK_SET_DESTDIR is set to ON.
+#     Note that currently this may fail if CPACK_SET_DESTDIR is set to ON.
 #     If CPACK_SET_DESTDIR is set then you will get a warning message
 #     but if there is file installed with absolute path you'll get
 #     unexpected behavior.
@@ -331,15 +330,18 @@ ELSE(CPACK_RPM_COMPRESSION_TYPE)
    SET(CPACK_RPM_COMPRESSION_TYPE_TMP "")
 ENDIF(CPACK_RPM_COMPRESSION_TYPE)
 
+if(CPACK_PACKAGE_RELOCATABLE)
+    set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE)
+endif(CPACK_PACKAGE_RELOCATABLE)
 if(CPACK_RPM_PACKAGE_RELOCATABLE)
   if(CPACK_RPM_PACKAGE_DEBUG)
-      message("CPackRPM:Debug: Trying to build a relocatable package")
+    message("CPackRPM:Debug: Trying to build a relocatable package")
   endif(CPACK_RPM_PACKAGE_DEBUG)
-  if(CPACK_SET_DESTDIR)
-    message(SEND_ERROR "CPackRPM:Warning: CPACK_SET_DESTDIR is set while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.")
-  else(CPACK_SET_DESTDIR)
+  if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
+    message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.")
+  else(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
     set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX})
-  endif(CPACK_SET_DESTDIR)
+  endif(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON"))
 endif(CPACK_RPM_PACKAGE_RELOCATABLE)
 
 # check if additional fields for RPM spec header are given
@@ -463,6 +465,34 @@ EXECUTE_PROCESS(COMMAND find -type f -o -type l
                WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}"
                OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES)
 
+if (CPACK_ABSOLUTE_DESTINATION_FILES)
+  IF(CPACK_RPM_PACKAGE_DEBUG)
+    message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES}")
+  ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+  # Remove trailing space
+  string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST)
+  # Transform endline separated - string into CMake List
+  string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}")
+  # Remove unecessary quotes
+  string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}")
+  # Remove ABSOLUTE install file from INSTALL FILE LIST
+  list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES})
+  # Rebuild INSTALL_FILES
+  set(CPACK_RPM_INSTALL_FILES "")
+  foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST)
+    set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n")
+  endforeach(F)
+  # Build ABSOLUTE_INSTALL_FILES
+  set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "")
+  foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES)
+    set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${CPACK_RPM_ABSOLUTE_INSTALL_FILES}%config \"${F}\"\n")
+  endforeach(F)
+  IF(CPACK_RPM_PACKAGE_DEBUG)
+    message("CPackRPM:Debug: CPACK_RPM_ABSOLUTE_INSTALL_FILES=${CPACK_RPM_ABSOLUTE_INSTALL_FILES}")
+    message("CPackRPM:Debug: CPACK_RPM_INSTALL_FILES=${CPACK_RPM_INSTALL_FILES}")
+  ENDIF(CPACK_RPM_PACKAGE_DEBUG)
+endif(CPACK_ABSOLUTE_DESTINATION_FILES)
+
 # The name of the final spec file to be used by rpmbuild
 SET(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}.spec")
 
@@ -547,6 +577,7 @@ fi
 %files
 %defattr(-,root,root,-)
 ${CPACK_RPM_INSTALL_FILES}
+${CPACK_RPM_ABSOLUTE_INSTALL_FILES}
 
 %changelog
 \@CPACK_RPM_SPEC_CHANGELOG\@

+ 4 - 1
Source/CPack/cmCPackDebGenerator.cxx

@@ -43,7 +43,10 @@ cmCPackDebGenerator::~cmCPackDebGenerator()
 int cmCPackDebGenerator::InitializeInternal()
 {
   this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
-
+  if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR")))
+    {
+    this->SetOption("CPACK_SET_DESTDIR", "I_ON");
+    }
   return this->Superclass::InitializeInternal();
 }
 

+ 25 - 2
Source/CPack/cmCPackGenerator.cxx

@@ -171,7 +171,8 @@ int cmCPackGenerator::InstallProject()
   std::string bareTempInstallDirectory
     = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY");
   std::string tempInstallDirectoryStr = bareTempInstallDirectory;
-  bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR"));
+  bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR"))
+                  | cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"));
   if (!setDestDir)
     {
     tempInstallDirectoryStr += this->GetPackagingInstallPrefix();
@@ -414,7 +415,8 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
         // underneath the tempInstallDirectory. The value of the project's
         // CMAKE_INSTALL_PREFIX is sent in here as the value of the
         // CPACK_INSTALL_PREFIX variable.
-       std::string dir;
+
+        std::string dir;
         if (this->GetOption("CPACK_INSTALL_PREFIX"))
           {
           dir += this->GetOption("CPACK_INSTALL_PREFIX");
@@ -459,6 +461,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
     = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS");
   const char* cmakeGenerator
     = this->GetOption("CPACK_CMAKE_GENERATOR");
+  std::string absoluteDestFiles;
   if ( cmakeProjects && *cmakeProjects )
     {
     if ( !cmakeGenerator )
@@ -643,6 +646,16 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
           // value of the project's CMAKE_INSTALL_PREFIX is sent in here as
           // the value of the CPACK_INSTALL_PREFIX variable.
           //
+          // If DESTDIR has been 'internally set ON' this means that
+          // the underlying CPack specific generator did ask for that
+          // In this case we may overrode CPACK_INSTALL_PREFIX with
+          // CPACK_PACKAGING_INSTALL_PREFIX
+          // I know this is tricky and awkward but it's the price for
+          // CPACK_SET_DESTDIR backward compatibility.
+          if (cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR")))
+            {
+            this->SetOption("CPACK_INSTALL_PREFIX",this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX"));
+            }
           std::string dir;
           if (this->GetOption("CPACK_INSTALL_PREFIX"))
             {
@@ -723,6 +736,15 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
           mf->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1");
           }
         int res = mf->ReadListFile(0, installFile.c_str());
+        if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) {
+          if (absoluteDestFiles.length()>0) {
+            absoluteDestFiles +=";";
+          }
+          absoluteDestFiles += mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES");
+          cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                                    "Got some ABSOLUTE DESTINATION FILES: "
+                                    << absoluteDestFiles << std::endl);
+        }
         if ( cmSystemTools::GetErrorOccuredFlag() || !res )
           {
           return 0;
@@ -730,6 +752,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
         }
       }
     }
+  this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",absoluteDestFiles.c_str());
   return 1;
 }
 

+ 5 - 1
Source/CPack/cmCPackRPMGenerator.cxx

@@ -11,6 +11,7 @@
 ============================================================================*/
 #include "cmCPackRPMGenerator.h"
 #include "cmCPackLog.h"
+#include "cmSystemTools.h"
 
 //----------------------------------------------------------------------
 cmCPackRPMGenerator::cmCPackRPMGenerator()
@@ -26,7 +27,10 @@ cmCPackRPMGenerator::~cmCPackRPMGenerator()
 int cmCPackRPMGenerator::InitializeInternal()
 {
   this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
-
+  if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR")))
+    {
+    this->SetOption("CPACK_SET_DESTDIR", "I_ON");
+    }
   return this->Superclass::InitializeInternal();
 }
 

+ 20 - 0
Source/cmInstallGenerator.cxx

@@ -60,6 +60,26 @@ void cmInstallGenerator
     }
   os << indent;
   std::string dest = this->GetInstallDestination();
+  if (cmSystemTools::FileIsFullPath(dest.c_str()))
+     {
+     os << "list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES\n";
+     os << indent << " \"";
+     for(std::vector<std::string>::const_iterator fi = files.begin();
+               fi != files.end(); ++fi)
+             {
+               if (fi!=files.begin()) os << ";";
+               os << dest << cmSystemTools::ConvertToOutputPath("/");
+               if (rename && *rename)
+                 {
+                 os << rename;
+                 }
+               else
+                 {
+                 os << cmSystemTools::GetFilenameName(*fi);
+                 }
+             }
+     os << "\")\n";
+     }
   os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str();
   if(optional)
     {

+ 16 - 1
Source/cmSystemTools.cxx

@@ -283,7 +283,22 @@ void cmSystemTools::ReportLastSystemError(const char* msg)
   cmSystemTools::Error(m.c_str());
 }
 
- 
+bool cmSystemTools::IsInternallyOn(const char* val)
+{
+  if (!val)
+    {
+    return false;
+    }
+  std::basic_string<char> v = val;
+
+  for(std::basic_string<char>::iterator c = v.begin();
+      c != v.end(); c++)
+    {
+    *c = static_cast<char>(toupper(*c));
+    }
+  return (v == "I_ON" || v == "i_on");
+}
+
 bool cmSystemTools::IsOn(const char* val)
 {
   if (!val)

+ 6 - 0
Source/cmSystemTools.h

@@ -103,6 +103,12 @@ public:
       cmSystemTools::s_ErrorOccured = false;
     }
   
+  /**
+   * Does a string indicates that CMake/CPack/CTest internally
+   * forced this value. This is not the same as On, but this
+   * may be considered as "internally switched on".
+   */
+  static bool IsInternallyOn(const char* val);
   /** 
    * does a string indicate a true or on value ? This is not the same
    * as ifdef.