summaryrefslogtreecommitdiff
path: root/Source/cmInstallExportGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmInstallExportGenerator.cxx')
-rw-r--r--Source/cmInstallExportGenerator.cxx229
1 files changed, 229 insertions, 0 deletions
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
new file mode 100644
index 000000000..28a19d740
--- /dev/null
+++ b/Source/cmInstallExportGenerator.cxx
@@ -0,0 +1,229 @@
+/*============================================================================
+ 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 "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, cmInstallType_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, cmInstallType_FILES, files, false,
+ this->FilePermissions.c_str(), 0, 0, 0, indent);
+}