summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalUnixMakefileGenerator3.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalUnixMakefileGenerator3.cxx')
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx280
1 files changed, 255 insertions, 25 deletions
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 7c506ea..df34fa3 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,13 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
this->ToolSupportsColor = true;
+ this->NumberOfSourceFiles = 0;
+ this->NumberOfSourceFilesWritten = 0;
+#ifdef _WIN32
+ this->UseLinkScript = false;
+#else
+ this->UseLinkScript = true;
+#endif
}
void cmGlobalUnixMakefileGenerator3
@@ -110,8 +119,83 @@ cmGlobalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
+int cmGlobalUnixMakefileGenerator3::ShouldAddProgressRule()
+{
+ // add progress to 100 source files
+ if (this->NumberOfSourceFiles &&
+ (((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<cmStdString, int >::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<cmSourceFile*>& sources = tgt.GetSourceFiles();
+ for(std::vector<cmSourceFile*>::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<cmLocalUnixMakefileGenerator3 *>
+ (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();
@@ -127,7 +211,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
// see if the build system must be regenerated.
std::string makefileName =
this->GetCMakeInstance()->GetHomeOutputDirectory();
- makefileName += "/CMakeFiles/Makefile2";
+ makefileName += cmake::GetCMakeFilesDirectory();
+ makefileName += "/Makefile2";
cmGeneratedFileStream makefileStream(makefileName.c_str());
if(!makefileStream)
{
@@ -214,7 +299,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// see if the build system must be regenerated.
std::string cmakefileName =
this->GetCMakeInstance()->GetHomeOutputDirectory();
- cmakefileName += "/CMakeFiles/Makefile.cmake";
+ cmakefileName += cmake::GetCMakeFilesDirectory();
+ cmakefileName += "/Makefile.cmake";
cmGeneratedFileStream cmakefileStream(cmakefileName.c_str());
if(!cmakefileStream)
{
@@ -281,7 +367,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// Build the path to the cache check file.
std::string check = this->GetCMakeInstance()->GetHomeOutputDirectory();
- check += "/CMakeFiles/cmake.check_cache";
+ check += cmake::GetCMakeFilesDirectory();
+ check += "/cmake.check_cache";
// Set the corresponding makefile in the cmake file.
cmakefileStream
@@ -301,7 +388,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
tmpStr = lg->GetMakefile()->GetStartOutputDirectory();
- tmpStr += "/CMakeFiles/CMakeDirectoryInformation.cmake";
+ tmpStr += cmake::GetCMakeFilesDirectory();
+ tmpStr += "/CMakeDirectoryInformation.cmake";
cmakefileStream << " \"" <<
lg->Convert(tmpStr.c_str(),cmLocalGenerator::HOME_OUTPUT).c_str()
<< "\"\n";
@@ -518,7 +606,7 @@ cmGlobalUnixMakefileGenerator3
std::string cmGlobalUnixMakefileGenerator3
::GenerateBuildCommand(const char* makeProgram, const char *projectName,
const char* additionalOptions, const char *targetName,
- const char* config, bool ignoreErrors)
+ const char* config, bool ignoreErrors, bool fast)
{
// Project name and config are not used yet.
(void)projectName;
@@ -565,7 +653,10 @@ std::string cmGlobalUnixMakefileGenerator3
lg->SetupPathConversions();
makeCommand += " \"";
std::string tname = targetName;
+ if(fast)
+ {
tname += "/fast";
+ }
tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
tname = lg->ConvertToMakeTarget(tname.c_str());
@@ -601,18 +692,20 @@ cmGlobalUnixMakefileGenerator3
cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{
- if((t->second.GetType() == cmTarget::EXECUTABLE) ||
- (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
- (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
- (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
- (t->second.GetType() == cmTarget::UTILITY))
- {
// Don't emit the same rule twice (e.g. two targets with the same
// simple name)
if(t->second.GetName() &&
strlen(t->second.GetName()) &&
emitted.insert(t->second.GetName()).second)
{
+ // Handle user targets here. Global targets are handled in
+ // the local generator on a per-directory basis.
+ if((t->second.GetType() == cmTarget::EXECUTABLE) ||
+ (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
+ (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
+ (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+ (t->second.GetType() == cmTarget::UTILITY))
+ {
// Add a rule to build the target by name.
lg->WriteDivider(ruleFileStream);
ruleFileStream
@@ -621,8 +714,10 @@ cmGlobalUnixMakefileGenerator3
// Write the rule.
commands.clear();
+ std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
+ tmp += "Makefile2";
commands.push_back(lg->GetRecursiveMakeCall
- ("CMakeFiles/Makefile2",t->second.GetName()));
+ (tmp.c_str(),t->second.GetName()));
depends.clear();
depends.push_back("cmake_check_build_system");
lg->WriteMakeRule(ruleFileStream,
@@ -647,17 +742,6 @@ cmGlobalUnixMakefileGenerator3
localName.c_str(), depends, commands, true);
}
}
- else
- {
- // Add a fast rule to build the target
- depends.clear();
- commands.clear();
- std::string localName = t->second.GetName();
- depends.push_back(localName);
- localName += "/fast";
- lg->WriteMakeRule(ruleFileStream, "fast build rule for target.",
- localName.c_str(), depends, commands, true);
- }
}
}
}
@@ -675,6 +759,7 @@ cmGlobalUnixMakefileGenerator3
std::string localName;
std::string makeTargetName;
+
// write the directory level rules for this local gen
this->WriteDirectoryRules2(ruleFileStream,lg);
@@ -731,6 +816,30 @@ cmGlobalUnixMakefileGenerator3
// Write the rule.
localName += "/all";
depends.clear();
+
+ std::string progressDir =
+ lg->GetMakefile()->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
+ {
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
+ // all target counts
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ progCmd << " ";
+ std::vector<int> &progFiles = lg->ProgressFiles[t->first];
+ for (std::vector<int>::iterator i = progFiles.begin();
+ i != progFiles.end(); ++i)
+ {
+ progCmd << " " << *i;
+ }
+ commands.push_back(progCmd.str());
+ }
+ progressDir = "Building target ";
+ progressDir += t->first;
+ lg->AppendEcho(commands,progressDir.c_str());
+
this->AppendGlobalTargetDepends(depends,t->second);
lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
localName.c_str(), depends, commands, true);
@@ -747,8 +856,35 @@ cmGlobalUnixMakefileGenerator3
// Write the rule.
commands.clear();
+ progressDir = lg->GetMakefile()->GetHomeOutputDirectory();
+ progressDir += cmake::GetCMakeFilesDirectory();
+
+ {
+ // TODO: Convert the total progress count to a make variable.
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
+ // # in target
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ //
+ progCmd << " "
+ << this->GetTargetTotalNumberOfProgressFiles(t->second);
+ commands.push_back(progCmd.str());
+ }
+ std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
+ tmp += "Makefile2";
commands.push_back(lg->GetRecursiveMakeCall
- ("CMakeFiles/Makefile2",localName.c_str()));
+ (tmp.c_str(),localName.c_str()));
+ {
+ cmOStringStream progCmd;
+ progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
+ progCmd << lg->Convert(progressDir.c_str(),
+ cmLocalGenerator::FULL,
+ cmLocalGenerator::SHELL);
+ progCmd << " 0";
+ commands.push_back(progCmd.str());
+ }
depends.clear();
depends.push_back("cmake_check_build_system");
localName = lg->GetRelativeTargetDirectory(t->second);
@@ -773,7 +909,6 @@ cmGlobalUnixMakefileGenerator3
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall
(makefileName.c_str(), localName.c_str()));
- this->AppendGlobalTargetDepends(depends,t->second);
lg->WriteMakeRule(ruleFileStream,
"Pre-install relink rule for target.",
localName.c_str(), depends, commands, true);
@@ -803,6 +938,101 @@ cmGlobalUnixMakefileGenerator3
}
}
+//----------------------------------------------------------------------------
+int cmGlobalUnixMakefileGenerator3
+::GetTargetTotalNumberOfProgressFiles(cmTarget& target)
+{
+ cmLocalUnixMakefileGenerator3 *lg =
+ static_cast<cmLocalUnixMakefileGenerator3 *>
+ (target.GetMakefile()->GetLocalGenerator());
+ int result = static_cast<int>(lg->ProgressFiles[target.GetName()].size());
+ std::vector<cmTarget *>& depends = this->GetTargetDepends(target);
+
+ std::vector<cmTarget *>::iterator i;
+ for (i = depends.begin(); i != depends.end(); ++i)
+ {
+ result += this->GetTargetTotalNumberOfProgressFiles(**i);
+ }
+
+ return result;
+}
+
+
+//----------------------------------------------------------------------------
+std::vector<cmTarget *>& cmGlobalUnixMakefileGenerator3
+::GetTargetDepends(cmTarget& target)
+{
+ // if the depends are already in the map then return
+ std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI =
+ this->TargetDependencies.find(target.GetName());
+ if (tgtI != this->TargetDependencies.end())
+ {
+ return tgtI->second;
+ }
+
+ // A target should not depend on itself.
+ std::set<cmStdString> emitted;
+ emitted.insert(target.GetName());
+
+ // the vector of results
+ std::vector<cmTarget *>& 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<cmStdString>& tutils = target.GetUtilities();
+ for(std::set<cmStdString>::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