CMake/Source/cmInstallExportGenerator.cxx
2007-08-30 16:22:01 -04:00

273 lines
8.5 KiB
C++

/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include <stdio.h>
#include "cmInstallTargetGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmTarget.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFilesGenerator.h"
cmInstallExportGenerator::cmInstallExportGenerator(
const char* destination,
const char* file_permissions,
std::vector<std::string> const& configurations,
const char* component,
const char* filename, const char* prefix, const char* tempOutputDir)
:cmInstallGenerator(destination, configurations, component)
,FilePermissions(file_permissions)
,Filename(filename)
,Prefix(prefix)
,TempOutputDir(tempOutputDir)
{
}
/* Helper function which adds the install locations from the generator
to the properties for this target.
*/
bool cmInstallExportGenerator::AddInstallLocations(cmTargetWithProperties* twp,
cmInstallTargetGenerator* generator,
const char* prefix)
{
if (generator == 0) // nothing to do
{
return true;
}
if (prefix == 0)
{
prefix = "";
}
const std::vector<std::string>& configs = generator->GetConfigurations();
if (configs.empty())
{
std::string propertyName = prefix;
propertyName += "LOCATION";
// check that this property doesn't exist yet and add it then
if (twp->Properties.find(propertyName.c_str()) == twp->Properties.end())
{
std::string destinationFilename = generator->GetDestination();
destinationFilename += "/";
destinationFilename += generator->GetInstallFilename(0);
twp->Properties[propertyName.c_str()] = destinationFilename;
}
else
{
return false;
}
}
else
{
for(std::vector<std::string>::const_iterator configIt = configs.begin();
configIt != configs.end();
++configIt)
{
std::string propertyName = configIt->c_str();
propertyName += "_";
propertyName += prefix;
propertyName += "LOCATION";
// check that this property doesn't exist yet and add it then
if (twp->Properties.find(propertyName.c_str()) == twp->Properties.end())
{
std::string destinationFilename = generator->GetDestination();
destinationFilename += "/";
destinationFilename +=generator->GetInstallFilename(configIt->c_str());
twp->Properties[propertyName.c_str()] = destinationFilename;
}
else
{
return false;
}
}
}
return true;
}
bool cmInstallExportGenerator::AddInstallLocations(cmTargetWithProperties* twp,
cmInstallFilesGenerator* generator,
const char* propertyName)
{
if (generator == 0) // nothing to do
{
return true;
}
if ((propertyName == 0) || (*propertyName == '\0'))
{
return false;
}
// check that this property doesn't exist yet and add it then
if (twp->Properties.find(propertyName) == twp->Properties.end())
{
twp->Properties[propertyName] = generator->GetDestination();
return true;
}
return false;
}
bool cmInstallExportGenerator::SetExportSet(const char* name,
const std::vector<cmTargetExport*>* set)
{
if ((name == 0) || (*name == 0) || (set==0))
{
return false;
}
this->Name = name;
/* iterate over all targets in the set.
If a cmTargetWithProperties with the same name already exists in this
generator, add the new properties to it. If the property already exists,
fail with an error.
If no cmTargetWithProperties exists, create a new one.
*/
for(std::vector<cmTargetExport*>::const_iterator it=set->begin();
it != set->end();
++it)
{
std::string targetName = (*it)->Target->GetName();
cmTargetWithProperties* targetWithProps = 0;
for(unsigned int i=0; i<this->Targets.size(); i++)
{
if (targetName == this->Targets[i]->Target->GetName())
{
targetWithProps = this->Targets[i];
break;
}
}
if (targetWithProps == 0)
{
targetWithProps = new cmTargetWithProperties((*it)->Target);
this->Targets.push_back(targetWithProps);
}
if (this->AddInstallLocations(targetWithProps, (*it)->ArchiveGenerator,
"ARCHIVE_") == false)
{
return false;
}
if (this->AddInstallLocations(targetWithProps, (*it)->RuntimeGenerator,
"") == false)
{
return false;
}
if (this->AddInstallLocations(targetWithProps, (*it)->LibraryGenerator,
"LIBRARY_") == false)
{
return false;
}
if (this->AddInstallLocations(targetWithProps, (*it)->HeaderGenerator,
"PUBLIC_HEADER_LOCATION") == false)
{
return false;
}
}
return true;
}
void cmInstallExportGenerator::GenerateScript(std::ostream& os)
{
// for the case that somebody exports the same set with the same file name
// to different locations make the temp filename unique
char buf[64];
sprintf(buf, "%p", this);
this->ExportFilename = this->TempOutputDir;
this->ExportFilename += "/";
this->ExportFilename += this->Filename;
this->ExportFilename += ".";
this->ExportFilename += buf;
cmGeneratedFileStream exportFileStream(this->ExportFilename.c_str());
if(!exportFileStream)
{
return;
}
/* for every target add the IMPORT statements and set the properties
of the target. */
for(std::vector<cmTargetWithProperties*>::const_iterator
targetIt = this->Targets.begin();
targetIt != this->Targets.end();
++targetIt)
{
switch ((*targetIt)->Target->GetType())
{
case cmTarget::EXECUTABLE:
exportFileStream << "ADD_EXECUTABLE(" << this->Prefix.c_str()
<< (*targetIt)->Target->GetName()
<< " IMPORT )\n";
break;
case cmTarget::STATIC_LIBRARY:
exportFileStream << "ADD_LIBRARY(" << this->Prefix.c_str()
<< (*targetIt)->Target->GetName()
<< " STATIC IMPORT )\n";
break;
case cmTarget::SHARED_LIBRARY:
exportFileStream << "ADD_LIBRARY(" << this->Prefix.c_str()
<< (*targetIt)->Target->GetName()
<< " SHARED IMPORT )\n";
break;
case cmTarget::MODULE_LIBRARY:
exportFileStream << "ADD_LIBRARY(" << this->Prefix.c_str()
<< (*targetIt)->Target->GetName()
<< " MODULE IMPORT )\n";
break;
default: // should never happen
break;
}
exportFileStream << "SET_TARGET_PROPERTIES ( " << this->Prefix.c_str()
<< (*targetIt)->Target->GetName() << " PROPERTIES \n";
for (std::map<std::string, std::string>::const_iterator
propIt = (*targetIt)->Properties.begin();
propIt != (*targetIt)->Properties.end();
++propIt)
{
exportFileStream << " " << propIt->first
<< " \"" << propIt->second << "\"\n";
}
exportFileStream << " )\n\n";
}
// Perform the main install script generation.
this->cmInstallGenerator::GenerateScript(os);
}
//----------------------------------------------------------------------------
void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
Indent const& indent)
{
// install rule for the file created above
std::vector<std::string> exportFile;
exportFile.push_back(this->ExportFilename);
this->AddInstallRule(os, this->Destination.c_str(), cmTarget::INSTALL_FILES,
exportFile, false, 0,
this->FilePermissions.c_str(),
0, this->Filename.c_str(), 0, indent);
}