Merge topic 'install-EXPORT-absolute-prefix'

dd089e08 install: Allow absolute EXPORT destination with relative targets (#15258)
This commit is contained in:
Brad King 2014-12-19 08:26:55 -05:00 committed by CMake Topic Stage
commit 1ac8523c3b
10 changed files with 73 additions and 41 deletions

View File

@ -0,0 +1,9 @@
install-EXPORT-absolute-prefix
------------------------------
* The :command:`install(EXPORT)` command now works with an absolute
``DESTINATION`` even if targets in the export set are installed
with a destination or usage requirements specified relative to the
install prefix. The value of the :variable:`CMAKE_INSTALL_PREFIX`
variable is hard-coded into the installed export file as the base
for relative references.

View File

@ -69,13 +69,24 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
// Add code to compute the installation prefix relative to the
// import file location.
// Set an _IMPORT_PREFIX variable for import location properties
// to reference if they are relative to the install prefix.
std::string installPrefix =
this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
const char* installDest = this->IEGen->GetDestination();
if(!cmSystemTools::FileIsFullPath(installDest))
if(cmSystemTools::FileIsFullPath(installDest))
{
std::string installPrefix =
this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
// The export file is being installed to an absolute path so the
// package is not relocatable. Use the configured install prefix.
os <<
"# The installation prefix configured by this project.\n"
"set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
"\n";
}
else
{
// Add code to compute the installation prefix relative to the
// import file location.
std::string absDest = installPrefix + "/" + installDest;
std::string absDestS = absDest + "/";
os << "# Compute the installation prefix relative to this file.\n"
@ -106,9 +117,6 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
dest = cmSystemTools::GetFilenamePath(dest);
}
os << "\n";
// Import location properties may reference this variable.
this->ImportPrefix = "${_IMPORT_PREFIX}/";
}
std::vector<std::string> missingTargets;
@ -209,12 +217,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
<< "\n";
// Cleanup the import prefix variable.
if(!this->ImportPrefix.empty())
{
os << "# Cleanup temporary variables.\n"
<< "set(_IMPORT_PREFIX)\n"
<< "\n";
}
os << "# Cleanup temporary variables.\n"
<< "set(_IMPORT_PREFIX)\n"
<< "\n";
this->GenerateImportedFileCheckLoop(os);
bool result = true;
@ -394,11 +399,7 @@ cmExportInstallFileGenerator
if(!cmSystemTools::FileIsFullPath(dest.c_str()))
{
// The target is installed relative to the installation prefix.
if(this->ImportPrefix.empty())
{
this->ComplainAboutImportPrefix(itgen);
}
value = this->ImportPrefix;
value = "${_IMPORT_PREFIX}/";
}
value += dest;
value += "/";
@ -508,24 +509,6 @@ cmExportInstallFileGenerator
return namespaces;
}
//----------------------------------------------------------------------------
void
cmExportInstallFileGenerator
::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
{
const char* installDest = this->IEGen->GetDestination();
cmOStringStream e;
e << "install(EXPORT \""
<< this->IEGen->GetExportSet()->GetName()
<< "\") given absolute "
<< "DESTINATION \"" << installDest << "\" but the export "
<< "references an installation of target \""
<< itgen->GetTarget()->GetName() << "\" which has relative "
<< "DESTINATION \"" << itgen->GetDestination() << "\".";
cmSystemTools::Error(e.str().c_str());
}
//----------------------------------------------------------------------------
void
cmExportInstallFileGenerator

View File

@ -83,14 +83,10 @@ protected:
std::set<std::string>& importedLocations
);
void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
std::string InstallNameDir(cmTarget* target, const std::string& config);
cmInstallExportGenerator* IEGen;
std::string ImportPrefix;
// The import file generated for each configuration.
std::map<std::string, std::string> ConfigImportFiles;
};

View File

@ -508,3 +508,18 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
)
add_subdirectory(Interface)
#-----------------------------------------------------------------------------
# Install export with absolute destination but relative pieces.
add_library(testLibAbs1 STATIC testLibAbs1.c)
target_include_directories(testLibAbs1 INTERFACE
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/abs/1a;include/abs/1b>"
)
install(
TARGETS testLibAbs1
EXPORT expAbs
ARCHIVE DESTINATION lib
INCLUDES DESTINATION include/abs
)
install(DIRECTORY include/abs DESTINATION include)
install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)

View File

@ -0,0 +1 @@
#define testLibAbs1a

View File

@ -0,0 +1 @@
#define testLibAbs1b

View File

@ -0,0 +1 @@
extern int testLibAbs1(void);

View File

@ -0,0 +1 @@
int testLibAbs1(void) { return 0; }

View File

@ -95,6 +95,16 @@ foreach(c DEBUG RELWITHDEBINFO)
set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
endforeach()
#-----------------------------------------------------------------------------
include(${CMAKE_INSTALL_PREFIX}/lib/expAbs/expAbs.cmake)
add_executable(imp_testExeAbs1
imp_testExeAbs1.c
)
target_link_libraries(imp_testExeAbs1
expAbs_testLibAbs1
)
#-----------------------------------------------------------------------------
# Create a custom target to generate a header for the libraries below.
# Drive the header generation through an indirect chain of imported

View File

@ -0,0 +1,15 @@
#include "testLibAbs1.h"
#include "testLibAbs1a.h"
#include "testLibAbs1b.h"
#ifndef testLibAbs1a
# error "testLibAbs1a not defined"
#endif
#ifndef testLibAbs1b
# error "testLibAbs1b not defined"
#endif
int main()
{
return 0
+ testLibAbs1()
;
}