summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-12-23 16:07:26 (GMT)
committerStephen Kelly <steveire@gmail.com>2013-12-24 12:02:49 (GMT)
commitcbe7e8fae48b3663e784bb37d5f66bf8b3eb0546 (patch)
tree910046c109660f4533f0ec6ceec1de485e3032d2 /Source
parente73d1ad003c50730a8141db757462574c0c2dddc (diff)
downloadCMake-cbe7e8fae48b3663e784bb37d5f66bf8b3eb0546.zip
CMake-cbe7e8fae48b3663e784bb37d5f66bf8b3eb0546.tar.gz
CMake-cbe7e8fae48b3663e784bb37d5f66bf8b3eb0546.tar.bz2
export: Implement EXPORT subcommand (#9822)
Teach the export command to handle export sets defined by invocations of install(TARGETS ... EXPORT foo). This makes maintenance of targets exported to both the build tree and install tree trivial.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmExportBuildFileGenerator.cxx36
-rw-r--r--Source/cmExportBuildFileGenerator.h7
-rw-r--r--Source/cmExportCommand.cxx160
-rw-r--r--Source/cmExportCommand.h4
4 files changed, 148 insertions, 59 deletions
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index c10f86f..b669cd1 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -13,11 +13,14 @@
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
+#include "cmExportSet.h"
+#include "cmTargetExport.h"
//----------------------------------------------------------------------------
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
{
this->Makefile = 0;
+ this->ExportSet = 0;
}
//----------------------------------------------------------------------------
@@ -26,9 +29,11 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
std::string expectedTargets;
std::string sep;
+ std::vector<std::string> targets;
+ this->GetTargets(targets);
for(std::vector<std::string>::const_iterator
- tei = this->Targets.begin();
- tei != this->Targets.end(); ++tei)
+ tei = targets.begin();
+ tei != targets.end(); ++tei)
{
cmTarget *te = this->Makefile->FindTargetToUse(tei->c_str());
expectedTargets += sep + this->Namespace + te->GetExportName();
@@ -153,6 +158,12 @@ cmExportBuildFileGenerator
}
//----------------------------------------------------------------------------
+void cmExportBuildFileGenerator::SetExportSet(cmExportSet *exportSet)
+{
+ this->ExportSet = exportSet;
+}
+
+//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator
::SetImportLocationProperty(const char* config, std::string const& suffix,
@@ -232,6 +243,23 @@ cmExportBuildFileGenerator::HandleMissingTarget(
}
//----------------------------------------------------------------------------
+void cmExportBuildFileGenerator
+::GetTargets(std::vector<std::string> &targets) const
+{
+ if (this->ExportSet)
+ {
+ for(std::vector<cmTargetExport*>::const_iterator
+ tei = this->ExportSet->GetTargetExports()->begin();
+ tei != this->ExportSet->GetTargetExports()->end(); ++tei)
+ {
+ targets.push_back((*tei)->Target->GetName());
+ }
+ return;
+ }
+ targets = this->Targets;
+}
+
+//----------------------------------------------------------------------------
std::vector<std::string>
cmExportBuildFileGenerator
::FindNamespaces(cmMakefile* mf, const std::string& name)
@@ -246,8 +274,8 @@ cmExportBuildFileGenerator
expIt = exportSets.begin(); expIt != exportSets.end(); ++expIt)
{
const cmExportBuildFileGenerator* exportSet = expIt->second;
- std::vector<std::string> const& targets = exportSet->GetTargets();
-
+ std::vector<std::string> targets;
+ exportSet->GetTargets(targets);
if (std::find(targets.begin(), targets.end(), name) != targets.end())
{
namespaces.push_back(exportSet->GetNamespace());
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 2fbd98f..cea2099 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -15,6 +15,8 @@
#include "cmExportFileGenerator.h"
#include "cmListFileCache.h"
+class cmExportSet;
+
/** \class cmExportBuildFileGenerator
* \brief Generate a file exporting targets from a build tree.
*
@@ -32,11 +34,11 @@ public:
/** Set the list of targets to export. */
void SetTargets(std::vector<std::string> const& targets)
{ this->Targets = targets; }
- std::vector<std::string> const& GetTargets() const
- { return this->Targets; }
+ void GetTargets(std::vector<std::string> &targets) const;
void AppendTargets(std::vector<std::string> const& targets)
{ this->Targets.insert(this->Targets.end(),
targets.begin(), targets.end()); }
+ void SetExportSet(cmExportSet*);
/** Set whether to append generated code to the output file. */
void SetAppendMode(bool append) { this->AppendMode = append; }
@@ -75,6 +77,7 @@ protected:
FindNamespaces(cmMakefile* mf, const std::string& name);
std::vector<std::string> Targets;
+ cmExportSet *ExportSet;
std::vector<cmTarget*> Exports;
cmMakefile* Makefile;
cmListFileBacktrace Backtrace;
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 0a67ccf..b6bf870 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -30,14 +30,12 @@ cmExportCommand::cmExportCommand()
,ArgumentGroup()
,Targets(&Helper, "TARGETS")
,Append(&Helper, "APPEND", &ArgumentGroup)
+,ExportSetName(&Helper, "EXPORT", &ArgumentGroup)
,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
,Filename(&Helper, "FILE", &ArgumentGroup)
,ExportOld(&Helper, "EXPORT_LINK_INTERFACE_LIBRARIES", &ArgumentGroup)
{
- // at first TARGETS
- this->Targets.Follows(0);
- // and after that the other options in any order
- this->ArgumentGroup.Follows(&this->Targets);
+ this->ExportSet = 0;
}
@@ -55,6 +53,16 @@ bool cmExportCommand
{
return this->HandlePackage(args);
}
+ else if (args[0] == "EXPORT")
+ {
+ this->ExportSetName.Follows(0);
+ this->ArgumentGroup.Follows(&this->ExportSetName);
+ }
+ else
+ {
+ this->Targets.Follows(0);
+ this->ArgumentGroup.Follows(&this->Targets);
+ }
std::vector<std::string> unknownArgs;
this->Helper.Parse(&args, &unknownArgs);
@@ -65,31 +73,32 @@ bool cmExportCommand
return false;
}
- if (this->Targets.WasFound() == false)
- {
- this->SetError("TARGETS option missing.");
- return false;
- }
-
+ std::string fname;
if(!this->Filename.WasFound())
{
- this->SetError("FILE <filename> option missing.");
- return false;
+ if (args[0] != "EXPORT")
+ {
+ this->SetError("FILE <filename> option missing.");
+ return false;
+ }
+ fname = this->ExportSetName.GetString() + ".cmake";
}
-
- // Make sure the file has a .cmake extension.
- if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
- != ".cmake")
+ else
{
- 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;
+ // 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;
+ }
+ fname = this->Filename.GetString();
}
// Get the file to write.
- std::string fname = this->Filename.GetString();
if(cmSystemTools::FileIsFullPath(fname.c_str()))
{
if(!this->Makefile->CanIWriteThisFile(fname.c_str()))
@@ -104,57 +113,95 @@ bool cmExportCommand
else
{
// Interpret relative paths with respect to the current build dir.
- fname = this->Makefile->GetCurrentOutputDirectory();
- fname += "/";
- fname += this->Filename.GetString();
+ std::string dir = this->Makefile->GetCurrentOutputDirectory();
+ fname = dir + "/" + fname;
}
- for(std::vector<std::string>::const_iterator
- currentTarget = this->Targets.GetVector().begin();
- currentTarget != this->Targets.GetVector().end();
- ++currentTarget)
+ std::vector<std::string> targets;
+
+ cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator()
+ ->GetGlobalGenerator();
+
+ if(args[0] == "EXPORT")
{
- if (this->Makefile->IsAlias(currentTarget->c_str()))
+ if (this->Append.IsEnabled())
+ {
+ cmOStringStream e;
+ e << "EXPORT signature does not recognise the APPEND option.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+
+ if (this->ExportOld.IsEnabled())
{
cmOStringStream e;
- e << "given ALIAS target \"" << *currentTarget
- << "\" which may not be exported.";
+ e << "EXPORT signature does not recognise the "
+ "EXPORT_LINK_INTERFACE_LIBRARIES option.";
this->SetError(e.str().c_str());
return false;
}
- if(cmTarget* target =
- this->Makefile->GetLocalGenerator()->
- GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
+ cmExportSetMap &setMap = gg->GetExportSets();
+ std::string setName = this->ExportSetName.GetString();
+ if (setMap.find(setName) == setMap.end())
{
- if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ cmOStringStream e;
+ e << "Export set \"" << setName << "\" not found.";
+ this->SetError(e.str().c_str());
+ return false;
+ }
+ this->ExportSet = setMap[setName];
+ }
+ else if (this->Targets.WasFound())
+ {
+ for(std::vector<std::string>::const_iterator
+ currentTarget = this->Targets.GetVector().begin();
+ currentTarget != this->Targets.GetVector().end();
+ ++currentTarget)
+ {
+ if (this->Makefile->IsAlias(currentTarget->c_str()))
{
cmOStringStream e;
- e << "given OBJECT library \"" << *currentTarget
+ e << "given ALIAS target \"" << *currentTarget
<< "\" which may not be exported.";
this->SetError(e.str().c_str());
return false;
}
+
+ if(cmTarget* target = gg->FindTarget(0, currentTarget->c_str()))
+ {
+ if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ {
+ cmOStringStream e;
+ e << "given OBJECT library \"" << *currentTarget
+ << "\" which may not be exported.";
+ 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;
+ }
+ targets.push_back(*currentTarget);
}
- else
+ if (this->Append.IsEnabled())
{
- cmOStringStream e;
- e << "given target \"" << *currentTarget
- << "\" which is not built by this project.";
- this->SetError(e.str().c_str());
- return false;
+ if (cmExportBuildFileGenerator *ebfg = gg->GetExportedTargetsFile(fname))
+ {
+ ebfg->AppendTargets(targets);
+ return true;
+ }
}
}
-
- cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator();
- if (this->Append.IsEnabled())
+ else
{
- if (cmExportBuildFileGenerator *ebfg = gg->GetExportedTargetsFile(fname))
- {
- ebfg->AppendTargets(this->Targets.GetVector());
- return true;
- }
+ this->SetError("EXPORT or TARGETS specifier missing.");
+ return false;
}
// Setup export file generation.
@@ -162,7 +209,14 @@ bool cmExportCommand
ebfg->SetExportFile(fname.c_str());
ebfg->SetNamespace(this->Namespace.GetCString());
ebfg->SetAppendMode(this->Append.IsEnabled());
- ebfg->SetTargets(this->Targets.GetVector());
+ if (this->ExportSet)
+ {
+ ebfg->SetExportSet(this->ExportSet);
+ }
+ else
+ {
+ ebfg->SetTargets(targets);
+ }
ebfg->SetMakefile(this->Makefile);
ebfg->SetExportOld(this->ExportOld.IsEnabled());
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index ea7c3a3..c0e445f 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -15,6 +15,7 @@
#include "cmCommand.h"
class cmExportBuildFileGenerator;
+class cmExportSet;
/** \class cmExportLibraryDependenciesCommand
* \brief Add a test to the lists of tests to run.
@@ -52,10 +53,13 @@ private:
cmCommandArgumentGroup ArgumentGroup;
cmCAStringVector Targets;
cmCAEnabler Append;
+ cmCAString ExportSetName;
cmCAString Namespace;
cmCAString Filename;
cmCAEnabler ExportOld;
+ cmExportSet *ExportSet;
+
friend class cmExportBuildFileGenerator;
std::string ErrorMessage;