Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / cmExportInstallFileGenerator.cxx
blob460ca7fbd6d93c22135fbfb1f92f57404b7d5e80
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportInstallFileGenerator.cxx,v $
5 Language: C++
6 <<<<<<< cmExportInstallFileGenerator.cxx
7 Date: $Date: 2008/02/06 19:20:35 $
8 Version: $Revision: 1.8 $
9 =======
10 Date: $Date: 2009-01-07 19:16:28 $
11 Version: $Revision: 1.9 $
12 >>>>>>> 1.9
14 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
15 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
17 This software is distributed WITHOUT ANY WARRANTY; without even
18 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 PURPOSE. See the above copyright notices for more information.
21 =========================================================================*/
22 #include "cmExportInstallFileGenerator.h"
24 #include "cmGeneratedFileStream.h"
25 #include "cmInstallExportGenerator.h"
26 #include "cmInstallTargetGenerator.h"
28 //----------------------------------------------------------------------------
29 cmExportInstallFileGenerator
30 ::cmExportInstallFileGenerator(cmInstallExportGenerator* iegen):
31 InstallExportGenerator(iegen)
35 //----------------------------------------------------------------------------
36 std::string cmExportInstallFileGenerator::GetConfigImportFileGlob()
38 std::string glob = this->FileBase;
39 glob += "-*";
40 glob += this->FileExt;
41 return glob;
44 //----------------------------------------------------------------------------
45 bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
47 // Create all the imported targets.
48 for(std::vector<cmTargetExport*>::const_iterator
49 tei = this->ExportSet->begin();
50 tei != this->ExportSet->end(); ++tei)
52 cmTargetExport* te = *tei;
53 if(this->ExportedTargets.insert(te->Target).second)
55 this->GenerateImportTargetCode(os, te->Target);
57 else
59 cmOStringStream e;
60 e << "INSTALL(EXPORT \"" << this->Name << "\" ...) "
61 << "includes target \"" << te->Target->GetName()
62 << "\" more than once in the export set.";
63 cmSystemTools::Error(e.str().c_str());
64 return false;
68 // Now load per-configuration properties for them.
69 os << "# Load information for each installed configuration.\n"
70 << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
71 << "FILE(GLOB CONFIG_FILES \"${_DIR}/"
72 << this->GetConfigImportFileGlob() << "\")\n"
73 << "FOREACH(f ${CONFIG_FILES})\n"
74 << " INCLUDE(${f})\n"
75 << "ENDFOREACH(f)\n"
76 << "\n";
78 // Generate an import file for each configuration.
79 bool result = true;
80 for(std::vector<std::string>::const_iterator
81 ci = this->Configurations.begin();
82 ci != this->Configurations.end(); ++ci)
84 if(!this->GenerateImportFileConfig(ci->c_str()))
86 result = false;
89 return result;
92 //----------------------------------------------------------------------------
93 bool
94 cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
96 // Skip configurations not enabled for this export.
97 if(!this->InstallExportGenerator->InstallsForConfig(config))
99 return true;
102 // Construct the name of the file to generate.
103 std::string fileName = this->FileDir;
104 fileName += "/";
105 fileName += this->FileBase;
106 fileName += "-";
107 if(config && *config)
109 fileName += cmSystemTools::LowerCase(config);
111 else
113 fileName += "noconfig";
115 fileName += this->FileExt;
117 // Open the output file to generate it.
118 cmGeneratedFileStream exportFileStream(fileName.c_str(), true);
119 if(!exportFileStream)
121 std::string se = cmSystemTools::GetLastSystemError();
122 cmOStringStream e;
123 e << "cannot write to file \"" << fileName.c_str()
124 << "\": " << se;
125 cmSystemTools::Error(e.str().c_str());
126 return false;
128 std::ostream& os = exportFileStream;
130 // Start with the import file header.
131 this->GenerateImportHeaderCode(os, config);
133 // Generate the per-config target information.
134 this->GenerateImportConfig(os, config);
136 // End with the import file footer.
137 this->GenerateImportFooterCode(os);
139 // Record this per-config import file.
140 this->ConfigImportFiles[config] = fileName;
142 return true;
145 //----------------------------------------------------------------------------
146 void
147 cmExportInstallFileGenerator
148 ::GenerateImportTargetsConfig(std::ostream& os,
149 const char* config, std::string const& suffix)
151 // Add code to compute the installation prefix relative to the
152 // import file location.
153 const char* installDest = this->InstallExportGenerator->GetDestination();
154 if(!cmSystemTools::FileIsFullPath(installDest))
156 std::string dest = installDest;
157 os << "# Compute the installation prefix relative to this file.\n"
158 << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
159 << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
160 while(!dest.empty())
162 os <<
163 "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
164 dest = cmSystemTools::GetFilenamePath(dest);
166 os << "\n";
168 // Import location properties may reference this variable.
169 this->ImportPrefix = "${_IMPORT_PREFIX}/";
172 // Add each target in the set to the export.
173 for(std::vector<cmTargetExport*>::const_iterator
174 tei = this->ExportSet->begin();
175 tei != this->ExportSet->end(); ++tei)
177 // Collect import properties for this target.
178 cmTargetExport* te = *tei;
179 ImportPropertyMap properties;
180 this->SetImportLocationProperty(config, suffix,
181 te->ArchiveGenerator, properties);
182 this->SetImportLocationProperty(config, suffix,
183 te->LibraryGenerator, properties);
184 this->SetImportLocationProperty(config, suffix,
185 te->RuntimeGenerator, properties);
186 this->SetImportLocationProperty(config, suffix,
187 te->FrameworkGenerator, properties);
188 this->SetImportLocationProperty(config, suffix,
189 te->BundleGenerator, properties);
191 // If any file location was set for the target add it to the
192 // import file.
193 if(!properties.empty())
195 // Get the rest of the target details.
196 this->SetImportDetailProperties(config, suffix,
197 te->Target, properties);
199 // TOOD: PUBLIC_HEADER_LOCATION
200 // This should wait until the build feature propagation stuff
201 // is done. Then this can be a propagated include directory.
202 // this->GenerateImportProperty(config, te->HeaderGenerator,
203 // properties);
205 // Generate code in the export file.
206 this->GenerateImportPropertyCode(os, config, te->Target, properties);
210 // Cleanup the import prefix variable.
211 if(!this->ImportPrefix.empty())
213 os << "# Cleanup temporary variables.\n"
214 << "SET(_IMPORT_PREFIX)\n"
215 << "\n";
219 //----------------------------------------------------------------------------
220 void
221 cmExportInstallFileGenerator
222 ::SetImportLocationProperty(const char* config, std::string const& suffix,
223 cmInstallTargetGenerator* itgen,
224 ImportPropertyMap& properties)
226 // Skip rules that do not match this configuration.
227 if(!(itgen && itgen->InstallsForConfig(config)))
229 return;
232 // Get the target to be installed.
233 cmTarget* target = itgen->GetTarget();
235 // Construct the installed location of the target.
236 std::string dest = itgen->GetDestination();
237 std::string value;
238 if(!cmSystemTools::FileIsFullPath(dest.c_str()))
240 // The target is installed relative to the installation prefix.
241 if(this->ImportPrefix.empty())
243 this->ComplainAboutImportPrefix(itgen);
245 value = this->ImportPrefix;
247 value += dest;
248 value += "/";
250 if(itgen->IsImportLibrary())
252 // Construct the property name.
253 std::string prop = "IMPORTED_IMPLIB";
254 prop += suffix;
256 // Append the installed file name.
257 value += itgen->GetInstallFilename(target, config,
258 cmInstallTargetGenerator::NameImplib);
260 // Store the property.
261 properties[prop] = value;
263 else
265 // Construct the property name.
266 std::string prop = "IMPORTED_LOCATION";
267 prop += suffix;
269 // Append the installed file name.
270 if(target->IsFrameworkOnApple())
272 value += itgen->GetInstallFilename(target, config);
273 value += ".framework/";
274 value += itgen->GetInstallFilename(target, config);
276 else if(target->IsAppBundleOnApple())
278 value += itgen->GetInstallFilename(target, config);
279 value += ".app/Contents/MacOS/";
280 value += itgen->GetInstallFilename(target, config);
282 else
284 value += itgen->GetInstallFilename(target, config,
285 cmInstallTargetGenerator::NameReal);
288 // Store the property.
289 properties[prop] = value;
293 //----------------------------------------------------------------------------
294 void
295 cmExportInstallFileGenerator
296 ::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen)
298 const char* installDest = this->InstallExportGenerator->GetDestination();
299 cmOStringStream e;
300 e << "INSTALL(EXPORT \"" << this->Name << "\") given absolute "
301 << "DESTINATION \"" << installDest << "\" but the export "
302 << "references an installation of target \""
303 << itgen->GetTarget()->GetName() << "\" which has relative "
304 << "DESTINATION \"" << itgen->GetDestination() << "\".";
305 cmSystemTools::Error(e.str().c_str());
308 //----------------------------------------------------------------------------
309 void
310 cmExportInstallFileGenerator
311 ::ComplainAboutMissingTarget(cmTarget* depender, cmTarget* dependee)
313 cmOStringStream e;
314 e << "INSTALL(EXPORT \"" << this->Name << "\" ...) "
315 << "includes target \"" << depender->GetName()
316 << "\" which requires target \"" << dependee->GetName()
317 << "\" that is not in the export set.";
318 cmSystemTools::Error(e.str().c_str());