CMake/Source/cmExportCommand.cxx
Brad King 9e64d5b272 ENH: Improve exporting/importing of targets
- Use real name instead of link for location of versioned targets
  - Error when a target is exported multiple times
2008-02-06 14:20:36 -05:00

187 lines
5.1 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 "cmExportCommand.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
#include "cmExportBuildFileGenerator.h"
cmExportCommand::cmExportCommand()
:cmCommand()
,ArgumentGroup()
,Targets(&Helper, "TARGETS")
,Append(&Helper, "APPEND", &ArgumentGroup)
,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
,Filename(&Helper, "FILE", &ArgumentGroup)
{
// at first TARGETS
this->Targets.Follows(0);
// and after that the other options in any order
this->ArgumentGroup.Follows(&this->Targets);
}
// cmExportCommand
bool cmExportCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
if(args.size() < 2 )
{
this->SetError("called with too few arguments");
return false;
}
std::vector<std::string> unknownArgs;
this->Helper.Parse(&args, &unknownArgs);
if (!unknownArgs.empty())
{
this->SetError("Unknown arguments.");
return false;
}
if (this->Targets.WasFound() == false)
{
this->SetError("TARGETS option missing.");
return false;
}
if(!this->Filename.WasFound())
{
this->SetError("FILE <filename> option missing.");
return false;
}
// Make sure the file has a .cmake extension.
if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
!= ".cmake")
{
cmOStringStream e;
e << "FILE option given filename \"" << this->Filename.GetString()
<< "\" which does not have an extension of \".cmake\".\n";
this->SetError(e.str().c_str());
return false;
}
// Get the file to write.
std::string fname = this->Filename.GetString();
if(cmSystemTools::FileIsFullPath(fname.c_str()))
{
if(!this->Makefile->CanIWriteThisFile(fname.c_str()))
{
cmOStringStream e;
e << "FILE option given filename \"" << fname
<< "\" which is in the source tree.\n";
this->SetError(e.str().c_str());
return false;
}
}
else
{
// Interpret relative paths with respect to the current build dir.
fname = this->Makefile->GetCurrentOutputDirectory();
fname += "/";
fname += this->Filename.GetString();
}
// Collect the targets to be exported.
std::vector<cmTarget*> targets;
for(std::vector<std::string>::const_iterator
currentTarget = this->Targets.GetVector().begin();
currentTarget != this->Targets.GetVector().end();
++currentTarget)
{
if(cmTarget* target =
this->Makefile->GetLocalGenerator()->
GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
{
if((target->GetType() == cmTarget::EXECUTABLE) ||
(target->GetType() == cmTarget::STATIC_LIBRARY) ||
(target->GetType() == cmTarget::SHARED_LIBRARY) ||
(target->GetType() == cmTarget::MODULE_LIBRARY))
{
targets.push_back(target);
}
else
{
cmOStringStream e;
e << "given target \"" << *currentTarget
<< "\" which is not an executable or library.";
this->SetError(e.str().c_str());
return false;
}
}
else
{
cmOStringStream e;
e << "given target \"" << *currentTarget
<< "\" which is not built by this project.";
this->SetError(e.str().c_str());
return false;
}
}
// Setup export file generation.
cmExportBuildFileGenerator ebfg;
ebfg.SetExportFile(fname.c_str());
ebfg.SetNamespace(this->Namespace.GetCString());
ebfg.SetAppendMode(this->Append.IsEnabled());
ebfg.SetExports(&targets);
ebfg.SetCommand(this);
// Compute the set of configurations exported.
if(const char* types =
this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
{
std::vector<std::string> configurationTypes;
cmSystemTools::ExpandListArgument(types, configurationTypes);
for(std::vector<std::string>::const_iterator
ci = configurationTypes.begin();
ci != configurationTypes.end(); ++ci)
{
ebfg.AddConfiguration(ci->c_str());
}
}
else if(const char* config =
this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
{
ebfg.AddConfiguration(config);
}
else
{
ebfg.AddConfiguration("");
}
// Generate the import file.
if(!ebfg.GenerateImportFile() && this->ErrorMessage.empty())
{
this->SetError("could not write export file.");
return false;
}
// Report generated error message if any.
if(!this->ErrorMessage.empty())
{
this->SetError(this->ErrorMessage.c_str());
return false;
}
return true;
}