Explorar el Código

install(EXPORT): Force absolute paths for usr-move

If the absolute install(EXPORT) destination for the CMAKE_INSTALL_PREFIX
used during configuration is under (/usr)?/lib(64)? then assume the
current build is for a system package installation instead of a
relocatable distribution.  Generate an absolute path for _IMPORT_PREFIX
in the target exports file instead of generating code to compute the
value relative to the file location.  This is necessary for
distributions implementing a move to /usr such as:

 https://wiki.archlinux.org/index.php/DeveloperWiki:usrlib
 "All files in the /lib directory have been moved to /usr/lib and now
  /lib is a symlink to usr/lib."

The relative path computation is not reliable because the targets file
could be installed through cross-prefix a symlink and loaded without it
or vice versa.

A similar change was made for package configuration file generation by
commit d4774140 (configure_package_config_file: force absolute paths for
usr-move, 2013-01-24).
Brad King hace 12 años
padre
commit
0c727b906a
Se han modificado 2 ficheros con 29 adiciones y 9 borrados
  1. 27 9
      Source/cmExportInstallFileGenerator.cxx
  2. 2 0
      Source/cmInstallExportGenerator.h

+ 27 - 9
Source/cmExportInstallFileGenerator.cxx

@@ -74,17 +74,35 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
   const char* installDest = this->IEGen->GetDestination();
   if(!cmSystemTools::FileIsFullPath(installDest))
     {
-    std::string dest = installDest;
-    os << "# Compute the installation prefix relative to this file.\n"
-       << "get_filename_component(_IMPORT_PREFIX "
-       << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
-    while(!dest.empty())
+    std::string installPrefix =
+      this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+    std::string absDest = installPrefix + "/" + installDest + "/";
+    if(strncmp(absDest.c_str(), "/lib/", 5) == 0 ||
+       strncmp(absDest.c_str(), "/lib64/", 7) == 0 ||
+       strncmp(absDest.c_str(), "/usr/lib/", 9) == 0 ||
+       strncmp(absDest.c_str(), "/usr/lib64/", 11) == 0)
       {
-      os <<
-        "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
-      dest = cmSystemTools::GetFilenamePath(dest);
+      // Assume this is a build for system package installation rather than a
+      // relocatable distribution.  Use an absolute prefix because some Linux
+      // distros symlink /lib to /usr/lib which confuses the relative path
+      // computation below if we generate for /lib under one prefix and but the
+      // file is loaded from another.
+      os << "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n";
+      }
+    else
+      {
+      std::string dest = installDest;
+      os << "# Compute the installation prefix relative to this file.\n"
+         << "get_filename_component(_IMPORT_PREFIX "
+         << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
+      while(!dest.empty())
+        {
+        os <<
+         "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
+        dest = cmSystemTools::GetFilenamePath(dest);
+        }
+      os << "\n";
       }
-    os << "\n";
 
     // Import location properties may reference this variable.
     this->ImportPrefix = "${_IMPORT_PREFIX}/";

+ 2 - 0
Source/cmInstallExportGenerator.h

@@ -36,6 +36,8 @@ public:
 
   cmExportSet* GetExportSet() {return this->ExportSet;}
 
+  cmMakefile* GetMakefile() const { return this->Makefile; }
+
   const std::string& GetNamespace() const { return this->Namespace; }
 
 protected: