1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportInstallFileGenerator.cxx,v $
6 <<<<<<< cmExportInstallFileGenerator.cxx
7 Date: $Date: 2008/02/06 19:20:35 $
8 Version: $Revision: 1.8 $
10 Date: $Date: 2009-01-07 19:16:28 $
11 Version: $Revision: 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
;
40 glob
+= this->FileExt
;
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
);
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());
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"
78 // Generate an import file for each configuration.
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()))
92 //----------------------------------------------------------------------------
94 cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config
)
96 // Skip configurations not enabled for this export.
97 if(!this->InstallExportGenerator
->InstallsForConfig(config
))
102 // Construct the name of the file to generate.
103 std::string fileName
= this->FileDir
;
105 fileName
+= this->FileBase
;
107 if(config
&& *config
)
109 fileName
+= cmSystemTools::LowerCase(config
);
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();
123 e
<< "cannot write to file \"" << fileName
.c_str()
125 cmSystemTools::Error(e
.str().c_str());
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
;
145 //----------------------------------------------------------------------------
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";
163 "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
164 dest
= cmSystemTools::GetFilenamePath(dest
);
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
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,
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"
219 //----------------------------------------------------------------------------
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
)))
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();
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
;
250 if(itgen
->IsImportLibrary())
252 // Construct the property name.
253 std::string prop
= "IMPORTED_IMPLIB";
256 // Append the installed file name.
257 value
+= itgen
->GetInstallFilename(target
, config
,
258 cmInstallTargetGenerator::NameImplib
);
260 // Store the property.
261 properties
[prop
] = value
;
265 // Construct the property name.
266 std::string prop
= "IMPORTED_LOCATION";
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
);
284 value
+= itgen
->GetInstallFilename(target
, config
,
285 cmInstallTargetGenerator::NameReal
);
288 // Store the property.
289 properties
[prop
] = value
;
293 //----------------------------------------------------------------------------
295 cmExportInstallFileGenerator
296 ::ComplainAboutImportPrefix(cmInstallTargetGenerator
* itgen
)
298 const char* installDest
= this->InstallExportGenerator
->GetDestination();
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 //----------------------------------------------------------------------------
310 cmExportInstallFileGenerator
311 ::ComplainAboutMissingTarget(cmTarget
* depender
, cmTarget
* dependee
)
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());