1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportInstallFileGenerator.cxx,v $
6 Date: $Date: 2009-01-07 19:16:28 $
7 Version: $Revision: 1.9 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmExportInstallFileGenerator.h"
19 #include "cmGeneratedFileStream.h"
20 #include "cmInstallExportGenerator.h"
21 #include "cmInstallTargetGenerator.h"
23 //----------------------------------------------------------------------------
24 cmExportInstallFileGenerator
25 ::cmExportInstallFileGenerator(cmInstallExportGenerator
* iegen
):
26 InstallExportGenerator(iegen
)
30 //----------------------------------------------------------------------------
31 std::string
cmExportInstallFileGenerator::GetConfigImportFileGlob()
33 std::string glob
= this->FileBase
;
35 glob
+= this->FileExt
;
39 //----------------------------------------------------------------------------
40 bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream
& os
)
42 // Create all the imported targets.
43 for(std::vector
<cmTargetExport
*>::const_iterator
44 tei
= this->ExportSet
->begin();
45 tei
!= this->ExportSet
->end(); ++tei
)
47 cmTargetExport
* te
= *tei
;
48 if(this->ExportedTargets
.insert(te
->Target
).second
)
50 this->GenerateImportTargetCode(os
, te
->Target
);
55 e
<< "INSTALL(EXPORT \"" << this->Name
<< "\" ...) "
56 << "includes target \"" << te
->Target
->GetName()
57 << "\" more than once in the export set.";
58 cmSystemTools::Error(e
.str().c_str());
63 // Now load per-configuration properties for them.
64 os
<< "# Load information for each installed configuration.\n"
65 << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
66 << "FILE(GLOB CONFIG_FILES \"${_DIR}/"
67 << this->GetConfigImportFileGlob() << "\")\n"
68 << "FOREACH(f ${CONFIG_FILES})\n"
73 // Generate an import file for each configuration.
75 for(std::vector
<std::string
>::const_iterator
76 ci
= this->Configurations
.begin();
77 ci
!= this->Configurations
.end(); ++ci
)
79 if(!this->GenerateImportFileConfig(ci
->c_str()))
87 //----------------------------------------------------------------------------
89 cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config
)
91 // Skip configurations not enabled for this export.
92 if(!this->InstallExportGenerator
->InstallsForConfig(config
))
97 // Construct the name of the file to generate.
98 std::string fileName
= this->FileDir
;
100 fileName
+= this->FileBase
;
102 if(config
&& *config
)
104 fileName
+= cmSystemTools::LowerCase(config
);
108 fileName
+= "noconfig";
110 fileName
+= this->FileExt
;
112 // Open the output file to generate it.
113 cmGeneratedFileStream
exportFileStream(fileName
.c_str(), true);
114 if(!exportFileStream
)
116 std::string se
= cmSystemTools::GetLastSystemError();
118 e
<< "cannot write to file \"" << fileName
.c_str()
120 cmSystemTools::Error(e
.str().c_str());
123 std::ostream
& os
= exportFileStream
;
125 // Start with the import file header.
126 this->GenerateImportHeaderCode(os
, config
);
128 // Generate the per-config target information.
129 this->GenerateImportConfig(os
, config
);
131 // End with the import file footer.
132 this->GenerateImportFooterCode(os
);
134 // Record this per-config import file.
135 this->ConfigImportFiles
[config
] = fileName
;
140 //----------------------------------------------------------------------------
142 cmExportInstallFileGenerator
143 ::GenerateImportTargetsConfig(std::ostream
& os
,
144 const char* config
, std::string
const& suffix
)
146 // Add code to compute the installation prefix relative to the
147 // import file location.
148 const char* installDest
= this->InstallExportGenerator
->GetDestination();
149 if(!cmSystemTools::FileIsFullPath(installDest
))
151 std::string dest
= installDest
;
152 os
<< "# Compute the installation prefix relative to this file.\n"
153 << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
154 << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
158 "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
159 dest
= cmSystemTools::GetFilenamePath(dest
);
163 // Import location properties may reference this variable.
164 this->ImportPrefix
= "${_IMPORT_PREFIX}/";
167 // Add each target in the set to the export.
168 for(std::vector
<cmTargetExport
*>::const_iterator
169 tei
= this->ExportSet
->begin();
170 tei
!= this->ExportSet
->end(); ++tei
)
172 // Collect import properties for this target.
173 cmTargetExport
* te
= *tei
;
174 ImportPropertyMap properties
;
175 this->SetImportLocationProperty(config
, suffix
,
176 te
->ArchiveGenerator
, properties
);
177 this->SetImportLocationProperty(config
, suffix
,
178 te
->LibraryGenerator
, properties
);
179 this->SetImportLocationProperty(config
, suffix
,
180 te
->RuntimeGenerator
, properties
);
181 this->SetImportLocationProperty(config
, suffix
,
182 te
->FrameworkGenerator
, properties
);
183 this->SetImportLocationProperty(config
, suffix
,
184 te
->BundleGenerator
, properties
);
186 // If any file location was set for the target add it to the
188 if(!properties
.empty())
190 // Get the rest of the target details.
191 this->SetImportDetailProperties(config
, suffix
,
192 te
->Target
, properties
);
194 // TOOD: PUBLIC_HEADER_LOCATION
195 // This should wait until the build feature propagation stuff
196 // is done. Then this can be a propagated include directory.
197 // this->GenerateImportProperty(config, te->HeaderGenerator,
200 // Generate code in the export file.
201 this->GenerateImportPropertyCode(os
, config
, te
->Target
, properties
);
205 // Cleanup the import prefix variable.
206 if(!this->ImportPrefix
.empty())
208 os
<< "# Cleanup temporary variables.\n"
209 << "SET(_IMPORT_PREFIX)\n"
214 //----------------------------------------------------------------------------
216 cmExportInstallFileGenerator
217 ::SetImportLocationProperty(const char* config
, std::string
const& suffix
,
218 cmInstallTargetGenerator
* itgen
,
219 ImportPropertyMap
& properties
)
221 // Skip rules that do not match this configuration.
222 if(!(itgen
&& itgen
->InstallsForConfig(config
)))
227 // Get the target to be installed.
228 cmTarget
* target
= itgen
->GetTarget();
230 // Construct the installed location of the target.
231 std::string dest
= itgen
->GetDestination();
233 if(!cmSystemTools::FileIsFullPath(dest
.c_str()))
235 // The target is installed relative to the installation prefix.
236 if(this->ImportPrefix
.empty())
238 this->ComplainAboutImportPrefix(itgen
);
240 value
= this->ImportPrefix
;
245 if(itgen
->IsImportLibrary())
247 // Construct the property name.
248 std::string prop
= "IMPORTED_IMPLIB";
251 // Append the installed file name.
252 value
+= itgen
->GetInstallFilename(target
, config
,
253 cmInstallTargetGenerator::NameImplib
);
255 // Store the property.
256 properties
[prop
] = value
;
260 // Construct the property name.
261 std::string prop
= "IMPORTED_LOCATION";
264 // Append the installed file name.
265 if(target
->IsFrameworkOnApple())
267 value
+= itgen
->GetInstallFilename(target
, config
);
268 value
+= ".framework/";
269 value
+= itgen
->GetInstallFilename(target
, config
);
271 else if(target
->IsAppBundleOnApple())
273 value
+= itgen
->GetInstallFilename(target
, config
);
274 value
+= ".app/Contents/MacOS/";
275 value
+= itgen
->GetInstallFilename(target
, config
);
279 value
+= itgen
->GetInstallFilename(target
, config
,
280 cmInstallTargetGenerator::NameReal
);
283 // Store the property.
284 properties
[prop
] = value
;
288 //----------------------------------------------------------------------------
290 cmExportInstallFileGenerator
291 ::ComplainAboutImportPrefix(cmInstallTargetGenerator
* itgen
)
293 const char* installDest
= this->InstallExportGenerator
->GetDestination();
295 e
<< "INSTALL(EXPORT \"" << this->Name
<< "\") given absolute "
296 << "DESTINATION \"" << installDest
<< "\" but the export "
297 << "references an installation of target \""
298 << itgen
->GetTarget()->GetName() << "\" which has relative "
299 << "DESTINATION \"" << itgen
->GetDestination() << "\".";
300 cmSystemTools::Error(e
.str().c_str());
303 //----------------------------------------------------------------------------
305 cmExportInstallFileGenerator
306 ::ComplainAboutMissingTarget(cmTarget
* depender
, cmTarget
* dependee
)
309 e
<< "INSTALL(EXPORT \"" << this->Name
<< "\" ...) "
310 << "includes target \"" << depender
->GetName()
311 << "\" which requires target \"" << dependee
->GetName()
312 << "\" that is not in the export set.";
313 cmSystemTools::Error(e
.str().c_str());