1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmExportInstallFileGenerator.cxx,v $
6 Date: $Date: 2008-02-06 19:20:35 $
7 Version: $Revision: 1.8 $
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 bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream
& os
)
33 // Create all the imported targets.
34 for(std::vector
<cmTargetExport
*>::const_iterator
35 tei
= this->ExportSet
->begin();
36 tei
!= this->ExportSet
->end(); ++tei
)
38 cmTargetExport
* te
= *tei
;
39 if(this->ExportedTargets
.insert(te
->Target
).second
)
41 this->GenerateImportTargetCode(os
, te
->Target
);
46 e
<< "INSTALL(EXPORT \"" << this->Name
<< "\" ...) "
47 << "includes target \"" << te
->Target
->GetName()
48 << "\" more than once in the export set.";
49 cmSystemTools::Error(e
.str().c_str());
54 // Now load per-configuration properties for them.
55 os
<< "# Load information for each installed configuration.\n"
56 << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
57 << "FILE(GLOB CONFIG_FILES \"${_DIR}/"
58 << this->FileBase
<< "-*" << this->FileExt
<< "\")\n"
59 << "FOREACH(f ${CONFIG_FILES})\n"
64 // Generate an import file for each configuration.
66 for(std::vector
<std::string
>::const_iterator
67 ci
= this->Configurations
.begin();
68 ci
!= this->Configurations
.end(); ++ci
)
70 if(!this->GenerateImportFileConfig(ci
->c_str()))
78 //----------------------------------------------------------------------------
80 cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config
)
82 // Skip configurations not enabled for this export.
83 if(!this->InstallExportGenerator
->InstallsForConfig(config
))
88 // Construct the name of the file to generate.
89 std::string fileName
= this->FileDir
;
91 fileName
+= this->FileBase
;
95 fileName
+= cmSystemTools::LowerCase(config
);
99 fileName
+= "noconfig";
101 fileName
+= this->FileExt
;
103 // Open the output file to generate it.
104 cmGeneratedFileStream
exportFileStream(fileName
.c_str(), true);
105 if(!exportFileStream
)
107 std::string se
= cmSystemTools::GetLastSystemError();
109 e
<< "cannot write to file \"" << fileName
.c_str()
111 cmSystemTools::Error(e
.str().c_str());
114 std::ostream
& os
= exportFileStream
;
116 // Start with the import file header.
117 this->GenerateImportHeaderCode(os
, config
);
119 // Generate the per-config target information.
120 this->GenerateImportConfig(os
, config
);
122 // End with the import file footer.
123 this->GenerateImportFooterCode(os
);
125 // Record this per-config import file.
126 this->ConfigImportFiles
[config
] = fileName
;
131 //----------------------------------------------------------------------------
133 cmExportInstallFileGenerator
134 ::GenerateImportTargetsConfig(std::ostream
& os
,
135 const char* config
, std::string
const& suffix
)
137 // Add code to compute the installation prefix relative to the
138 // import file location.
139 const char* installDest
= this->InstallExportGenerator
->GetDestination();
140 if(!cmSystemTools::FileIsFullPath(installDest
))
142 std::string dest
= installDest
;
143 os
<< "# Compute the installation prefix relative to this file.\n"
144 << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
145 << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
149 "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
150 dest
= cmSystemTools::GetFilenamePath(dest
);
154 // Import location properties may reference this variable.
155 this->ImportPrefix
= "${_IMPORT_PREFIX}/";
158 // Add each target in the set to the export.
159 for(std::vector
<cmTargetExport
*>::const_iterator
160 tei
= this->ExportSet
->begin();
161 tei
!= this->ExportSet
->end(); ++tei
)
163 // Collect import properties for this target.
164 cmTargetExport
* te
= *tei
;
165 ImportPropertyMap properties
;
166 this->SetImportLocationProperty(config
, suffix
,
167 te
->ArchiveGenerator
, properties
);
168 this->SetImportLocationProperty(config
, suffix
,
169 te
->LibraryGenerator
, properties
);
170 this->SetImportLocationProperty(config
, suffix
,
171 te
->RuntimeGenerator
, properties
);
172 this->SetImportLocationProperty(config
, suffix
,
173 te
->FrameworkGenerator
, properties
);
174 this->SetImportLocationProperty(config
, suffix
,
175 te
->BundleGenerator
, properties
);
177 // If any file location was set for the target add it to the
179 if(!properties
.empty())
181 // Get the rest of the target details.
182 this->SetImportDetailProperties(config
, suffix
,
183 te
->Target
, properties
);
185 // TOOD: PUBLIC_HEADER_LOCATION
186 // This should wait until the build feature propagation stuff
187 // is done. Then this can be a propagated include directory.
188 // this->GenerateImportProperty(config, te->HeaderGenerator,
191 // Generate code in the export file.
192 this->GenerateImportPropertyCode(os
, config
, te
->Target
, properties
);
196 // Cleanup the import prefix variable.
197 if(!this->ImportPrefix
.empty())
199 os
<< "# Cleanup temporary variables.\n"
200 << "SET(_IMPORT_PREFIX)\n"
205 //----------------------------------------------------------------------------
207 cmExportInstallFileGenerator
208 ::SetImportLocationProperty(const char* config
, std::string
const& suffix
,
209 cmInstallTargetGenerator
* itgen
,
210 ImportPropertyMap
& properties
)
212 // Skip rules that do not match this configuration.
213 if(!(itgen
&& itgen
->InstallsForConfig(config
)))
218 // Get the target to be installed.
219 cmTarget
* target
= itgen
->GetTarget();
221 // Construct the installed location of the target.
222 std::string dest
= itgen
->GetDestination();
224 if(!cmSystemTools::FileIsFullPath(dest
.c_str()))
226 // The target is installed relative to the installation prefix.
227 if(this->ImportPrefix
.empty())
229 this->ComplainAboutImportPrefix(itgen
);
231 value
= this->ImportPrefix
;
236 if(itgen
->IsImportLibrary())
238 // Construct the property name.
239 std::string prop
= "IMPORTED_IMPLIB";
242 // Append the installed file name.
243 value
+= itgen
->GetInstallFilename(target
, config
,
244 cmInstallTargetGenerator::NameImplib
);
246 // Store the property.
247 properties
[prop
] = value
;
251 // Construct the property name.
252 std::string prop
= "IMPORTED_LOCATION";
255 // Append the installed file name.
256 if(target
->IsFrameworkOnApple())
258 value
+= itgen
->GetInstallFilename(target
, config
);
259 value
+= ".framework/";
260 value
+= itgen
->GetInstallFilename(target
, config
);
262 else if(target
->IsAppBundleOnApple())
264 value
+= itgen
->GetInstallFilename(target
, config
);
265 value
+= ".app/Contents/MacOS/";
266 value
+= itgen
->GetInstallFilename(target
, config
);
270 value
+= itgen
->GetInstallFilename(target
, config
,
271 cmInstallTargetGenerator::NameReal
);
274 // Store the property.
275 properties
[prop
] = value
;
279 //----------------------------------------------------------------------------
281 cmExportInstallFileGenerator
282 ::ComplainAboutImportPrefix(cmInstallTargetGenerator
* itgen
)
284 const char* installDest
= this->InstallExportGenerator
->GetDestination();
286 e
<< "INSTALL(EXPORT \"" << this->Name
<< "\") given absolute "
287 << "DESTINATION \"" << installDest
<< "\" but the export "
288 << "references an installation of target \""
289 << itgen
->GetTarget()->GetName() << "\" which has relative "
290 << "DESTINATION \"" << itgen
->GetDestination() << "\".";
291 cmSystemTools::Error(e
.str().c_str());
294 //----------------------------------------------------------------------------
296 cmExportInstallFileGenerator
297 ::ComplainAboutMissingTarget(cmTarget
* depender
, cmTarget
* dependee
)
300 e
<< "INSTALL(EXPORT \"" << this->Name
<< "\" ...) "
301 << "includes target \"" << depender
->GetName()
302 << "\" which requires target \"" << dependee
->GetName()
303 << "\" that is not in the export set.";
304 cmSystemTools::Error(e
.str().c_str());