cmGeneratorTarget: Compute target objects on demand

Add a ComputeObjectMapping method to compute the object
names.  It takes mapping to populate as an out-parameter so
that it can be extended in the future with parameters
relevant to generator expression evaluation.

Remove the supporting cmGeneratorTarget::AddObject method. It is
no longer needed as the container member is populated directly.

The ComputeObjectMapping method is called whenever objects are
requested from the cmGeneratorTarget.  Because the Xcode generator
makes no such request, explicitly invoke the method from that
generator so that the logic of checking for bad sources in object
libraries is executed.

In a follow-up, the UseObjectLibraries usage may be replaced by a
true generator expression evaluator for TARGET_OBJECTS. That
will require generators to use cmGeneratorTarget::GetExternalObjects
which is not currently the case for Xcode and VS generators.
This commit is contained in:
Stephen Kelly 2014-03-14 13:21:26 +01:00
parent 042c1c834e
commit aa0a3562dd
5 changed files with 30 additions and 56 deletions

View File

@ -311,20 +311,38 @@ cmGeneratorTarget
::GetObjectSources(std::vector<cmSourceFile const*> &data) const ::GetObjectSources(std::vector<cmSourceFile const*> &data) const
{ {
IMPLEMENT_VISIT(ObjectSources); IMPLEMENT_VISIT(ObjectSources);
if (!this->Objects.empty())
{
return;
}
for(std::vector<cmSourceFile const*>::const_iterator it = data.begin();
it != data.end(); ++it)
{
this->Objects[*it];
}
this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
}
void cmGeneratorTarget::ComputeObjectMapping()
{
if(!this->Objects.empty())
{
return;
}
std::vector<cmSourceFile const*> sourceFiles;
this->GetObjectSources(sourceFiles);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file) const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
{ {
this->ComputeObjectMapping();
return this->Objects[file]; return this->Objects[file];
} }
void cmGeneratorTarget::AddObject(cmSourceFile const* sf,
std::string const&name)
{
this->Objects[sf] = name;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf) void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
{ {
@ -334,6 +352,7 @@ void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
{ {
const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
std::set<cmSourceFile const*>::const_iterator it std::set<cmSourceFile const*>::const_iterator it
= this->ExplicitObjectName.find(file); = this->ExplicitObjectName.find(file);
return it != this->ExplicitObjectName.end(); return it != this->ExplicitObjectName.end();

View File

@ -35,7 +35,6 @@ public:
void GetObjectSources(std::vector<cmSourceFile const*> &) const; void GetObjectSources(std::vector<cmSourceFile const*> &) const;
const std::string& GetObjectName(cmSourceFile const* file); const std::string& GetObjectName(cmSourceFile const* file);
void AddObject(cmSourceFile const* sf, std::string const&name);
bool HasExplicitObjectName(cmSourceFile const* file) const; bool HasExplicitObjectName(cmSourceFile const* file) const;
void AddExplicitObjectName(cmSourceFile const* sf); void AddExplicitObjectName(cmSourceFile const* sf);
@ -47,6 +46,8 @@ public:
void GetCustomCommands(std::vector<cmSourceFile const*>&) const; void GetCustomCommands(std::vector<cmSourceFile const*>&) const;
void GetExpectedResxHeaders(std::set<std::string>&) const; void GetExpectedResxHeaders(std::set<std::string>&) const;
void ComputeObjectMapping();
cmTarget* Target; cmTarget* Target;
cmMakefile* Makefile; cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator; cmLocalGenerator* LocalGenerator;
@ -123,7 +124,7 @@ private:
typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType; typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
SourceEntriesType SourceEntries; SourceEntriesType SourceEntries;
std::map<cmSourceFile const*, std::string> Objects; mutable std::map<cmSourceFile const*, std::string> Objects;
std::set<cmSourceFile const*> ExplicitObjectName; std::set<cmSourceFile const*> ExplicitObjectName;
mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache; mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;

View File

@ -1222,8 +1222,6 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->GenerateTargetManifest(); this->LocalGenerators[i]->GenerateTargetManifest();
} }
this->ComputeGeneratorTargetObjects();
this->ProcessEvaluationFiles(); this->ProcessEvaluationFiles();
// Compute the inter-target dependencies. // Compute the inter-target dependencies.
@ -1440,27 +1438,6 @@ void cmGlobalGenerator::CreateGeneratorTargets()
} }
} }
//----------------------------------------------------------------------------
void cmGlobalGenerator::ComputeGeneratorTargetObjects()
{
// Construct per-target generator information.
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
{
cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
cmGeneratorTargetsType targets = mf->GetGeneratorTargets();
for(cmGeneratorTargetsType::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
if (ti->second->Target->IsImported()
|| ti->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
cmGeneratorTarget* gt = ti->second;
this->ComputeTargetObjects(gt);
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGlobalGenerator::ClearGeneratorMembers() void cmGlobalGenerator::ClearGeneratorMembers()
@ -1521,29 +1498,6 @@ cmGlobalGenerator::GetGeneratorTarget(cmTarget const* t) const
return ti->second; return ti->second;
} }
//----------------------------------------------------------------------------
void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
{
std::vector<cmSourceFile const*> objectSources;
gt->GetObjectSources(objectSources);
std::map<cmSourceFile const*, std::string> mapping;
for(std::vector<cmSourceFile const*>::const_iterator it
= objectSources.begin(); it != objectSources.end(); ++it)
{
mapping[*it];
}
gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
for(std::map<cmSourceFile const*, std::string>::const_iterator it
= mapping.begin(); it != mapping.end(); ++it)
{
assert(!it->second.empty());
gt->AddObject(it->first, it->second);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
{ {

View File

@ -444,8 +444,6 @@ private:
friend class cmake; friend class cmake;
void CreateGeneratorTargets(cmMakefile* mf); void CreateGeneratorTargets(cmMakefile* mf);
void CreateGeneratorTargets(); void CreateGeneratorTargets();
void ComputeGeneratorTargetObjects();
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
void ClearGeneratorMembers(); void ClearGeneratorMembers();

View File

@ -987,6 +987,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
cmtarget.GetSourceFiles(classes); cmtarget.GetSourceFiles(classes);
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare()); std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
gtgt->ComputeObjectMapping();
std::vector<cmXCodeObject*> externalObjFiles; std::vector<cmXCodeObject*> externalObjFiles;
std::vector<cmXCodeObject*> headerFiles; std::vector<cmXCodeObject*> headerFiles;
std::vector<cmXCodeObject*> resourceFiles; std::vector<cmXCodeObject*> resourceFiles;