From 50d058a3a1ed4fbb1a1df29ae9979d8c9812ceef Mon Sep 17 00:00:00 2001 From: Ken Martin Date: Tue, 23 May 2006 09:11:46 -0400 Subject: [PATCH] ENH: always compile progress --- Source/cmGlobalUnixMakefileGenerator3.cxx | 199 +++++++++++++++++++++- Source/cmGlobalUnixMakefileGenerator3.h | 15 ++ Source/cmLocalUnixMakefileGenerator3.cxx | 23 ++- Source/cmLocalUnixMakefileGenerator3.h | 3 + Source/cmMacroCommand.cxx | 21 ++- Source/cmMacroCommand.h | 3 +- Source/cmMakefileTargetGenerator.cxx | 16 ++ Source/cmake.cxx | 7 +- 8 files changed, 269 insertions(+), 18 deletions(-) diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index ecb718c45..4be48c9a3 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -20,6 +20,8 @@ #include "cmMakefile.h" #include "cmake.h" #include "cmGeneratedFileStream.h" +#include "cmSourceFile.h" +#include "cmTarget.h" cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() { @@ -27,6 +29,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3() this->ForceUnixPaths = true; this->FindMakeProgramFile = "CMakeUnixFindMake.cmake"; this->ToolSupportsColor = true; + this->NumberOfSourceFiles = 0; + this->NumberOfSourceFilesWritten = 0; } void cmGlobalUnixMakefileGenerator3 @@ -109,9 +113,83 @@ cmGlobalUnixMakefileGenerator3 this->MultipleOutputPairs.insert(p); } +//---------------------------------------------------------------------------- +int cmGlobalUnixMakefileGenerator3::ShouldAddProgressRule() +{ + // add progress to 100 source files + if ((((this->NumberOfSourceFilesWritten + 1)*100)/this->NumberOfSourceFiles) + -(this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles) + { + this->NumberOfSourceFilesWritten++; + return (this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles; + } + this->NumberOfSourceFilesWritten++; + return 0; +} + +int cmGlobalUnixMakefileGenerator3:: +GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt) +{ + std::map::iterator tgtI = + this->TargetSourceFileCount.find(tgt.GetName()); + if (tgtI != this->TargetSourceFileCount.end()) + { + return tgtI->second; + } + + int result = 0; + + if((tgt.GetType() == cmTarget::EXECUTABLE) || + (tgt.GetType() == cmTarget::STATIC_LIBRARY) || + (tgt.GetType() == cmTarget::SHARED_LIBRARY) || + (tgt.GetType() == cmTarget::MODULE_LIBRARY) ) + { + std::vector& sources = tgt.GetSourceFiles(); + for(std::vector::iterator source = sources.begin(); + source != sources.end(); ++source) + { + if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") && + !(*source)->GetCustomCommand()) + { + if(!this->IgnoreFile((*source)->GetSourceExtension().c_str())) + { + const char* lang = + static_cast + (tgt.GetMakefile()->GetLocalGenerator()) + ->GetSourceFileLanguage(**source); + if(lang) + { + result++; + } + } + } + } + } + this->TargetSourceFileCount[tgt.GetName()] = result; + return result; +} + + //---------------------------------------------------------------------------- void cmGlobalUnixMakefileGenerator3::Generate() { + // initialize progress + this->NumberOfSourceFiles = 0; + unsigned int i; + for (i = 0; i < this->LocalGenerators.size(); ++i) + { + // for all of out targets + for (cmTargets::iterator l = + this->LocalGenerators[i]->GetMakefile()->GetTargets().begin(); + l != this->LocalGenerators[i]->GetMakefile()->GetTargets().end(); + l++) + { + this->NumberOfSourceFiles += + this->GetNumberOfCompilableSourceFilesForTarget(l->second); + } + } + this->NumberOfSourceFilesWritten = 0; + // first do superclass method this->cmGlobalGenerator::Generate(); @@ -621,10 +699,16 @@ cmGlobalUnixMakefileGenerator3 // Write the rule. commands.clear(); + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; + progCmd << lg->GetMakefile()->GetHomeOutputDirectory(); + progCmd << "/CMakeFiles "; + progCmd << + (100*this->GetTargetTotalNumberOfSourceFiles(t->second))/ + this->GetNumberOfSourceFiles(); + commands.push_back(progCmd.str()); commands.push_back(lg->GetRecursiveMakeCall ("CMakeFiles/Makefile2",t->second.GetName())); - std::string echoCommand = "@echo \"\""; - commands.push_back(echoCommand.c_str()); depends.clear(); depends.push_back("cmake_check_build_system"); lg->WriteMakeRule(ruleFileStream, @@ -714,9 +798,7 @@ cmGlobalUnixMakefileGenerator3 << "# Target rules for target " << localName << "\n\n"; - commands.clear(); - std::string echoCommand = "@$(CMAKE_COMMAND) -E echo_append \".\""; - commands.push_back(echoCommand.c_str()); + commands.clear(); if (t->second.GetType() != cmTarget::UTILITY) { makeTargetName = localName; @@ -742,6 +824,21 @@ cmGlobalUnixMakefileGenerator3 localName += "/all"; depends.clear(); + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + progCmd << lg->GetMakefile()->GetHomeOutputDirectory(); + progCmd << "/CMakeFiles "; + std::vector &progFiles = lg->ProgressFiles[t->first]; + for (std::vector::iterator i = progFiles.begin(); + i != progFiles.end(); ++i) + { + progCmd << " " << *i; + } + if (progFiles.size()) + { + commands.push_back(progCmd.str()); + } + this->AppendGlobalTargetDepends(depends,t->second); lg->WriteMakeRule(ruleFileStream, "All Build rule for target.", localName.c_str(), depends, commands, true); @@ -814,6 +911,98 @@ cmGlobalUnixMakefileGenerator3 } } +//---------------------------------------------------------------------------- +int cmGlobalUnixMakefileGenerator3 +::GetTargetTotalNumberOfSourceFiles(cmTarget& target) +{ + int result = this->GetNumberOfCompilableSourceFilesForTarget(target); + std::vector& depends = this->GetTargetDepends(target); + + std::vector::iterator i; + for (i = depends.begin(); i != depends.end(); ++i) + { + result += this->GetTargetTotalNumberOfSourceFiles(**i); + } + + return result; +} + + +//---------------------------------------------------------------------------- +std::vector& cmGlobalUnixMakefileGenerator3 +::GetTargetDepends(cmTarget& target) +{ + // if the depends are already in the map then return + std::map >::iterator tgtI = + this->TargetDependencies.find(target.GetName()); + if (tgtI != this->TargetDependencies.end()) + { + return tgtI->second; + } + + // A target should not depend on itself. + std::set emitted; + emitted.insert(target.GetName()); + + // the vector of results + std::vector& result = + this->TargetDependencies[target.GetName()]; + + // Loop over all library dependencies but not for static libs + if (target.GetType() != cmTarget::STATIC_LIBRARY) + { + const cmTarget::LinkLibraryVectorType& tlibs = target.GetLinkLibraries(); + for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin(); + lib != tlibs.end(); ++lib) + { + // Don't emit the same library twice for this target. + if(emitted.insert(lib->first).second) + { + cmTarget *target2 = + target.GetMakefile()->FindTarget(lib->first.c_str()); + + // search each local generator until a match is found + if (!target2) + { + target2 = this->FindTarget(0,lib->first.c_str()); + } + + // if a match was found then ... + if (target2) + { + // Add this dependency. + result.push_back(target2); + } + } + } + } + + // Loop over all utility dependencies. + const std::set& tutils = target.GetUtilities(); + for(std::set::const_iterator util = tutils.begin(); + util != tutils.end(); ++util) + { + // Don't emit the same utility twice for this target. + if(emitted.insert(*util).second) + { + cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str()); + + // search each local generator until a match is found + if (!target2) + { + target2 = this->FindTarget(0,util->c_str()); + } + + // if a match was found then ... + if (target2) + { + // Add this dependency. + result.push_back(target2); + } + } + } + return result; +} //---------------------------------------------------------------------------- void diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 1b7733d5e..1cce9a8fa 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -123,6 +123,15 @@ public: const char *targetName, const char* config, bool ignoreErrors); + // returns true if a progress rule should be added + int ShouldAddProgressRule(); + int GetNumberOfSourceFiles() {return this->NumberOfSourceFiles; } + int GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt); + int GetTargetTotalNumberOfSourceFiles(cmTarget& target); + + // what targets does the specified target depend on + std::vector& GetTargetDepends(cmTarget& target); + protected: void WriteMainMakefile2(); void WriteMainCMakefile(); @@ -173,6 +182,12 @@ protected: typedef std::map MultipleOutputPairsType; MultipleOutputPairsType MultipleOutputPairs; + + size_t NumberOfSourceFiles; + size_t NumberOfSourceFilesWritten; + + std::map > TargetDependencies; + std::map TargetSourceFileCount; }; #endif diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index a69ae73f3..e2d3f8925 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1408,13 +1408,32 @@ void cmLocalUnixMakefileGenerator3 depends.push_back("cmake_check_build_system"); + if (!this->Parent) + { + cmGlobalUnixMakefileGenerator3 *gg = + static_cast(this->GlobalGenerator); + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; + progCmd << this->Makefile->GetHomeOutputDirectory(); + progCmd << "/CMakeFiles 100"; + commands.push_back(progCmd.str()); + } + commands.push_back (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str())); this->CreateCDCommand(commands, this->Makefile->GetHomeOutputDirectory(), this->Makefile->GetStartOutputDirectory()); - std::string echoCommand = "@echo \"\""; - commands.push_back(echoCommand.c_str()); + if (!this->Parent) + { + cmGlobalUnixMakefileGenerator3 *gg = + static_cast(this->GlobalGenerator); + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; + progCmd << this->Makefile->GetHomeOutputDirectory(); + progCmd << "/CMakeFiles 0"; + commands.push_back(progCmd.str()); + } this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands, true); diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index c96ca0056..d9b9a8d35 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -280,11 +280,14 @@ protected: cmTarget& target, const char* filename =0); bool ForceVerboseMakefiles; + std::map > ProgressFiles; + private: friend class cmMakefileTargetGenerator; friend class cmMakefileExecutableTargetGenerator; friend class cmMakefileLibraryTargetGenerator; friend class cmMakefileUtilityTargetGenerator; + friend class cmGlobalUnixMakefileGenerator3; std::map CheckDependFiles; diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx index c8565a961..ca86b3bad 100644 --- a/Source/cmMacroCommand.cxx +++ b/Source/cmMacroCommand.cxx @@ -252,11 +252,14 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) { // record commands until we hit the ENDMACRO // at the ENDMACRO call we shift gears and start looking for invocations - if(cmSystemTools::LowerCase(lff.Name) == "endmacro") + if(cmSystemTools::LowerCase(lff.Name) == "macro") { - std::vector expandedArguments; - mf.ExpandArguments(lff.Arguments, expandedArguments); - if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0])) + this->Depth++; + } + else if(cmSystemTools::LowerCase(lff.Name) == "endmacro") + { + // if this is the endmacro for this macro then execute + if (!this->Depth) { std::string name = this->Args[0]; std::vector::size_type cc; @@ -280,6 +283,11 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf) mf.RemoveFunctionBlocker(lff); return true; } + else + { + // decrement for each nested macro that ends + this->Depth--; + } } // if it wasn't an endmacro and we are not executing then we must be @@ -296,11 +304,14 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf) { std::vector expandedArguments; mf.ExpandArguments(lff.Arguments, expandedArguments); - if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0])) + if ((!expandedArguments.empty() && + (expandedArguments[0] == this->Args[0])) + || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS")) { return true; } } + return false; } diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h index 99e8b91b8..d93bdd86b 100644 --- a/Source/cmMacroCommand.h +++ b/Source/cmMacroCommand.h @@ -28,7 +28,7 @@ class cmMacroFunctionBlocker : public cmFunctionBlocker { public: - cmMacroFunctionBlocker() {} + cmMacroFunctionBlocker() {this->Depth=0;} virtual ~cmMacroFunctionBlocker() {} virtual bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile &mf); virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf); @@ -36,6 +36,7 @@ public: std::vector Args; std::vector Functions; + int Depth; }; /** \class cmMacroCommand diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 69a58d3e1..1f1bf6e33 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -381,6 +381,22 @@ cmMakefileTargetGenerator this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(), cmLocalUnixMakefileGenerator3::EchoBuild); + // add in a progress call if needed + cmGlobalUnixMakefileGenerator3* gg = + static_cast(this->GlobalGenerator); + int prog = gg->ShouldAddProgressRule(); + if (prog) + { + cmOStringStream progCmd; + progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report "; + progCmd << this->Makefile->GetHomeOutputDirectory(); + progCmd << "/CMakeFiles "; + progCmd << prog; + commands.push_back(progCmd.str()); + this->LocalGenerator->ProgressFiles[this->Target->GetName()]. + push_back(prog); + } + // Construct the compile rules. std::string compileRuleVar = "CMAKE_"; compileRuleVar += lang; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index a4e5640b5..ca9f1c335 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -29,9 +29,10 @@ # include "cmVariableWatch.h" # include "cmVersion.h" # include -# include #endif +# include + // only build kdevelop generator on non-windows platforms // when not bootstrapping cmake #if !defined(_WIN32) @@ -977,7 +978,6 @@ int cmake::ExecuteCMakeCommand(std::vector& args) // Command to start progress for a build else if (args[1] == "cmake_progress_start" && args.size() == 4) { -#if defined(CMAKE_BUILD_WITH_CMAKE) // bascially remove the directory std::string dirName = args[2]; dirName += "/Progress"; @@ -993,14 +993,12 @@ int cmake::ExecuteCMakeCommand(std::vector& args) fprintf(progFile,"%i\n",count); fclose(progFile); } -#endif return 0; } // Command to report progress for a build else if (args[1] == "cmake_progress_report" && args.size() >= 4) { -#if defined(CMAKE_BUILD_WITH_CMAKE) std::string dirName = args[2]; dirName += "/Progress"; std::string fName; @@ -1036,7 +1034,6 @@ int cmake::ExecuteCMakeCommand(std::vector& args) } fclose(progFile); } -#endif return 0; }