1 From dd089e08b578f20b7dc7d2ce658e3df05e346e35 Mon Sep 17 00:00:00 2001
2 From: Brad King <brad.king@kitware.com>
3 Date: Mon, 15 Dec 2014 09:52:48 -0500
4 Subject: [PATCH] install: Allow absolute EXPORT destination with relative
7 When install(EXPORT) is given an absolute destination we cannot compute
8 the install prefix relative to the installed export file location.
9 Previously we disallowed installation of targets in such exports with a
10 relative destination, but did not enforce this for target property
11 values besides the location of the main target file. This could lead to
12 broken installations when the EXPORT is installed to an absolute path
13 but usage requirements are specified relative to the install prefix.
15 Since an EXPORT installed to an absolute destination cannot be relocated
16 we can just hard-code the value of CMAKE_INSTALL_PREFIX as the base for
17 relative paths. This will allow absolute install(EXPORT) destinations
18 to work with relative destinations for targets and usage requirements.
20 Extend the ExportImport test with a case covering this behavior.
22 .../release/dev/install-EXPORT-absolute-prefix.rst | 9 ++++
23 Source/cmExportInstallFileGenerator.cxx | 57 +++++++-------------
24 Source/cmExportInstallFileGenerator.h | 4 --
25 Tests/ExportImport/Export/CMakeLists.txt | 15 ++++++
26 .../Export/include/abs/1a/testLibAbs1a.h | 1 +
27 .../Export/include/abs/1b/testLibAbs1b.h | 1 +
28 .../ExportImport/Export/include/abs/testLibAbs1.h | 1 +
29 Tests/ExportImport/Export/testLibAbs1.c | 1 +
30 Tests/ExportImport/Import/A/CMakeLists.txt | 10 ++++
31 Tests/ExportImport/Import/A/imp_testExeAbs1.c | 15 ++++++
32 10 files changed, 73 insertions(+), 41 deletions(-)
33 create mode 100644 Help/release/dev/install-EXPORT-absolute-prefix.rst
34 create mode 100644 Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h
35 create mode 100644 Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h
36 create mode 100644 Tests/ExportImport/Export/include/abs/testLibAbs1.h
37 create mode 100644 Tests/ExportImport/Export/testLibAbs1.c
38 create mode 100644 Tests/ExportImport/Import/A/imp_testExeAbs1.c
40 diff --git a/Help/release/dev/install-EXPORT-absolute-prefix.rst b/Help/release/dev/install-EXPORT-absolute-prefix.rst
42 index 0000000..1b2a01c
44 +++ b/Help/release/dev/install-EXPORT-absolute-prefix.rst
46 +install-EXPORT-absolute-prefix
47 +------------------------------
49 +* The :command:`install(EXPORT)` command now works with an absolute
50 + ``DESTINATION`` even if targets in the export set are installed
51 + with a destination or usage requirements specified relative to the
52 + install prefix. The value of the :variable:`CMAKE_INSTALL_PREFIX`
53 + variable is hard-coded into the installed export file as the base
54 + for relative references.
55 diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
56 index 23180f1..3f5866a 100644
57 --- a/Source/cmExportInstallFileGenerator.cxx
58 +++ b/Source/cmExportInstallFileGenerator.cxx
59 @@ -69,13 +69,24 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
60 this->GenerateExpectedTargetsCode(os, expectedTargets);
63 - // Add code to compute the installation prefix relative to the
64 - // import file location.
65 + // Set an _IMPORT_PREFIX variable for import location properties
66 + // to reference if they are relative to the install prefix.
67 + std::string installPrefix =
68 + this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
69 const char* installDest = this->IEGen->GetDestination();
70 - if(!cmSystemTools::FileIsFullPath(installDest))
71 + if(cmSystemTools::FileIsFullPath(installDest))
73 - std::string installPrefix =
74 - this->IEGen->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
75 + // The export file is being installed to an absolute path so the
76 + // package is not relocatable. Use the configured install prefix.
78 + "# The installation prefix configured by this project.\n"
79 + "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n"
84 + // Add code to compute the installation prefix relative to the
85 + // import file location.
86 std::string absDest = installPrefix + "/" + installDest;
87 std::string absDestS = absDest + "/";
88 os << "# Compute the installation prefix relative to this file.\n"
89 @@ -106,9 +117,6 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
90 dest = cmSystemTools::GetFilenamePath(dest);
94 - // Import location properties may reference this variable.
95 - this->ImportPrefix = "${_IMPORT_PREFIX}/";
98 std::vector<std::string> missingTargets;
99 @@ -209,12 +217,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
102 // Cleanup the import prefix variable.
103 - if(!this->ImportPrefix.empty())
105 - os << "# Cleanup temporary variables.\n"
106 - << "set(_IMPORT_PREFIX)\n"
109 + os << "# Cleanup temporary variables.\n"
110 + << "set(_IMPORT_PREFIX)\n"
112 this->GenerateImportedFileCheckLoop(os);
115 @@ -394,11 +399,7 @@ cmExportInstallFileGenerator
116 if(!cmSystemTools::FileIsFullPath(dest.c_str()))
118 // The target is installed relative to the installation prefix.
119 - if(this->ImportPrefix.empty())
121 - this->ComplainAboutImportPrefix(itgen);
123 - value = this->ImportPrefix;
124 + value = "${_IMPORT_PREFIX}/";
128 @@ -508,24 +509,6 @@ cmExportInstallFileGenerator
133 -//----------------------------------------------------------------------------
135 -cmExportInstallFileGenerator
136 -::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
138 - const char* installDest = this->IEGen->GetDestination();
140 - e << "install(EXPORT \""
141 - << this->IEGen->GetExportSet()->GetName()
142 - << "\") given absolute "
143 - << "DESTINATION \"" << installDest << "\" but the export "
144 - << "references an installation of target \""
145 - << itgen->GetTarget()->GetName() << "\" which has relative "
146 - << "DESTINATION \"" << itgen->GetDestination() << "\".";
147 - cmSystemTools::Error(e.str().c_str());
150 //----------------------------------------------------------------------------
152 cmExportInstallFileGenerator
153 diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
154 index b851ad5..6f86ac9 100644
155 --- a/Source/cmExportInstallFileGenerator.h
156 +++ b/Source/cmExportInstallFileGenerator.h
157 @@ -83,14 +83,10 @@ protected:
158 std::set<std::string>& importedLocations
161 - void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen);
163 std::string InstallNameDir(cmTarget* target, const std::string& config);
165 cmInstallExportGenerator* IEGen;
167 - std::string ImportPrefix;
169 // The import file generated for each configuration.
170 std::map<std::string, std::string> ConfigImportFiles;
172 diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
173 index febdfe6..e130eca 100644
174 --- a/Tests/ExportImport/Export/CMakeLists.txt
175 +++ b/Tests/ExportImport/Export/CMakeLists.txt
176 @@ -508,3 +508,18 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
179 add_subdirectory(Interface)
181 +#-----------------------------------------------------------------------------
182 +# Install export with absolute destination but relative pieces.
183 +add_library(testLibAbs1 STATIC testLibAbs1.c)
184 +target_include_directories(testLibAbs1 INTERFACE
185 + "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/abs/1a;include/abs/1b>"
188 + TARGETS testLibAbs1
190 + ARCHIVE DESTINATION lib
191 + INCLUDES DESTINATION include/abs
193 +install(DIRECTORY include/abs DESTINATION include)
194 +install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)
195 diff --git a/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h
197 index 0000000..4421227
199 +++ b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h
201 +#define testLibAbs1a
202 diff --git a/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h
204 index 0000000..00a2a29
206 +++ b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h
208 +#define testLibAbs1b
209 diff --git a/Tests/ExportImport/Export/include/abs/testLibAbs1.h b/Tests/ExportImport/Export/include/abs/testLibAbs1.h
211 index 0000000..19d80a5
213 +++ b/Tests/ExportImport/Export/include/abs/testLibAbs1.h
215 +extern int testLibAbs1(void);
216 diff --git a/Tests/ExportImport/Export/testLibAbs1.c b/Tests/ExportImport/Export/testLibAbs1.c
218 index 0000000..34aec75
220 +++ b/Tests/ExportImport/Export/testLibAbs1.c
222 +int testLibAbs1(void) { return 0; }
223 diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
224 index eb0bbf8..9450c82 100644
225 --- a/Tests/ExportImport/Import/A/CMakeLists.txt
226 +++ b/Tests/ExportImport/Import/A/CMakeLists.txt
227 @@ -96,6 +96,16 @@ foreach(c DEBUG RELWITHDEBINFO)
230 #-----------------------------------------------------------------------------
231 +include(${CMAKE_INSTALL_PREFIX}/lib/expAbs/expAbs.cmake)
233 +add_executable(imp_testExeAbs1
236 +target_link_libraries(imp_testExeAbs1
240 +#-----------------------------------------------------------------------------
241 # Create a custom target to generate a header for the libraries below.
242 # Drive the header generation through an indirect chain of imported
243 # target dependencies.
244 diff --git a/Tests/ExportImport/Import/A/imp_testExeAbs1.c b/Tests/ExportImport/Import/A/imp_testExeAbs1.c
246 index 0000000..069c3f0
248 +++ b/Tests/ExportImport/Import/A/imp_testExeAbs1.c
250 +#include "testLibAbs1.h"
251 +#include "testLibAbs1a.h"
252 +#include "testLibAbs1b.h"
253 +#ifndef testLibAbs1a
254 +# error "testLibAbs1a not defined"
256 +#ifndef testLibAbs1b
257 +# error "testLibAbs1b not defined"