exports: move the handling of missing targets into subclasses

Before, cmExportFileGenerator::ComplainAboutMissingTarget() was a virtual
function which had to be implemented in the subclasses. It is not
anymore. Instead, there is now a virtual function
HandleMissingTargets(), which is implemented in the two subclasses.
This makes e.g. dealing correctly with APPEND mode easier.

Alex
This commit is contained in:
Alex Neundorf 2012-09-28 21:47:37 +02:00 committed by Brad King
parent 190f2c8253
commit 0cfd055acd
6 changed files with 124 additions and 98 deletions

View File

@ -133,12 +133,30 @@ cmExportBuildFileGenerator
}
}
//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator::HandleMissingTarget(
std::string& link_libs, std::vector<std::string>&,
cmMakefile*, 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);
}
// Assume the target will be exported by another command.
// Append it with the export namespace.
link_libs += this->Namespace;
link_libs += dependee->GetName();
}
//----------------------------------------------------------------------------
void
cmExportBuildFileGenerator
::ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee,
int occurrences)
cmTarget* dependee)
{
if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty())
{
@ -146,20 +164,10 @@ cmExportBuildFileGenerator
}
cmOStringStream e;
if (occurrences == 0)
{
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, "
<< "consider using the APPEND option with multiple separate calls.";
}
else
{
e << "called with target \"" << depender->GetName()
<< "\" which requires target \"" << dependee->GetName()
<< "\" that is exported " << occurrences << " times in other "
<< "export ""lists.\n";
}
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, "
<< "consider using the APPEND option with multiple separate calls.";
this->ExportCommand->ErrorMessage = e.str();
}

View File

@ -45,9 +45,14 @@ protected:
virtual void GenerateImportTargetsConfig(std::ostream& os,
const char* config,
std::string const& suffix);
virtual void ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee,
int occurrences);
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
cmMakefile* mf,
cmTarget* depender,
cmTarget* dependee);
void ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee);
/** Fill in properties indicating built file locations. */
void SetImportLocationProperty(const char* config,

View File

@ -233,30 +233,7 @@ cmExportFileGenerator
}
else
{
std::vector<std::string> namespaces = this->FindNamespaces(mf, *li);
int targetOccurrences = (int)namespaces.size();
if (targetOccurrences == 1)
{
std::string missingTarget = namespaces[0];
missingTarget += *li;
link_libs += missingTarget;
missingTargets.push_back(missingTarget);
}
else
{
// 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(target, tgt, targetOccurrences);
}
// Assume the target will be exported by another command.
// Append it with the export namespace.
link_libs += this->Namespace;
link_libs += *li;
}
this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
}
}
else
@ -273,47 +250,6 @@ cmExportFileGenerator
}
//----------------------------------------------------------------------------
std::vector<std::string> cmExportFileGenerator::FindNamespaces(cmMakefile* mf,
const std::string& name)
{
std::vector<std::string> namespaces;
cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator();
const cmExportSetMap& exportSets = gg->GetExportSets();
for(cmExportSetMap::const_iterator expIt = exportSets.begin();
expIt != exportSets.end();
++expIt)
{
const cmExportSet* exportSet = expIt->second;
std::vector<cmTargetExport*> const* targets =
exportSet->GetTargetExports();
bool containsTarget = false;
for(unsigned int i=0; i<targets->size(); i++)
{
if (name == (*targets)[i]->Target->GetName())
{
containsTarget = true;
break;
}
}
if (containsTarget)
{
std::vector<cmInstallExportGenerator const*> const* installs =
exportSet->GetInstallations();
for(unsigned int i=0; i<installs->size(); i++)
{
namespaces.push_back((*installs)[i]->GetNamespace());
}
}
}
return namespaces;
}
//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
const char* config)

View File

@ -84,15 +84,13 @@ protected:
const char* config,
std::string const& suffix) = 0;
/** Each subclass knows how to complain about a target that is
missing from an export set. */
virtual void ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee,
int occurrences) = 0;
std::vector<std::string> FindNamespaces(cmMakefile* mf,
const std::string& name);
/** Each subclass knows how to deal with a target that is missing from an
* export set. */
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
cmMakefile* mf,
cmTarget* depender,
cmTarget* dependee) = 0;
// The namespace in which the exports are placed in the generated file.
std::string Namespace;

View File

@ -11,11 +11,14 @@
============================================================================*/
#include "cmExportInstallFileGenerator.h"
#include "cmExportSet.h"
#include "cmExportSetMap.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmTargetExport.h"
#include "cmExportSet.h"
//----------------------------------------------------------------------------
cmExportInstallFileGenerator
@ -309,6 +312,72 @@ cmExportInstallFileGenerator
}
}
//----------------------------------------------------------------------------
void
cmExportInstallFileGenerator::HandleMissingTarget(
std::string& link_libs, std::vector<std::string>& missingTargets,
cmMakefile* mf, cmTarget* depender, cmTarget* dependee)
{
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 += name;
link_libs += missingTarget;
missingTargets.push_back(missingTarget);
}
else
{
// We are not appending, so all exported targets should be
// known here. This is probably user-error.
this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences);
}
}
//----------------------------------------------------------------------------
std::vector<std::string>
cmExportInstallFileGenerator
::FindNamespaces(cmMakefile* mf, const std::string& name)
{
std::vector<std::string> namespaces;
cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator();
const cmExportSetMap& exportSets = gg->GetExportSets();
for(cmExportSetMap::const_iterator expIt = exportSets.begin();
expIt != exportSets.end();
++expIt)
{
const cmExportSet* exportSet = expIt->second;
std::vector<cmTargetExport*> const* targets =
exportSet->GetTargetExports();
bool containsTarget = false;
for(unsigned int i=0; i<targets->size(); i++)
{
if (name == (*targets)[i]->Target->GetName())
{
containsTarget = true;
break;
}
}
if (containsTarget)
{
std::vector<cmInstallExportGenerator const*> const* installs =
exportSet->GetInstallations();
for(unsigned int i=0; i<installs->size(); i++)
{
namespaces.push_back((*installs)[i]->GetNamespace());
}
}
}
return namespaces;
}
//----------------------------------------------------------------------------
void
cmExportInstallFileGenerator

View File

@ -57,9 +57,19 @@ protected:
virtual void GenerateImportTargetsConfig(std::ostream& os,
const char* config,
std::string const& suffix);
virtual void ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee,
int occurrences);
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
cmMakefile* mf,
cmTarget* depender,
cmTarget* dependee);
void ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee,
int occurrences);
std::vector<std::string> FindNamespaces(cmMakefile* mf,
const std::string& name);
/** Generate a per-configuration file for the targets. */
bool GenerateImportFileConfig(const char* config);