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).
This commit is contained in:
Brad King 2013-03-08 09:23:44 -05:00
parent aa027af9af
commit 0c727b906a
2 changed files with 29 additions and 9 deletions

View File

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

View File

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