ENH: put the 64 bit paths first
[cmake.git] / Source / cmInstallExportGenerator.cxx
blob5245f4c570894a323b867b5abbef7f71f253fdb7
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmInstallExportGenerator.cxx,v $
5 Language: C++
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"
19 #include <stdio.h>
21 #include "cmake.h"
22 #include "cmInstallTargetGenerator.h"
23 #include "cmGeneratedFileStream.h"
24 #include "cmTarget.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(
35 const char* name,
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,
41 cmMakefile* mf)
42 :cmInstallGenerator(destination, configurations, component)
43 ,Name(name)
44 ,FilePermissions(file_permissions)
45 ,FileName(filename)
46 ,Namespace(name_space)
47 ,Makefile(mf)
49 this->EFGen = new cmExportInstallFileGenerator(this);
52 //----------------------------------------------------------------------------
53 cmInstallExportGenerator::~cmInstallExportGenerator()
55 delete this->EFGen;
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())
68 return;
70 else
72 this->TempDir += "/";
75 // Enforce a maximum length.
76 bool useMD5 = false;
77 #if defined(_WIN32) || defined(__CYGWIN__)
78 std::string::size_type const max_total_len = 250;
79 #else
80 std::string::size_type const max_total_len = 1000;
81 #endif
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)
88 useMD5 = true;
91 else
93 useMD5 = true;
95 if(useMD5)
97 // Replace the destination path with a hash to keep it short.
98 this->TempDir +=
99 cmSystemTools::ComputeStringMD5(this->Destination.c_str());
101 else
103 std::string dest = this->Destination;
104 // Avoid unix full paths.
105 if(dest[0] == '/')
107 dest[0] = '_';
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, "../", "__/");
113 // Avoid spaces.
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());
127 // Skip empty sets.
128 if(!exportSet)
130 cmOStringStream e;
131 e << "INSTALL(EXPORT) given unknown export \"" << this->Name << "\"";
132 cmSystemTools::Error(e.str().c_str());
133 return;
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);
156 else
158 this->EFGen->AddConfiguration("");
161 else
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 //----------------------------------------------------------------------------
177 void
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,
196 indent.Next());
197 os << indent << "ENDIF(" << config_test << ")\n";
198 files.clear();
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();
209 installedDir += "/";
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);