From 4224513ccee04d540e89db5cf1ca531b6ef8e0e5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Sep 2009 10:11:43 -0400 Subject: Save source dependencies from custom command trace In each target we trace dependencies among custom commands to pull in all source files and build rules necessary to complete the target. This commit teaches cmTarget to save the inter-source dependencies found during its analysis. Later this can be used by generators that need to topologically order custom command rules. --- Source/cmTarget.cxx | 46 +++++++++++++++++++++++++++++++++++++++++----- Source/cmTarget.h | 5 ++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 22b49ef..3882253 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -88,6 +88,10 @@ public: typedef std::map LinkClosureMapType; LinkClosureMapType LinkClosureMap; + + struct SourceEntry { std::vector Depends; }; + typedef std::map SourceEntriesType; + SourceEntriesType SourceEntries; }; //---------------------------------------------------------------------------- @@ -1081,12 +1085,16 @@ bool cmTarget::IsAppBundleOnApple() class cmTargetTraceDependencies { public: - cmTargetTraceDependencies(cmTarget* target, const char* vsProjectFile); + cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal, + const char* vsProjectFile); void Trace(); private: cmTarget* Target; + cmTargetInternals* Internal; cmMakefile* Makefile; cmGlobalGenerator* GlobalGenerator; + typedef cmTargetInternals::SourceEntry SourceEntry; + SourceEntry* CurrentEntry; std::queue SourceQueue; std::set SourcesQueued; typedef std::map NameMapType; @@ -1102,13 +1110,15 @@ private: //---------------------------------------------------------------------------- cmTargetTraceDependencies -::cmTargetTraceDependencies(cmTarget* target, const char* vsProjectFile): - Target(target) +::cmTargetTraceDependencies(cmTarget* target, cmTargetInternals* internal, + const char* vsProjectFile): + Target(target), Internal(internal) { // Convenience. this->Makefile = this->Target->GetMakefile(); this->GlobalGenerator = this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); + this->CurrentEntry = 0; // Queue all the source files already specified for the target. std::vector const& sources = this->Target->GetSourceFiles(); @@ -1140,6 +1150,7 @@ void cmTargetTraceDependencies::Trace() // Get the next source from the queue. cmSourceFile* sf = this->SourceQueue.front(); this->SourceQueue.pop(); + this->CurrentEntry = &this->Internal->SourceEntries[sf]; // Queue dependencies added explicitly by the user. if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) @@ -1161,6 +1172,7 @@ void cmTargetTraceDependencies::Trace() this->CheckCustomCommand(*cc); } } + this->CurrentEntry = 0; } //---------------------------------------------------------------------------- @@ -1188,6 +1200,12 @@ void cmTargetTraceDependencies::FollowName(std::string const& name) } if(cmSourceFile* sf = i->second) { + // Record the dependency we just followed. + if(this->CurrentEntry) + { + this->CurrentEntry->Depends.push_back(sf); + } + this->QueueSource(sf); } } @@ -1308,7 +1326,7 @@ cmTargetTraceDependencies void cmTarget::TraceDependencies(const char* vsProjectFile) { // Use a helper object to trace the dependencies. - cmTargetTraceDependencies tracer(this, vsProjectFile); + cmTargetTraceDependencies tracer(this, this->Internal.Get(), vsProjectFile); tracer.Trace(); } @@ -1336,13 +1354,31 @@ std::vector const& cmTarget::GetSourceFiles() //---------------------------------------------------------------------------- void cmTarget::AddSourceFile(cmSourceFile* sf) { - if(this->SourceFileSet.insert(sf).second) + typedef cmTargetInternals::SourceEntriesType SourceEntriesType; + SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf); + if(i == this->Internal->SourceEntries.end()) { + typedef cmTargetInternals::SourceEntry SourceEntry; + SourceEntriesType::value_type entry(sf, SourceEntry()); + i = this->Internal->SourceEntries.insert(entry).first; this->SourceFiles.push_back(sf); } } //---------------------------------------------------------------------------- +std::vector const* +cmTarget::GetSourceDepends(cmSourceFile* sf) +{ + typedef cmTargetInternals::SourceEntriesType SourceEntriesType; + SourceEntriesType::iterator i = this->Internal->SourceEntries.find(sf); + if(i != this->Internal->SourceEntries.end()) + { + return &i->second.Depends; + } + return 0; +} + +//---------------------------------------------------------------------------- void cmTarget::AddSources(std::vector const& srcs) { for(std::vector::const_iterator i = srcs.begin(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 5054f2d..66cfab0 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -48,6 +48,7 @@ public: ~cmTargetInternalPointer(); cmTargetInternalPointer& operator=(cmTargetInternalPointer const& r); cmTargetInternals* operator->() const { return this->Pointer; } + cmTargetInternals* Get() const { return this->Pointer; } private: cmTargetInternals* Pointer; }; @@ -122,6 +123,9 @@ public: std::vector const& GetSourceFiles(); void AddSourceFile(cmSourceFile* sf); + /** Get sources that must be built before the given source. */ + std::vector const* GetSourceDepends(cmSourceFile* sf); + /** * Flags for a given source file as used in this target. Typically assigned * via SET_TARGET_PROPERTIES when the property is a list of source files. @@ -530,7 +534,6 @@ private: std::vector PostBuildCommands; TargetType TargetTypeValue; std::vector SourceFiles; - std::set SourceFileSet; LinkLibraryVectorType LinkLibraries; LinkLibraryVectorType PrevLinkedLibraries; bool LinkLibrariesAnalyzed; -- cgit v0.12