diff options
Diffstat (limited to 'Source/cmInstallExportGenerator.cxx')
-rw-r--r-- | Source/cmInstallExportGenerator.cxx | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx new file mode 100644 index 0000000..69e3f2c --- /dev/null +++ b/Source/cmInstallExportGenerator.cxx @@ -0,0 +1,230 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmInstallExportGenerator.h" + +#include <stdio.h> + +#include "cmake.h" +#include "cmInstallTargetGenerator.h" +#include "cmGeneratedFileStream.h" +#include "cmTarget.h" +#include "cmMakefile.h" +#include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" + +#include "cmInstallFilesGenerator.h" + +#include "cmExportInstallFileGenerator.h" + +//---------------------------------------------------------------------------- +cmInstallExportGenerator::cmInstallExportGenerator( + const char* name, + const char* destination, + const char* file_permissions, + std::vector<std::string> const& configurations, + const char* component, + const char* filename, const char* name_space, + cmMakefile* mf) + :cmInstallGenerator(destination, configurations, component) + ,Name(name) + ,FilePermissions(file_permissions) + ,FileName(filename) + ,Namespace(name_space) + ,Makefile(mf) +{ + this->EFGen = new cmExportInstallFileGenerator(this); +} + +//---------------------------------------------------------------------------- +cmInstallExportGenerator::~cmInstallExportGenerator() +{ + delete this->EFGen; +} + +//---------------------------------------------------------------------------- +void cmInstallExportGenerator::ComputeTempDir() +{ + // Choose a temporary directory in which to generate the import + // files to be installed. + this->TempDir = this->Makefile->GetCurrentOutputDirectory(); + this->TempDir += cmake::GetCMakeFilesDirectory(); + this->TempDir += "/Export"; + if(this->Destination.empty()) + { + return; + } + else + { + this->TempDir += "/"; + } + + // Enforce a maximum length. + bool useMD5 = false; +#if defined(_WIN32) || defined(__CYGWIN__) + std::string::size_type const max_total_len = 250; +#else + std::string::size_type const max_total_len = 1000; +#endif + if(this->TempDir.size() < max_total_len) + { + // Keep the total path length below the limit. + std::string::size_type max_len = max_total_len - this->TempDir.size(); + if(this->Destination.size() > max_len) + { + useMD5 = true; + } + } + else + { + useMD5 = true; + } + if(useMD5) + { + // Replace the destination path with a hash to keep it short. + this->TempDir += + cmSystemTools::ComputeStringMD5(this->Destination.c_str()); + } + else + { + std::string dest = this->Destination; + // Avoid unix full paths. + if(dest[0] == '/') + { + dest[0] = '_'; + } + // Avoid windows full paths by removing colons. + cmSystemTools::ReplaceString(dest, ":", "_"); + // Avoid relative paths that go up the tree. + cmSystemTools::ReplaceString(dest, "../", "__/"); + // Avoid spaces. + cmSystemTools::ReplaceString(dest, " ", "_"); + this->TempDir += dest; + } +} + +//---------------------------------------------------------------------------- +void cmInstallExportGenerator::GenerateScript(std::ostream& os) +{ + // Get the export set requested. + ExportSet const* exportSet = + this->Makefile->GetLocalGenerator()->GetGlobalGenerator() + ->GetExportSet(this->Name.c_str()); + + // Skip empty sets. + if(!exportSet) + { + cmOStringStream e; + e << "INSTALL(EXPORT) given unknown export \"" << this->Name << "\""; + cmSystemTools::Error(e.str().c_str()); + return; + } + + // Create the temporary directory in which to store the files. + this->ComputeTempDir(); + cmSystemTools::MakeDirectory(this->TempDir.c_str()); + + // Construct a temporary location for the file. + this->MainImportFile = this->TempDir; + this->MainImportFile += "/"; + this->MainImportFile += this->FileName; + + // Generate the import file for this export set. + this->EFGen->SetName(this->Name.c_str()); + this->EFGen->SetExportSet(exportSet); + this->EFGen->SetExportFile(this->MainImportFile.c_str()); + this->EFGen->SetNamespace(this->Namespace.c_str()); + if(this->ConfigurationTypes->empty()) + { + if(this->ConfigurationName && *this->ConfigurationName) + { + this->EFGen->AddConfiguration(this->ConfigurationName); + } + else + { + this->EFGen->AddConfiguration(""); + } + } + else + { + for(std::vector<std::string>::const_iterator + ci = this->ConfigurationTypes->begin(); + ci != this->ConfigurationTypes->end(); ++ci) + { + this->EFGen->AddConfiguration(ci->c_str()); + } + } + this->EFGen->GenerateImportFile(); + + // Perform the main install script generation. + this->cmInstallGenerator::GenerateScript(os); +} + +//---------------------------------------------------------------------------- +void +cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os, + Indent const& indent) +{ + // Create the main install rules first. + this->cmInstallGenerator::GenerateScriptConfigs(os, indent); + + // Now create a configuration-specific install rule for the import + // file of each configuration. + std::vector<std::string> files; + for(std::map<cmStdString, cmStdString>::const_iterator + i = this->EFGen->GetConfigImportFiles().begin(); + i != this->EFGen->GetConfigImportFiles().end(); ++i) + { + files.push_back(i->second); + std::string config_test = this->CreateConfigTest(i->first.c_str()); + os << indent << "IF(" << config_test << ")\n"; + this->AddInstallRule(os, cmTarget::INSTALL_FILES, files, false, + this->FilePermissions.c_str(), 0, 0, 0, + indent.Next()); + os << indent << "ENDIF(" << config_test << ")\n"; + files.clear(); + } +} + +//---------------------------------------------------------------------------- +void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os, + Indent const& indent) +{ + // Remove old per-configuration export files if the main changes. + std::string installedDir = "$ENV{DESTDIR}"; + installedDir += this->GetInstallDestination(); + installedDir += "/"; + std::string installedFile = installedDir; + installedFile += this->FileName; + os << indent << "IF(EXISTS \"" << installedFile << "\")\n"; + Indent indentN = indent.Next(); + Indent indentNN = indentN.Next(); + Indent indentNNN = indentNN.Next(); + os << indentN << "FILE(DIFFERENT EXPORT_FILE_CHANGED FILES\n" + << indentN << " \"" << installedFile << "\"\n" + << indentN << " \"" << this->MainImportFile << "\")\n"; + os << indentN << "IF(EXPORT_FILE_CHANGED)\n"; + os << indentNN << "FILE(GLOB OLD_CONFIG_FILES \"" << installedDir + << this->EFGen->GetConfigImportFileGlob() << "\")\n"; + os << indentNN << "IF(OLD_CONFIG_FILES)\n"; + os << indentNNN << "MESSAGE(STATUS \"Old export file \\\"" << installedFile + << "\\\" will be replaced. Removing files [${OLD_CONFIG_FILES}].\")\n"; + os << indentNNN << "FILE(REMOVE ${OLD_CONFIG_FILES})\n"; + os << indentNN << "ENDIF(OLD_CONFIG_FILES)\n"; + os << indentN << "ENDIF(EXPORT_FILE_CHANGED)\n"; + os << indent << "ENDIF()\n"; + + // Install the main export file. + std::vector<std::string> files; + files.push_back(this->MainImportFile); + this->AddInstallRule(os, cmTarget::INSTALL_FILES, files, false, + this->FilePermissions.c_str(), 0, 0, 0, indent); +} |