From 3baaf6ccecb9117b613fc89cd37206960298dfaa Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 7 Mar 2012 14:01:46 -0500 Subject: [PATCH] Pre-compute object file names before Makefile generation Add a virtual cmGlobalGenerator::ComputeTargetObjects method invoked during cmGeneratorTarget construction. Implement it in the Makefile generator to pre-compute all object file names for each target. Use the results during generation instead of re-computing it later. --- Source/cmGeneratorTarget.h | 2 ++ Source/cmGlobalGenerator.cxx | 10 +++++- Source/cmGlobalGenerator.h | 1 + Source/cmGlobalUnixMakefileGenerator3.cxx | 32 +++++++++++++++++++ Source/cmGlobalUnixMakefileGenerator3.h | 2 ++ Source/cmLocalUnixMakefileGenerator3.cxx | 39 ----------------------- Source/cmLocalUnixMakefileGenerator3.h | 5 --- Source/cmMakefileTargetGenerator.cxx | 14 +++----- 8 files changed, 50 insertions(+), 55 deletions(-) diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index d93b052bc..976cac4f4 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -40,6 +40,8 @@ public: std::vector OSXContent; std::string ModuleDefinitionFile; + std::map Objects; + private: void ClassifySources(); diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index a1f80d934..d7ba8b6fb 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1074,7 +1074,9 @@ void cmGlobalGenerator::CreateGeneratorTargets() ti != targets.end(); ++ti) { cmTarget* t = &ti->second; - this->GeneratorTargets[t] = new cmGeneratorTarget(t); + cmGeneratorTarget* gt = new cmGeneratorTarget(t); + this->GeneratorTargets[t] = gt; + this->ComputeTargetObjects(gt); } } } @@ -1104,6 +1106,12 @@ cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const return ti->second; } +//---------------------------------------------------------------------------- +void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const +{ + // Implemented in generator subclasses that need this. +} + void cmGlobalGenerator::CheckLocalGenerators() { std::map notFoundMap; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index b94cc6c57..e818e37e9 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -379,6 +379,7 @@ private: GeneratorTargetsType GeneratorTargets; void CreateGeneratorTargets(); void ClearGeneratorTargets(); + virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; // Cache directory content and target files to be built. struct DirectoryContent: public std::set diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index a23c0d8d3..059692ed1 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -17,6 +17,7 @@ #include "cmGeneratedFileStream.h" #include "cmSourceFile.h" #include "cmTarget.h" +#include "cmGeneratorTarget.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() { @@ -70,6 +71,37 @@ void cmGlobalUnixMakefileGenerator3 "default make target. A \"make install\" target is also provided."; } +//---------------------------------------------------------------------------- +void +cmGlobalUnixMakefileGenerator3 +::ComputeTargetObjects(cmGeneratorTarget* gt) const +{ + cmTarget* target = gt->Target; + cmLocalUnixMakefileGenerator3* lg = + static_cast(gt->LocalGenerator); + + // Compute full path to object file directory for this target. + std::string dir_max; + dir_max += gt->Makefile->GetCurrentOutputDirectory(); + dir_max += "/"; + dir_max += gt->LocalGenerator->GetTargetDirectory(*target); + dir_max += "/"; + + // Compute the name of each object file. + for(std::vector::iterator + si = gt->ObjectSources.begin(); + si != gt->ObjectSources.end(); ++si) + { + cmSourceFile* sf = *si; + bool hasSourceExtension = true; + std::string objectName = gt->LocalGenerator + ->GetObjectFileNameWithoutTarget(*sf, dir_max, + &hasSourceExtension); + gt->Objects[sf] = objectName; + lg->AddLocalObjectFile(target, sf, objectName, hasSourceExtension); + } +} + //---------------------------------------------------------------------------- std::string EscapeJSON(const std::string& s) { std::string result; diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 9663b5592..e6dd09d6d 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -182,6 +182,8 @@ protected: size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg); cmGeneratedFileStream *CommandDatabase; +private: + virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const; }; #endif diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index fdf59b24c..b991b2538 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -2008,45 +2008,6 @@ void cmLocalUnixMakefileGenerator3 } } -//---------------------------------------------------------------------------- -std::string -cmLocalUnixMakefileGenerator3 -::GetObjectFileName(cmTarget& target, - const cmSourceFile& source, - std::string* nameWithoutTargetDir, - bool* hasSourceExtension) -{ - // Make sure we never hit this old case. - if(source.GetProperty("MACOSX_PACKAGE_LOCATION")) - { - std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: "; - msg += source.GetFullPath(); - this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR, - msg.c_str()); - } - - // Start with the target directory. - std::string obj = this->GetTargetDirectory(target); - obj += "/"; - - // Get the object file name without the target directory. - std::string dir_max; - dir_max += this->Makefile->GetCurrentOutputDirectory(); - dir_max += "/"; - dir_max += obj; - std::string objectName = - this->GetObjectFileNameWithoutTarget(source, dir_max, - hasSourceExtension); - if(nameWithoutTargetDir) - { - *nameWithoutTargetDir = objectName; - } - - // Append the object name to the target directory. - obj += objectName; - return obj; -} - //---------------------------------------------------------------------------- void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os) { diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 4bde0825b..e3749590b 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -284,11 +284,6 @@ protected: cmTarget& target, const std::vector& objects); - std::string GetObjectFileName(cmTarget& target, - const cmSourceFile& source, - std::string* nameWithoutTargetDir = 0, - bool* hasSourceExtension = 0); - void AppendRuleDepend(std::vector& depends, const char* ruleFileName); void AppendRuleDepends(std::vector& depends, diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index b374bb6ee..fc55f1e94 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -418,12 +418,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) } // Get the full path name of the object file. - bool hasSourceExtension; - std::string objNoTargetDir; - std::string obj = - this->LocalGenerator->GetObjectFileName(*this->Target, source, - &objNoTargetDir, - &hasSourceExtension); + std::string const& objectName = this->GeneratorTarget->Objects[&source]; + std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target); + obj += "/"; + obj += objectName; // Avoid generating duplicate rules. if(this->ObjectFiles.find(obj) == this->ObjectFiles.end()) @@ -477,10 +475,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source) AddImplicitDepends(*this->Target, lang, objFullPath.c_str(), srcFullPath.c_str()); - - // add this to the list of objects for this local generator - this->LocalGenerator->AddLocalObjectFile( - this->Target, &source, objNoTargetDir, hasSourceExtension); } //----------------------------------------------------------------------------