summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2013-10-15 13:32:36 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2013-10-15 13:32:36 (GMT)
commit06491955ebe566e025b25abaa91977824811e282 (patch)
treec835e87d2cfc40b88617921c0738a8fe42af502f /Source
parentebffbda4476aae1e89029f2e24fd76a22765205a (diff)
parenta4263c9f6447e526886d6af301b84c9097c097fa (diff)
downloadCMake-06491955ebe566e025b25abaa91977824811e282.zip
CMake-06491955ebe566e025b25abaa91977824811e282.tar.gz
CMake-06491955ebe566e025b25abaa91977824811e282.tar.bz2
Merge topic 'export-at-generate-time'
a4263c9 export(): Handle multiple dependent export sets. 66b290e export(): Process the export() command at generate time. 5fe5c32 export(): Set a Makefile on the cmExportBuildFileGenerator. e383555 cmExportInstallFileGenerator: Fix comment to match reality.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmExportBuildFileGenerator.cxx115
-rw-r--r--Source/cmExportBuildFileGenerator.h31
-rw-r--r--Source/cmExportCommand.cxx71
-rw-r--r--Source/cmExportCommand.h4
-rw-r--r--Source/cmExportFileGenerator.cxx6
-rw-r--r--Source/cmExportFileGenerator.h2
-rw-r--r--Source/cmExportInstallFileGenerator.cxx4
-rw-r--r--Source/cmGlobalGenerator.cxx56
-rw-r--r--Source/cmGlobalGenerator.h22
-rw-r--r--Source/cmIncludeCommand.cxx1
10 files changed, 205 insertions, 107 deletions
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 243e5ce..50835e2 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -11,40 +11,38 @@
============================================================================*/
#include "cmExportBuildFileGenerator.h"
-#include "cmExportCommand.h"
+#include "cmLocalGenerator.h"
+#include "cmGlobalGenerator.h"
//----------------------------------------------------------------------------
cmExportBuildFileGenerator::cmExportBuildFileGenerator()
{
- this->ExportCommand = 0;
+ this->Makefile = 0;
}
//----------------------------------------------------------------------------
bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
{
- std::vector<cmTarget*> allTargets;
{
std::string expectedTargets;
std::string sep;
- for(std::vector<cmTarget*>::const_iterator
- tei = this->Exports->begin();
- tei != this->Exports->end(); ++tei)
+ for(std::vector<std::string>::const_iterator
+ tei = this->Targets.begin();
+ tei != this->Targets.end(); ++tei)
{
- expectedTargets += sep + this->Namespace + (*tei)->GetExportName();
+ cmTarget *te = this->Makefile->FindTargetToUse(tei->c_str());
+ expectedTargets += sep + this->Namespace + te->GetExportName();
sep = " ";
- cmTarget* te = *tei;
if(this->ExportedTargets.insert(te).second)
{
- allTargets.push_back(te);
+ this->Exports.push_back(te);
}
else
{
- if(this->ExportCommand && this->ExportCommand->ErrorMessage.empty())
- {
- cmOStringStream e;
- e << "given target \"" << te->GetName() << "\" more than once.";
- this->ExportCommand->ErrorMessage = e.str();
- }
+ cmOStringStream e;
+ e << "given target \"" << te->GetName() << "\" more than once.";
+ this->Makefile->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), this->Backtrace);
return false;
}
if (te->GetType() == cmTarget::INTERFACE_LIBRARY)
@@ -60,8 +58,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
// Create all the imported targets.
for(std::vector<cmTarget*>::const_iterator
- tei = allTargets.begin();
- tei != allTargets.end(); ++tei)
+ tei = this->Exports.begin();
+ tei != this->Exports.end(); ++tei)
{
cmTarget* te = *tei;
this->GenerateImportTargetCode(os, te);
@@ -116,8 +114,8 @@ cmExportBuildFileGenerator
std::vector<std::string> &missingTargets)
{
for(std::vector<cmTarget*>::const_iterator
- tei = this->Exports->begin();
- tei != this->Exports->end(); ++tei)
+ tei = this->Exports.begin();
+ tei != this->Exports.end(); ++tei)
{
// Collect import properties for this target.
cmTarget* target = *tei;
@@ -198,40 +196,95 @@ cmExportBuildFileGenerator
//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator::HandleMissingTarget(
- std::string& link_libs, std::vector<std::string>&,
- cmMakefile*, cmTarget* depender, cmTarget* dependee)
+ std::string& link_libs, std::vector<std::string>& missingTargets,
+ cmMakefile* mf, cmTarget* depender, cmTarget* dependee)
{
// The target is not in the export.
if(!this->AppendMode)
{
- // We are not appending, so all exported targets should be
- // known here. This is probably user-error.
- this->ComplainAboutMissingTarget(depender, dependee);
+ const std::string name = dependee->GetName();
+ std::vector<std::string> namespaces = this->FindNamespaces(mf, name);
+
+ int targetOccurrences = (int)namespaces.size();
+ if (targetOccurrences == 1)
+ {
+ std::string missingTarget = namespaces[0];
+
+ missingTarget += dependee->GetExportName();
+ link_libs += missingTarget;
+ missingTargets.push_back(missingTarget);
+ return;
+ }
+ else
+ {
+ // We are not appending, so all exported targets should be
+ // known here. This is probably user-error.
+ this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
+ }
}
// Assume the target will be exported by another command.
// Append it with the export namespace.
link_libs += this->Namespace;
link_libs += dependee->GetExportName();
+// if generate time {}
+}
+
+
+//----------------------------------------------------------------------------
+std::vector<std::string>
+cmExportBuildFileGenerator
+::FindNamespaces(cmMakefile* mf, const std::string& name)
+{
+ std::vector<std::string> namespaces;
+ cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator();
+
+ std::map<std::string, cmExportBuildFileGenerator*>& exportSets
+ = gg->GetBuildExportSets();
+
+ for(std::map<std::string, cmExportBuildFileGenerator*>::const_iterator
+ expIt = exportSets.begin(); expIt != exportSets.end(); ++expIt)
+ {
+ const cmExportBuildFileGenerator* exportSet = expIt->second;
+ std::vector<std::string> const& targets = exportSet->GetTargets();
+
+ if (std::find(targets.begin(), targets.end(), name) != targets.end())
+ {
+ namespaces.push_back(exportSet->GetNamespace());
+ }
+ }
+
+ return namespaces;
}
//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator
::ComplainAboutMissingTarget(cmTarget* depender,
- cmTarget* dependee)
+ cmTarget* dependee,
+ int occurrences)
{
- if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty())
+ if(cmSystemTools::GetErrorOccuredFlag())
{
return;
}
cmOStringStream e;
- e << "called with target \"" << depender->GetName()
- << "\" which requires target \"" << dependee->GetName()
- << "\" that is not in the export list.\n"
- << "If the required target is not easy to reference in this call, "
+ e << "export called with target \"" << depender->GetName()
+ << "\" which requires target \"" << dependee->GetName() << "\" ";
+ if (occurrences == 0)
+ {
+ e << "that is not in the export set.\n";
+ }
+ else
+ {
+ e << "that is not in this export set, but " << occurrences
+ << " times in others.\n";
+ }
+ e << "If the required target is not easy to reference in this call, "
<< "consider using the APPEND option with multiple separate calls.";
- this->ExportCommand->ErrorMessage = e.str();
+
+ this->Makefile->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), this->Backtrace);
}
std::string
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 3ffdf8b..2fbd98f 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -13,8 +13,7 @@
#define cmExportBuildFileGenerator_h
#include "cmExportFileGenerator.h"
-
-class cmExportCommand;
+#include "cmListFileCache.h"
/** \class cmExportBuildFileGenerator
* \brief Generate a file exporting targets from a build tree.
@@ -31,14 +30,22 @@ public:
cmExportBuildFileGenerator();
/** Set the list of targets to export. */
- void SetExports(std::vector<cmTarget*> const* exports)
- { this->Exports = exports; }
+ void SetTargets(std::vector<std::string> const& targets)
+ { this->Targets = targets; }
+ std::vector<std::string> const& GetTargets() const
+ { return this->Targets; }
+ void AppendTargets(std::vector<std::string> const& targets)
+ { this->Targets.insert(this->Targets.end(),
+ targets.begin(), targets.end()); }
/** Set whether to append generated code to the output file. */
void SetAppendMode(bool append) { this->AppendMode = append; }
- /** Set the command instance through which errors should be reported. */
- void SetCommand(cmExportCommand* cmd) { this->ExportCommand = cmd; }
+ void SetMakefile(cmMakefile *mf) {
+ this->Makefile = mf;
+ this->Makefile->GetBacktrace(this->Backtrace);
+ }
+
protected:
// Implement virtual methods from the superclass.
virtual bool GenerateMainFile(std::ostream& os);
@@ -53,7 +60,8 @@ protected:
cmTarget* dependee);
void ComplainAboutMissingTarget(cmTarget* depender,
- cmTarget* dependee);
+ cmTarget* dependee,
+ int occurrences);
/** Fill in properties indicating built file locations. */
void SetImportLocationProperty(const char* config,
@@ -63,8 +71,13 @@ protected:
std::string InstallNameDir(cmTarget* target, const std::string& config);
- std::vector<cmTarget*> const* Exports;
- cmExportCommand* ExportCommand;
+ std::vector<std::string>
+ FindNamespaces(cmMakefile* mf, const std::string& name);
+
+ std::vector<std::string> Targets;
+ std::vector<cmTarget*> Exports;
+ cmMakefile* Makefile;
+ cmListFileBacktrace Backtrace;
};
#endif
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index f335b8b..86ddc3f 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -108,8 +108,6 @@ bool cmExportCommand
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();
@@ -128,15 +126,7 @@ bool cmExportCommand
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) ||
- (target->GetType() == cmTarget::INTERFACE_LIBRARY))
- {
- targets.push_back(target);
- }
- else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ if(target->GetType() == cmTarget::OBJECT_LIBRARY)
{
cmOStringStream e;
e << "given OBJECT library \"" << *currentTarget
@@ -144,37 +134,28 @@ bool cmExportCommand
this->SetError(e.str().c_str());
return false;
}
- else
- {
- cmOStringStream e;
- e << "given target \"" << *currentTarget
- << "\" which is not an executable or library.";
- this->SetError(e.str().c_str());
- return false;
- }
}
- else
+ }
+
+ cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator()
+ ->GetGlobalGenerator();
+ if (this->Append.IsEnabled())
+ {
+ if (cmExportBuildFileGenerator *ebfg = gg->GetExportedTargetsFile(fname))
{
- cmOStringStream e;
- e << "given target \"" << *currentTarget
- << "\" which is not built by this project.";
- this->SetError(e.str().c_str());
- return false;
+ ebfg->AppendTargets(this->Targets.GetVector());
+ return true;
}
}
// 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);
- ebfg.SetExportOld(this->ExportOld.IsEnabled());
-
- cmGlobalGenerator *gg = this->Makefile->GetLocalGenerator()
- ->GetGlobalGenerator();
- gg->AddExportedTargetsFile(fname);
+ cmExportBuildFileGenerator *ebfg = new cmExportBuildFileGenerator;
+ ebfg->SetExportFile(fname.c_str());
+ ebfg->SetNamespace(this->Namespace.GetCString());
+ ebfg->SetAppendMode(this->Append.IsEnabled());
+ ebfg->SetTargets(this->Targets.GetVector());
+ ebfg->SetMakefile(this->Makefile);
+ ebfg->SetExportOld(this->ExportOld.IsEnabled());
// Compute the set of configurations exported.
std::vector<std::string> configurationTypes;
@@ -185,27 +166,15 @@ bool cmExportCommand
ci = configurationTypes.begin();
ci != configurationTypes.end(); ++ci)
{
- ebfg.AddConfiguration(ci->c_str());
+ ebfg->AddConfiguration(ci->c_str());
}
}
else
{
- ebfg.AddConfiguration("");
+ 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;
- }
+ gg->AddBuildExportSet(ebfg);
return true;
}
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index 87c3452..38e8d9a 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -85,7 +85,9 @@ public:
"should never be installed. "
"See the install(EXPORT) command to export targets from an "
"installation tree."
- CM_LOCATION_UNDEFINED_BEHAVIOR("passing it to this command")
+ "\n"
+ "The properties set on the generated IMPORTED targets will have the "
+ "same values as the final values of the input TARGETS."
"\n"
" export(PACKAGE <name>)\n"
"Store the current build directory in the CMake user package registry "
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 25c5710..b01e499 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -52,6 +52,12 @@ void cmExportFileGenerator::SetExportFile(const char* mainFile)
}
//----------------------------------------------------------------------------
+const char* cmExportFileGenerator::GetMainExportFileName() const
+{
+ return this->MainImportFile.c_str();
+}
+
+//----------------------------------------------------------------------------
bool cmExportFileGenerator::GenerateImportFile()
{
// Open the output file to generate it.
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 9628b96..f3d0807 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -33,9 +33,11 @@ public:
/** Set the full path to the export file to generate. */
void SetExportFile(const char* mainFile);
+ const char *GetMainExportFileName() const;
/** Set the namespace in which to place exported target names. */
void SetNamespace(const char* ns) { this->Namespace = ns; }
+ std::string GetNamespace() const { return this->Namespace; }
void SetExportOld(bool exportOld) { this->ExportOld = exportOld; }
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index c71008e..133944e 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -432,8 +432,8 @@ cmExportInstallFileGenerator::HandleMissingTarget(
}
else
{
- // We are not appending, so all exported targets should be
- // known here. This is probably user-error.
+ // All exported targets should be known here and should be unique.
+ // This is probably user-error.
this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
}
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index eacf85b..fb205be 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -27,6 +27,7 @@
#include "cmGeneratorTarget.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionEvaluationFile.h"
+#include "cmExportBuildFileGenerator.h"
#include <cmsys/Directory.hxx>
@@ -77,6 +78,12 @@ cmGlobalGenerator::~cmGlobalGenerator()
{
delete *li;
}
+ for(std::map<std::string, cmExportBuildFileGenerator*>::iterator
+ i = this->BuildExportSets.begin();
+ i != this->BuildExportSets.end(); ++i)
+ {
+ delete i->second;
+ }
this->LocalGenerators.clear();
if (this->ExtraGenerator)
@@ -183,6 +190,34 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang,
doc.c_str(), cmCacheManager::FILEPATH);
}
+void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
+{
+ this->BuildExportSets[gen->GetMainExportFileName()] = gen;
+}
+
+bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
+{
+ std::map<std::string, cmExportBuildFileGenerator*>::iterator it
+ = this->BuildExportSets.find(file);
+ if (it != this->BuildExportSets.end())
+ {
+ bool result = it->second->GenerateImportFile();
+ delete it->second;
+ it->second = 0;
+ this->BuildExportSets.erase(it);
+ return result;
+ }
+ return false;
+}
+
+bool
+cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
+{
+ const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
+ = this->BuildExportSets.find(filename);
+ return it != this->BuildExportSets.end();
+}
+
// Find the make program for the generator, required for try compiles
void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
{
@@ -966,6 +1001,14 @@ void cmGlobalGenerator::Configure()
}
}
+cmExportBuildFileGenerator*
+cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const
+{
+ std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it
+ = this->BuildExportSets.find(filename);
+ return it == this->BuildExportSets.end() ? 0 : it->second;
+}
+
bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
{
// If the property is not enabled then okay.
@@ -1091,6 +1134,19 @@ void cmGlobalGenerator::Generate()
}
this->SetCurrentLocalGenerator(0);
+ for (std::map<std::string, cmExportBuildFileGenerator*>::iterator
+ it = this->BuildExportSets.begin(); it != this->BuildExportSets.end();
+ ++it)
+ {
+ if (!it->second->GenerateImportFile()
+ && !cmSystemTools::GetErrorOccuredFlag())
+ {
+ this->GetCMakeInstance()
+ ->IssueMessage(cmake::FATAL_ERROR, "Could not write export file.",
+ cmListFileBacktrace());
+ return;
+ }
+ }
// Update rule hashes.
this->CheckRuleHashes();
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index b8860f1..c930b2b 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -31,6 +31,7 @@ class cmExternalMakefileProjectGenerator;
class cmTarget;
class cmInstallTargetGenerator;
class cmInstallFilesGenerator;
+class cmExportBuildFileGenerator;
/** \class cmGlobalGenerator
* \brief Responable for overseeing the generation process for the entire tree
@@ -293,18 +294,13 @@ public:
void ProcessEvaluationFiles();
- void AddExportedTargetsFile(const std::string &filename)
- {
- this->ExportedTargetsFiles.insert(filename);
- }
-
- bool IsExportedTargetsFile(const std::string &filename) const
- {
- const std::set<std::string>::const_iterator it
- = this->ExportedTargetsFiles.find(filename);
- return it != this->ExportedTargetsFiles.end();
- }
-
+ std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets()
+ {return this->BuildExportSets;}
+ void AddBuildExportSet(cmExportBuildFileGenerator*);
+ bool IsExportedTargetsFile(const std::string &filename) const;
+ bool GenerateImportFile(const std::string &file);
+ cmExportBuildFileGenerator*
+ GetExportedTargetsFile(const std::string &filename) const;
protected:
typedef std::vector<cmLocalGenerator*> GeneratorVector;
// for a project collect all its targets by following depend
@@ -356,6 +352,7 @@ protected:
bool InstallTargetEnabled;
// Sets of named target exports
cmExportSetMap ExportSets;
+ std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets;
// Manifest of all targets that will be built for each configuration.
// This is computed just before local generators generate.
@@ -384,7 +381,6 @@ private:
std::map<cmStdString, cmStdString> ExtensionToLanguage;
std::map<cmStdString, int> LanguageToLinkerPreference;
std::map<cmStdString, cmStdString> LanguageToOriginalSharedLibFlags;
- std::set<std::string> ExportedTargetsFiles;
// Record hashes for rules and outputs.
struct RuleHash { char Data[32]; };
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 39d4993..5b93171 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -127,6 +127,7 @@ bool cmIncludeCommand
return false;
}
}
+ gg->GenerateImportFile(fname_abs);
}
std::string fullFilePath;