Browse Source

Merge topic 'usr-move-relocatable'

6c613b4 Handle usr-move without forcing absolute paths (#14041)
Brad King 12 years ago
parent
commit
9cccd2c29c
2 changed files with 45 additions and 44 deletions
  1. 19 21
      Modules/CMakePackageConfigHelpers.cmake
  2. 26 23
      Source/cmExportInstallFileGenerator.cxx

+ 19 - 21
Modules/CMakePackageConfigHelpers.cmake

@@ -9,8 +9,6 @@
 # configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
 # file for installing a project or library. It helps making the resulting package
 # relocatable by avoiding hardcoded paths in the installed Config.cmake file.
-# <Name>Config.cmake files installed under UNIX into /lib(64) or /usr/lib(64) are
-# considered system packages and are not relocatable.
 #
 # In a FooConfig.cmake file there may be code like this to make the
 # install destinations know to the using project:
@@ -176,32 +174,17 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
     set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
   endif()
 
-  # with the /usr-move, /lib(64) is a symlink to /usr/lib on Fedora, ArchLinux, Mageira and others.
-  # If we are installed to such a location, force using absolute paths.
-  set(forceAbsolutePaths FALSE)
-  if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
-    set(forceAbsolutePaths TRUE)
-  endif()
-
   file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
 
   foreach(var ${CCF_PATH_VARS})
     if(NOT DEFINED ${var})
       message(FATAL_ERROR "Variable ${var} does not exist")
     else()
-      if(forceAbsolutePaths)
-        if(IS_ABSOLUTE "${${var}}")
-          set(PACKAGE_${var} "${${var}}")
-        else()
-          set(PACKAGE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
-        endif()
+      if(IS_ABSOLUTE "${${var}}")
+        string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
+                        PACKAGE_${var} "${${var}}")
       else()
-        if(IS_ABSOLUTE "${${var}}")
-          string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
-                          PACKAGE_${var} "${${var}}")
-        else()
-          set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
-        endif()
+        set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
       endif()
     endif()
   endforeach()
@@ -216,6 +199,21 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
 get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE)
 ")
 
+  if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
+    # Handle "/usr move" symlinks created by some Linux distros.
+    set(PACKAGE_INIT "${PACKAGE_INIT}
+# Use original install prefix when loaded through a \"/usr move\"
+# cross-prefix symbolic link such as /lib -> /usr/lib.
+get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH)
+get_filename_component(_realOrig \"${absInstallDir}\" REALPATH)
+if(_realCurr STREQUAL _realOrig)
+  set(PACKAGE_PREFIX_DIR \"${CMAKE_INSTALL_PREFIX}\")
+endif()
+unset(_realOrig)
+unset(_realCurr)
+")
+  endif()
+
   if(NOT CCF_NO_SET_AND_CHECK_MACRO)
     set(PACKAGE_INIT "${PACKAGE_INIT}
 macro(set_and_check _var _file)

+ 26 - 23
Source/cmExportInstallFileGenerator.cxx

@@ -76,33 +76,36 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
     {
     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)
+    std::string absDest = installPrefix + "/" + installDest;
+    std::string absDestS = absDest + "/";
+    os << "# Compute the installation prefix relative to this file.\n"
+       << "get_filename_component(_IMPORT_PREFIX"
+       << " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
+    if(strncmp(absDestS.c_str(), "/lib/", 5) == 0 ||
+       strncmp(absDestS.c_str(), "/lib64/", 7) == 0 ||
+       strncmp(absDestS.c_str(), "/usr/lib/", 9) == 0 ||
+       strncmp(absDestS.c_str(), "/usr/lib64/", 11) == 0)
       {
-      // 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";
+      // Handle "/usr move" symlinks created by some Linux distros.
+      os <<
+        "# Use original install prefix when loaded through a\n"
+        "# cross-prefix symbolic link such as /lib -> /usr/lib.\n"
+        "get_filename_component(_realCurr \"${_IMPORT_PREFIX}\" REALPATH)\n"
+        "get_filename_component(_realOrig \"" << absDest << "\" REALPATH)\n"
+        "if(_realCurr STREQUAL _realOrig)\n"
+        "  set(_IMPORT_PREFIX \"" << absDest << "\")\n"
+        "endif()\n"
+        "unset(_realOrig)\n"
+        "unset(_realCurr)\n";
       }
-    else
+    std::string dest = installDest;
+    while(!dest.empty())
       {
-      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 <<
+        "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
+      dest = cmSystemTools::GetFilenamePath(dest);
       }
+    os << "\n";
 
     // Import location properties may reference this variable.
     this->ImportPrefix = "${_IMPORT_PREFIX}/";