]>
Commit | Line | Data |
---|---|---|
aed8617e AM |
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 | |
5 | targets (#15258) | |
6 | ||
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. | |
14 | ||
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. | |
19 | ||
20 | Extend the ExportImport test with a case covering this behavior. | |
21 | --- | |
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 | |
39 | ||
40 | diff --git a/Help/release/dev/install-EXPORT-absolute-prefix.rst b/Help/release/dev/install-EXPORT-absolute-prefix.rst | |
41 | new file mode 100644 | |
42 | index 0000000..1b2a01c | |
43 | --- /dev/null | |
44 | +++ b/Help/release/dev/install-EXPORT-absolute-prefix.rst | |
45 | @@ -0,0 +1,9 @@ | |
46 | +install-EXPORT-absolute-prefix | |
47 | +------------------------------ | |
48 | + | |
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); | |
61 | } | |
62 | ||
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)) | |
72 | { | |
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. | |
77 | + os << | |
78 | + "# The installation prefix configured by this project.\n" | |
79 | + "set(_IMPORT_PREFIX \"" << installPrefix << "\")\n" | |
80 | + "\n"; | |
81 | + } | |
82 | + else | |
83 | + { | |
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); | |
91 | } | |
92 | os << "\n"; | |
93 | - | |
94 | - // Import location properties may reference this variable. | |
95 | - this->ImportPrefix = "${_IMPORT_PREFIX}/"; | |
96 | } | |
97 | ||
98 | std::vector<std::string> missingTargets; | |
99 | @@ -209,12 +217,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) | |
100 | << "\n"; | |
101 | ||
102 | // Cleanup the import prefix variable. | |
103 | - if(!this->ImportPrefix.empty()) | |
104 | - { | |
105 | - os << "# Cleanup temporary variables.\n" | |
106 | - << "set(_IMPORT_PREFIX)\n" | |
107 | - << "\n"; | |
108 | - } | |
109 | + os << "# Cleanup temporary variables.\n" | |
110 | + << "set(_IMPORT_PREFIX)\n" | |
111 | + << "\n"; | |
112 | this->GenerateImportedFileCheckLoop(os); | |
113 | ||
114 | bool result = true; | |
115 | @@ -394,11 +399,7 @@ cmExportInstallFileGenerator | |
116 | if(!cmSystemTools::FileIsFullPath(dest.c_str())) | |
117 | { | |
118 | // The target is installed relative to the installation prefix. | |
119 | - if(this->ImportPrefix.empty()) | |
120 | - { | |
121 | - this->ComplainAboutImportPrefix(itgen); | |
122 | - } | |
123 | - value = this->ImportPrefix; | |
124 | + value = "${_IMPORT_PREFIX}/"; | |
125 | } | |
126 | value += dest; | |
127 | value += "/"; | |
128 | @@ -508,24 +509,6 @@ cmExportInstallFileGenerator | |
129 | return namespaces; | |
130 | } | |
131 | ||
132 | - | |
133 | -//---------------------------------------------------------------------------- | |
134 | -void | |
135 | -cmExportInstallFileGenerator | |
136 | -::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen) | |
137 | -{ | |
138 | - const char* installDest = this->IEGen->GetDestination(); | |
139 | - cmOStringStream e; | |
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()); | |
148 | -} | |
149 | - | |
150 | //---------------------------------------------------------------------------- | |
151 | void | |
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 | |
159 | ); | |
160 | ||
161 | - void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen); | |
162 | - | |
163 | std::string InstallNameDir(cmTarget* target, const std::string& config); | |
164 | ||
165 | cmInstallExportGenerator* IEGen; | |
166 | ||
167 | - std::string ImportPrefix; | |
168 | - | |
169 | // The import file generated for each configuration. | |
170 | std::map<std::string, std::string> ConfigImportFiles; | |
171 | }; | |
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 | |
177 | ) | |
178 | ||
179 | add_subdirectory(Interface) | |
180 | + | |
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>" | |
186 | + ) | |
187 | +install( | |
188 | + TARGETS testLibAbs1 | |
189 | + EXPORT expAbs | |
190 | + ARCHIVE DESTINATION lib | |
191 | + INCLUDES DESTINATION include/abs | |
192 | + ) | |
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 | |
196 | new file mode 100644 | |
197 | index 0000000..4421227 | |
198 | --- /dev/null | |
199 | +++ b/Tests/ExportImport/Export/include/abs/1a/testLibAbs1a.h | |
200 | @@ -0,0 +1 @@ | |
201 | +#define testLibAbs1a | |
202 | diff --git a/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h | |
203 | new file mode 100644 | |
204 | index 0000000..00a2a29 | |
205 | --- /dev/null | |
206 | +++ b/Tests/ExportImport/Export/include/abs/1b/testLibAbs1b.h | |
207 | @@ -0,0 +1 @@ | |
208 | +#define testLibAbs1b | |
209 | diff --git a/Tests/ExportImport/Export/include/abs/testLibAbs1.h b/Tests/ExportImport/Export/include/abs/testLibAbs1.h | |
210 | new file mode 100644 | |
211 | index 0000000..19d80a5 | |
212 | --- /dev/null | |
213 | +++ b/Tests/ExportImport/Export/include/abs/testLibAbs1.h | |
214 | @@ -0,0 +1 @@ | |
215 | +extern int testLibAbs1(void); | |
216 | diff --git a/Tests/ExportImport/Export/testLibAbs1.c b/Tests/ExportImport/Export/testLibAbs1.c | |
217 | new file mode 100644 | |
218 | index 0000000..34aec75 | |
219 | --- /dev/null | |
220 | +++ b/Tests/ExportImport/Export/testLibAbs1.c | |
221 | @@ -0,0 +1 @@ | |
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) | |
228 | endforeach() | |
229 | ||
230 | #----------------------------------------------------------------------------- | |
231 | +include(${CMAKE_INSTALL_PREFIX}/lib/expAbs/expAbs.cmake) | |
232 | + | |
233 | +add_executable(imp_testExeAbs1 | |
234 | + imp_testExeAbs1.c | |
235 | + ) | |
236 | +target_link_libraries(imp_testExeAbs1 | |
237 | + expAbs_testLibAbs1 | |
238 | + ) | |
239 | + | |
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 | |
245 | new file mode 100644 | |
246 | index 0000000..069c3f0 | |
247 | --- /dev/null | |
248 | +++ b/Tests/ExportImport/Import/A/imp_testExeAbs1.c | |
249 | @@ -0,0 +1,15 @@ | |
250 | +#include "testLibAbs1.h" | |
251 | +#include "testLibAbs1a.h" | |
252 | +#include "testLibAbs1b.h" | |
253 | +#ifndef testLibAbs1a | |
254 | +# error "testLibAbs1a not defined" | |
255 | +#endif | |
256 | +#ifndef testLibAbs1b | |
257 | +# error "testLibAbs1b not defined" | |
258 | +#endif | |
259 | +int main() | |
260 | +{ | |
261 | + return 0 | |
262 | + + testLibAbs1() | |
263 | + ; | |
264 | +} | |
265 | -- | |
266 | 1.7.10.4 | |
267 |