1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmInstallExportGenerator.cxx,v $
6 Date: $Date: 2009-04-27 17:20:54 $
7 Version: $Revision: 1.10 $
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 "cmInstallExportGenerator.h"
22 #include "cmInstallTargetGenerator.h"
23 #include "cmGeneratedFileStream.h"
25 #include "cmMakefile.h"
26 #include "cmLocalGenerator.h"
27 #include "cmGlobalGenerator.h"
29 #include "cmInstallFilesGenerator.h"
31 #include "cmExportInstallFileGenerator.h"
33 //----------------------------------------------------------------------------
34 cmInstallExportGenerator::cmInstallExportGenerator(
36 const char* destination
,
37 const char* file_permissions
,
38 std::vector
<std::string
> const& configurations
,
39 const char* component
,
40 const char* filename
, const char* name_space
,
42 :cmInstallGenerator(destination
, configurations
, component
)
44 ,FilePermissions(file_permissions
)
46 ,Namespace(name_space
)
49 this->EFGen
= new cmExportInstallFileGenerator(this);
52 //----------------------------------------------------------------------------
53 cmInstallExportGenerator::~cmInstallExportGenerator()
58 //----------------------------------------------------------------------------
59 void cmInstallExportGenerator::ComputeTempDir()
61 // Choose a temporary directory in which to generate the import
62 // files to be installed.
63 this->TempDir
= this->Makefile
->GetCurrentOutputDirectory();
64 this->TempDir
+= cmake::GetCMakeFilesDirectory();
65 this->TempDir
+= "/Export";
66 if(this->Destination
.empty())
75 // Enforce a maximum length.
77 #if defined(_WIN32) || defined(__CYGWIN__)
78 std::string::size_type
const max_total_len
= 250;
80 std::string::size_type
const max_total_len
= 1000;
82 if(this->TempDir
.size() < max_total_len
)
84 // Keep the total path length below the limit.
85 std::string::size_type max_len
= max_total_len
- this->TempDir
.size();
86 if(this->Destination
.size() > max_len
)
97 // Replace the destination path with a hash to keep it short.
99 cmSystemTools::ComputeStringMD5(this->Destination
.c_str());
103 std::string dest
= this->Destination
;
104 // Avoid unix full paths.
109 // Avoid windows full paths by removing colons.
110 cmSystemTools::ReplaceString(dest
, ":", "_");
111 // Avoid relative paths that go up the tree.
112 cmSystemTools::ReplaceString(dest
, "../", "__/");
114 cmSystemTools::ReplaceString(dest
, " ", "_");
115 this->TempDir
+= dest
;
119 //----------------------------------------------------------------------------
120 void cmInstallExportGenerator::GenerateScript(std::ostream
& os
)
122 // Get the export set requested.
123 ExportSet
const* exportSet
=
124 this->Makefile
->GetLocalGenerator()->GetGlobalGenerator()
125 ->GetExportSet(this->Name
.c_str());
131 e
<< "INSTALL(EXPORT) given unknown export \"" << this->Name
<< "\"";
132 cmSystemTools::Error(e
.str().c_str());
136 // Create the temporary directory in which to store the files.
137 this->ComputeTempDir();
138 cmSystemTools::MakeDirectory(this->TempDir
.c_str());
140 // Construct a temporary location for the file.
141 this->MainImportFile
= this->TempDir
;
142 this->MainImportFile
+= "/";
143 this->MainImportFile
+= this->FileName
;
145 // Generate the import file for this export set.
146 this->EFGen
->SetName(this->Name
.c_str());
147 this->EFGen
->SetExportSet(exportSet
);
148 this->EFGen
->SetExportFile(this->MainImportFile
.c_str());
149 this->EFGen
->SetNamespace(this->Namespace
.c_str());
150 if(this->ConfigurationTypes
->empty())
152 if(this->ConfigurationName
&& *this->ConfigurationName
)
154 this->EFGen
->AddConfiguration(this->ConfigurationName
);
158 this->EFGen
->AddConfiguration("");
163 for(std::vector
<std::string
>::const_iterator
164 ci
= this->ConfigurationTypes
->begin();
165 ci
!= this->ConfigurationTypes
->end(); ++ci
)
167 this->EFGen
->AddConfiguration(ci
->c_str());
170 this->EFGen
->GenerateImportFile();
172 // Perform the main install script generation.
173 this->cmInstallGenerator::GenerateScript(os
);
176 //----------------------------------------------------------------------------
178 cmInstallExportGenerator::GenerateScriptConfigs(std::ostream
& os
,
179 Indent
const& indent
)
181 // Create the main install rules first.
182 this->cmInstallGenerator::GenerateScriptConfigs(os
, indent
);
184 // Now create a configuration-specific install rule for the import
185 // file of each configuration.
186 std::vector
<std::string
> files
;
187 for(std::map
<cmStdString
, cmStdString
>::const_iterator
188 i
= this->EFGen
->GetConfigImportFiles().begin();
189 i
!= this->EFGen
->GetConfigImportFiles().end(); ++i
)
191 files
.push_back(i
->second
);
192 std::string config_test
= this->CreateConfigTest(i
->first
.c_str());
193 os
<< indent
<< "IF(" << config_test
<< ")\n";
194 this->AddInstallRule(os
, cmTarget::INSTALL_FILES
, files
, false,
195 this->FilePermissions
.c_str(), 0, 0, 0,
197 os
<< indent
<< "ENDIF(" << config_test
<< ")\n";
202 //----------------------------------------------------------------------------
203 void cmInstallExportGenerator::GenerateScriptActions(std::ostream
& os
,
204 Indent
const& indent
)
206 // Remove old per-configuration export files if the main changes.
207 std::string installedDir
= "$ENV{DESTDIR}";
208 installedDir
+= this->GetInstallDestination();
210 std::string installedFile
= installedDir
;
211 installedFile
+= this->FileName
;
212 os
<< indent
<< "IF(EXISTS \"" << installedFile
<< "\")\n";
213 Indent indentN
= indent
.Next();
214 Indent indentNN
= indentN
.Next();
215 Indent indentNNN
= indentNN
.Next();
216 os
<< indentN
<< "FILE(DIFFERENT EXPORT_FILE_CHANGED FILES\n"
217 << indentN
<< " \"" << installedFile
<< "\"\n"
218 << indentN
<< " \"" << this->MainImportFile
<< "\")\n";
219 os
<< indentN
<< "IF(EXPORT_FILE_CHANGED)\n";
220 os
<< indentNN
<< "FILE(GLOB OLD_CONFIG_FILES \"" << installedDir
221 << this->EFGen
->GetConfigImportFileGlob() << "\")\n";
222 os
<< indentNN
<< "IF(OLD_CONFIG_FILES)\n";
223 os
<< indentNNN
<< "MESSAGE(STATUS \"Old export file \\\"" << installedFile
224 << "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n";
225 os
<< indentNNN
<< "FILE(REMOVE ${OLD_CONFIG_FILES})\n";
226 os
<< indentNN
<< "ENDIF(OLD_CONFIG_FILES)\n";
227 os
<< indentN
<< "ENDIF(EXPORT_FILE_CHANGED)\n";
228 os
<< indent
<< "ENDIF()\n";
230 // Install the main export file.
231 std::vector
<std::string
> files
;
232 files
.push_back(this->MainImportFile
);
233 this->AddInstallRule(os
, cmTarget::INSTALL_FILES
, files
, false,
234 this->FilePermissions
.c_str(), 0, 0, 0, indent
);