ENH: Cleaned up format of generated makefiles. Consolidated rule generation into single WriteMakeRule method. Added special targets like rebuild_cache and edit_cache.

This commit is contained in:
Brad King 2004-10-29 10:52:52 -04:00
parent 53763e14d4
commit 37ae7d6acf
2 changed files with 515 additions and 190 deletions

View File

@ -65,12 +65,9 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop)
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator2::GenerateMakefile()
{
// Open the output file.
std::string makefileName = m_Makefile->GetStartOutputDirectory();
makefileName += "/Makefile2";
std::string cmakefileName = makefileName;
cmakefileName += ".cmake";
// Open the output files.
std::ofstream makefileStream(makefileName.c_str());
if(!makefileStream)
{
@ -83,127 +80,23 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
// Write the do not edit header.
this->WriteDisclaimer(makefileStream);
// Write some rules to make things look nice.
makefileStream
<< "# Disable some common implicit rules to speed things up.\n"
<< ".SUFFIXES:\n"
<< ".SUFFIXES:.hpuxmakemusthaverule\n\n";
// Write standard variables to the makefile.
this->OutputMakeVariables(makefileStream);
this->WriteMakeVariables(makefileStream);
// Build command to run CMake to check if anything needs regenerating.
std::string runRule =
"@$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
runRule += " --check-rerun ";
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
// Write special targets that belong at the top of the file.
this->WriteSpecialTargetsTop(makefileStream);
// Construct recursive calls for the "all" rules.
std::string depRule;
std::string allRule;
this->AppendRecursiveMake(depRule, "Makefile2", "all.depends");
this->AppendRecursiveMake(allRule, "Makefile2", "all");
// Write the main entry point target. This must be the VERY first
// target so that make with no arguments will run it.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
commands.push_back(runRule);
commands.push_back(depRule);
commands.push_back(allRule);
this->OutputMakeRule(
makefileStream,
"Default target executed when no arguments are given to make.",
"default_target",
depends,
commands);
}
// Write special target to silence make output. This must be after
// the default target in case VERBOSE is set (which changes the name).
if(!m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
{
makefileStream
<< "# Suppress display of executed commands.\n"
<< "$(VERBOSE).SILENT:\n\n";
}
// Get the set of targets.
const cmTargets& targets = m_Makefile->GetTargets();
// Output top level dependency rule.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
{
// TODO: Dispatch generation of each target type.
if((t->second.GetType() == cmTarget::EXECUTABLE) ||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY))
{
if(t->second.IsInAll())
{
std::string dep = this->GetTargetDirectory(t->second);
dep += "/";
dep += t->first;
dep += ".depends";
depends.push_back(dep);
}
}
}
this->OutputMakeRule(makefileStream, "all dependencies", "all.depends",
depends, commands);
}
// Output top level build rule.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
{
// TODO: Dispatch generation of each target type.
if((t->second.GetType() == cmTarget::EXECUTABLE) ||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY))
{
if(t->second.IsInAll())
{
depends.push_back(t->first+".requires");
}
}
}
this->OutputMakeRule(makefileStream, "all", "all",
depends, commands);
}
// Write the directory-level build rules.
this->WriteAllRule(makefileStream);
// Write include statements to get rules for each target.
makefileStream
<< "# Include target rule files.\n";
for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
{
// TODO: Dispatch generation of each target type.
if((t->second.GetType() == cmTarget::EXECUTABLE) ||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY))
{
std::string ruleFileName = this->GetTargetDirectory(t->second);
ruleFileName += "/";
ruleFileName += t->first;
ruleFileName += ".make";
makefileStream
<< m_IncludeDirective << " "
<< this->ConvertToOutputForExisting(ruleFileName.c_str()).c_str()
<< "\n";
}
}
this->WriteTargetIncludes(makefileStream);
// Write jump-and-build rules that were recorded in the map.
this->WriteJumpAndBuildRules(makefileStream);
// Write special targets that belong at the bottom of the file.
this->WriteSpecialTargetsBottom(makefileStream);
}
//----------------------------------------------------------------------------
@ -351,8 +244,9 @@ cmLocalUnixMakefileGenerator2
{
std::vector<std::string> depends;
std::vector<std::string> commands;
std::string depComment = "dependencies for ";
depComment += target.GetName();
std::string depEcho = "Building dependencies for ";
depEcho += target.GetName();
depEcho += "...";
std::string depTarget = dir;
depTarget += "/";
depTarget += target.GetName();
@ -363,30 +257,10 @@ cmLocalUnixMakefileGenerator2
depends.push_back((*obj)+".depends");
}
depends.push_back(ruleFileName);
this->OutputMakeRule(ruleFileStream, depComment.c_str(), depTarget.c_str(),
depends, commands);
this->WriteMakeRule(ruleFileStream, 0, depEcho.c_str(),
depTarget.c_str(), depends, commands);
}
#if 0
// Write the requires rule.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
std::string reqComment = "requirements for ";
reqComment += target.GetName();
std::string reqTarget = target.GetName();
reqTarget += ".requires";
for(std::vector<std::string>::const_iterator obj = objects.begin();
obj != objects.end(); ++obj)
{
depends.push_back(*obj);
}
depends.push_back(ruleFileName);
this->OutputMakeRule(ruleFileStream, reqComment.c_str(), reqTarget.c_str(),
depends, commands);
}
#endif
// Write the build rule.
switch(target.GetType())
{
@ -491,8 +365,11 @@ cmLocalUnixMakefileGenerator2
std::string depTarget = obj;
depTarget += ".depends";
{
std::string depComment = "dependencies for ";
depComment += obj;
std::string depEcho = "Scanning ";
depEcho += lang;
depEcho += " dependencies of ";
depEcho += obj;
depEcho += "...";
cmOStringStream depCmd;
// TODO: Account for source file properties and directory-level
// definitions when scanning for dependencies.
@ -511,8 +388,8 @@ cmLocalUnixMakefileGenerator2
std::string touchCmd = "@touch ";
touchCmd += this->ConvertToRelativeOutputPath(depTarget.c_str());
commands.push_back(touchCmd);
this->OutputMakeRule(ruleFileStream, depComment.c_str(), depTarget.c_str(),
depends, commands);
this->WriteMakeRule(ruleFileStream, 0, depEcho.c_str(),
depTarget.c_str(), depends, commands);
}
// Write the build rule.
@ -580,13 +457,113 @@ cmLocalUnixMakefileGenerator2
}
// Write the rule.
std::string buildComment = lang;
buildComment += " object";
this->OutputMakeRule(ruleFileStream, buildComment.c_str(), obj.c_str(),
depends, commands);
std::string buildEcho = "Building ";
buildEcho += lang;
buildEcho += " object ";
buildEcho += obj;
buildEcho += "...";
this->WriteMakeRule(ruleFileStream, 0, buildEcho.c_str(),
obj.c_str(), depends, commands);
}
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteMakeRule(std::ostream& os,
const char* comment,
const char* preEcho,
const char* target,
const std::vector<std::string>& depends,
const std::vector<std::string>& commands,
const char* postEcho)
{
// Make sure there is a target.
if(!target || !*target)
{
cmSystemTools::Error("No target for WriteMakeRule!");
return;
}
std::string replace;
// Write the comment describing the rule in the makefile.
if(comment)
{
replace = comment;
m_Makefile->ExpandVariablesInString(replace);
std::string::size_type lpos = 0;
std::string::size_type rpos;
while((rpos = replace.find(lpos, '\n')) != std::string::npos)
{
os << "# " << replace.substr(lpos, rpos-lpos);
lpos = rpos+1;
}
os << "# " << replace.substr(lpos) << "\n";
}
// Construct the left hand side of the rule.
replace = target;
m_Makefile->ExpandVariablesInString(replace);
std::string tgt = this->ConvertToRelativeOutputPath(replace.c_str());
tgt = this->ConvertToMakeTarget(tgt.c_str());
const char* space = "";
if(tgt.size() == 1)
{
// Add a space before the ":" to avoid drive letter confusion on
// Windows.
space = " ";
}
// Write the rule.
if(depends.empty())
{
// No dependencies. The commands will always run.
os << tgt.c_str() << space << ":\n";
}
else
{
// Split dependencies into multiple rule lines. This allows for
// very long dependency lists even on older make implementations.
for(std::vector<std::string>::const_iterator dep = depends.begin();
dep != depends.end(); ++dep)
{
replace = *dep;
m_Makefile->ExpandVariablesInString(replace);
replace = this->ConvertToMakeTarget(replace.c_str());
os << tgt.c_str() << space << ": " << replace.c_str() << "\n";
}
}
// Write the list of commands.
bool first = true;
for(std::vector<std::string>::const_iterator i = commands.begin();
i != commands.end(); ++i)
{
replace = *i;
m_Makefile->ExpandVariablesInString(replace);
if(first && preEcho)
{
this->OutputEcho(os, preEcho);
}
os << "\t" << replace.c_str() << "\n";
first = false;
}
if(postEcho)
{
this->OutputEcho(os, postEcho);
}
os << "\n";
}
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator2::WriteDivider(std::ostream& os)
{
os
<< "#======================================"
<< "=======================================\n";
}
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator2::WriteDisclaimer(std::ostream& os)
{
@ -598,6 +575,331 @@ void cmLocalUnixMakefileGenerator2::WriteDisclaimer(std::ostream& os)
<< cmMakefile::GetMinorVersion() << "\n\n";
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteMakeVariables(std::ostream& makefileStream)
{
this->WriteDivider(makefileStream);
makefileStream
<< "# Set environment variables for the build.\n"
<< "\n";
if(m_WindowsShell)
{
makefileStream
<< "!IF \"$(OS)\" == \"Windows_NT\"\n"
<< "NULL=\n"
<< "!ELSE \n"
<< "NULL=nul\n"
<< "!ENDIF \n";
}
else
{
makefileStream
<< "# The shell in which to execute make rules.\n"
<< "SHELL = /bin/sh\n"
<< "\n";
}
std::string cmakecommand =
this->ConvertToOutputForExisting(
m_Makefile->GetRequiredDefinition("CMAKE_COMMAND"));
makefileStream
<< "# The CMake executable.\n"
<< "CMAKE_COMMAND = " << cmakecommand.c_str() << "\n"
<< "\n";
makefileStream
<< "# The command to remove a file.\n"
<< "RM = " << cmakecommand.c_str() << " -E remove -f\n"
<< "\n";
if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
{
makefileStream
<< "# The program to use to edit the cache.\n"
<< "CMAKE_EDIT_COMMAND = "
<< (this->ConvertToOutputForExisting(
m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))) << "\n"
<< "\n";
}
makefileStream
<< "# The source directory corresponding to this makefile.\n"
<< "CMAKE_CURRENT_SOURCE = "
<< this->ConvertToRelativeOutputPath(m_Makefile->GetStartDirectory())
<< "\n"
<< "\n";
makefileStream
<< "# The build directory corresponding to this makefile.\n"
<< "CMAKE_CURRENT_BINARY = "
<< this->ConvertToRelativeOutputPath(m_Makefile->GetStartOutputDirectory())
<< "\n"
<< "\n";
makefileStream
<< "# The top-level source directory on which CMake was run.\n"
<< "CMAKE_SOURCE_DIR = "
<< this->ConvertToRelativeOutputPath(m_Makefile->GetHomeDirectory())
<< "\n"
<< "\n";
makefileStream
<< "# The top-level build directory on which CMake was run.\n"
<< "CMAKE_BINARY_DIR = "
<< this->ConvertToRelativeOutputPath(m_Makefile->GetHomeOutputDirectory())
<< "\n"
<< "\n";
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteSpecialTargetsTop(std::ostream& makefileStream)
{
this->WriteDivider(makefileStream);
makefileStream
<< "# Special targets provided by cmake.\n"
<< "\n";
// Build command to run CMake to check if anything needs regenerating.
std::string cmakefileName = m_Makefile->GetStartOutputDirectory();
cmakefileName += "/Makefile2.cmake";
std::string runRule =
"@$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
runRule += " --check-rerun ";
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
// Construct recursive calls for the directory-level rules.
std::string depRule;
std::string allRule;
this->AppendRecursiveMake(depRule, "Makefile2", "all.depends");
this->AppendRecursiveMake(allRule, "Makefile2", "all.build");
// Write the main entry point target. This must be the VERY first
// target so that make with no arguments will run it.
{
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(runRule);
commands.push_back(depRule);
commands.push_back(allRule);
this->WriteMakeRule(makefileStream,
"Default target executed when no arguments are "
"given to make.",
"Checking build system...",
"all",
no_depends,
commands,
"Targets are up-to-date.");
}
// Write special "rebuild_cache" target to re-run cmake.
{
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(
"$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
this->WriteMakeRule(makefileStream,
"Special rule to re-run CMake using make.",
"Running CMake to regenerate build system...",
"rebuild_cache",
no_depends,
commands);
}
// Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined.
// Otherwise default to the interactive command-line interface.
if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
{
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(
"$(CMAKE_EDIT_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
this->WriteMakeRule(makefileStream,
"Special rule to re-run CMake cache editor using make.",
"Running CMake cache editor...",
"edit_cache",
no_depends,
commands);
}
else
{
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(
"$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -i");
this->WriteMakeRule(makefileStream,
"Special rule to re-run CMake cache editor using make.",
"Running interactive CMake command-line interface...",
"edit_cache",
no_depends,
commands);
}
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteSpecialTargetsBottom(std::ostream& makefileStream)
{
this->WriteDivider(makefileStream);
makefileStream
<< "# Special targets to cleanup operation of make.\n"
<< "\n";
std::vector<std::string> no_commands;
// Write special target to silence make output. This must be after
// the default target in case VERBOSE is set (which changes the name).
if(!m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
{
std::vector<std::string> no_depends;
this->WriteMakeRule(makefileStream,
"Suppress display of executed commands.",
0,
"$(VERBOSE).SILENT",
no_depends,
no_commands);
}
// Special target to cleanup operation of make tool.
std::vector<std::string> depends;
depends.push_back(".hpux_make_must_have_this_dependency_here");
this->WriteMakeRule(makefileStream,
"Disable some common implicit rules to speed things up.",
0,
".SUFFIXES",
depends,
no_commands);
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteAllRule(std::ostream& makefileStream)
{
// Write section header.
this->WriteDivider(makefileStream);
makefileStream
<< "# Main rules for this directory.\n"
<< "\n";
const cmTargets& targets = m_Makefile->GetTargets();
// Output top level dependency rule.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
{
// TODO: Dispatch generation of each target type.
if((t->second.GetType() == cmTarget::EXECUTABLE) ||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY))
{
if(t->second.IsInAll())
{
std::string dep = this->GetTargetDirectory(t->second);
dep += "/";
dep += t->first;
dep += ".depends";
depends.push_back(dep);
}
}
}
this->WriteMakeRule(makefileStream,
"Main dependencies target for this directory.",
0,
"all.depends",
depends,
commands);
}
// Output top level build rule.
{
std::vector<std::string> depends;
std::vector<std::string> commands;
for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
{
// TODO: Dispatch generation of each target type.
if((t->second.GetType() == cmTarget::EXECUTABLE) ||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY))
{
if(t->second.IsInAll())
{
depends.push_back(t->first+".requires");
}
}
}
this->WriteMakeRule(makefileStream,
"Main build target for this directory.",
0,
"all.build",
depends,
commands);
}
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteRequiresRule(std::ostream& ruleFileStream, const cmTarget& target,
const char* targetFullPath)
{
std::vector<std::string> depends;
std::vector<std::string> no_commands;
std::string reqComment = "Requirements for target ";
reqComment += target.GetName();
std::string reqTarget = target.GetName();
reqTarget += ".requires";
depends.push_back(targetFullPath);
this->WriteMakeRule(ruleFileStream, reqComment.c_str(), 0,
reqTarget.c_str(), depends, no_commands);
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
::WriteTargetIncludes(std::ostream& makefileStream)
{
bool first = true;
const cmTargets& targets = m_Makefile->GetTargets();
for(cmTargets::const_iterator t = targets.begin(); t != targets.end(); ++t)
{
// TODO: Handle the rest of the target types.
if((t->second.GetType() == cmTarget::EXECUTABLE) ||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(t->second.GetType() == cmTarget::MODULE_LIBRARY))
{
// Write the header for this section.
if(first)
{
this->WriteDivider(makefileStream);
makefileStream
<< "# Include rule files for each target in this directory.\n"
<< "\n";
first = false;
}
// Construct the rule file name for this target.
std::string ruleFileName = this->GetTargetDirectory(t->second);
ruleFileName += "/";
ruleFileName += t->first;
ruleFileName += ".make";
makefileStream
<< m_IncludeDirective << " "
<< this->ConvertToOutputForExisting(ruleFileName.c_str()).c_str()
<< "\n";
}
}
if(!first)
{
makefileStream << "\n";
}
}
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator2
@ -636,7 +938,7 @@ cmLocalUnixMakefileGenerator2
std::string targetFullPath = m_ExecutableOutputPath;
if(targetFullPath.length() == 0)
{
targetFullPath = m_Makefile->GetCurrentOutputDirectory();
targetFullPath = m_Makefile->GetStartOutputDirectory();
if(targetFullPath.size() && targetFullPath[targetFullPath.size()-1] != '/')
{
targetFullPath += "/";
@ -737,25 +1039,17 @@ cmLocalUnixMakefileGenerator2
}
// Write the build rule.
std::string buildComment = linkLanguage;
buildComment += " executable";
this->OutputMakeRule(ruleFileStream, buildComment.c_str(),
targetFullPath.c_str(),
depends, commands);
std::string buildEcho = "Linking ";
buildEcho += linkLanguage;
buildEcho += " executable ";
buildEcho += targetFullPath;
buildEcho += "...";
this->WriteMakeRule(ruleFileStream, 0, buildEcho.c_str(),
targetFullPath.c_str(), depends, commands);
// TODO: Add "local" target and canonical target name as rules.
// Write the requires rule.
{
std::vector<std::string> depends2;
std::vector<std::string> commands2;
std::string reqComment = "requirements for ";
reqComment += target.GetName();
std::string reqTarget = target.GetName();
reqTarget += ".requires";
depends2.push_back(targetFullPath);
this->OutputMakeRule(ruleFileStream, reqComment.c_str(), reqTarget.c_str(),
depends2, commands2);
}
// Write driver rule for this target.
this->WriteRequiresRule(ruleFileStream, target, targetFullPath.c_str());
}
//----------------------------------------------------------------------------
@ -980,26 +1274,28 @@ cmLocalUnixMakefileGenerator2
}
// Write the build rule.
std::string buildComment = linkLanguage;
buildComment += " static library";
this->OutputMakeRule(ruleFileStream, buildComment.c_str(),
targetFullPath.c_str(),
depends, commands);
std::string buildEcho = "Linking ";
buildEcho += linkLanguage;
switch(target.GetType())
{
case cmTarget::STATIC_LIBRARY:
buildEcho += " static library "; break;
case cmTarget::SHARED_LIBRARY:
buildEcho += " shared library "; break;
case cmTarget::MODULE_LIBRARY:
buildEcho += " shared module "; break;
default:
buildEcho += " library "; break;
}
buildEcho += targetFullPath.c_str();
buildEcho += "...";
this->WriteMakeRule(ruleFileStream, 0, buildEcho.c_str(),
targetFullPath.c_str(), depends, commands);
// TODO: Add "local" target and canonical target name as rules.
// Write the requires rule.
{
std::vector<std::string> depends2;
std::vector<std::string> commands2;
std::string reqComment = "requirements for ";
reqComment += target.GetName();
std::string reqTarget = target.GetName();
reqTarget += ".requires";
depends2.push_back(targetFullPath);
this->OutputMakeRule(ruleFileStream, reqComment.c_str(), reqTarget.c_str(),
depends2, commands2);
}
// Write driver rule for this target.
this->WriteRequiresRule(ruleFileStream, target, targetFullPath.c_str());
}
//----------------------------------------------------------------------------
@ -1028,7 +1324,7 @@ cmLocalUnixMakefileGenerator2
m_Makefile->GetCurrentDirectory()) == 0)
|| (cmSystemTools::GetFilenamePath(
source.GetFullPath()).find(
m_Makefile->GetCurrentOutputDirectory()) == 0))
m_Makefile->GetStartOutputDirectory()) == 0))
{
objectName = source.GetSourceName();
}
@ -1067,7 +1363,7 @@ std::string
cmLocalUnixMakefileGenerator2
::ConvertToFullPath(const std::string& localPath)
{
std::string dir = m_Makefile->GetCurrentOutputDirectory();
std::string dir = m_Makefile->GetStartOutputDirectory();
dir += "/";
dir += localPath;
return dir;
@ -1164,7 +1460,7 @@ cmLocalUnixMakefileGenerator2
// Get the path to the library.
std::string libPath;
if(this->SamePath(m_Makefile->GetCurrentOutputDirectory(), dir))
if(this->SamePath(m_Makefile->GetStartOutputDirectory(), dir))
{
// The target is in the current directory so this makefile will
// know about it already.
@ -1244,9 +1540,14 @@ cmLocalUnixMakefileGenerator2
// Call make on the given file.
cmd += "$(MAKE) -f ";
cmd += file;
cmd += " ";
// Pass down verbosity level.
cmd += " $(MAKESILENT) ";
if(m_MakeSilentFlag.size())
{
cmd += m_MakeSilentFlag;
cmd += " ";
}
// Most unix makes will pass the command line flags to make down to
// sub-invoked makes via an environment variable. However, some
@ -1288,8 +1589,17 @@ cmLocalUnixMakefileGenerator2
tgt += ".requires";
this->AppendRecursiveMake(cmd, "Makefile2", tgt.c_str());
}
this->OutputMakeRule(makefileStream, "jump rule for",
rt.m_FilePath.c_str(), depends, commands);
std::string jumpPreEcho = "Jumping to ";
jumpPreEcho += rt.m_BuildDirectory.c_str();
jumpPreEcho += " to build ";
jumpPreEcho += jump->first;
jumpPreEcho += "...";
std::string jumpPostEcho = "Returning to ";
jumpPostEcho += m_Makefile->GetStartOutputDirectory();
jumpPostEcho += "...";
this->WriteMakeRule(makefileStream, 0, jumpPreEcho.c_str(),
rt.m_FilePath.c_str(), depends, commands,
jumpPostEcho.c_str());
}
}

View File

@ -57,7 +57,22 @@ protected:
void GenerateTargetRuleFile(const cmTarget& target);
void GenerateObjectRuleFile(const cmTarget& target,
const cmSourceFile& source);
void WriteMakeRule(std::ostream& os,
const char* comment,
const char* preEcho,
const char* target,
const std::vector<std::string>& depends,
const std::vector<std::string>& commands,
const char* postEcho=0);
void WriteDivider(std::ostream& os);
void WriteDisclaimer(std::ostream& os);
void WriteMakeVariables(std::ostream& makefileStream);
void WriteSpecialTargetsTop(std::ostream& makefileStream);
void WriteSpecialTargetsBottom(std::ostream& makefileStream);
void WriteTargetIncludes(std::ostream& makefileStream);
void WriteAllRule(std::ostream& makefileStream);
void WriteRequiresRule(std::ostream& ruleFileStream, const cmTarget& target,
const char* targetFullPath);
void WriteExecutableRule(std::ostream& ruleFileStream,
const char* ruleFileName,
const cmTarget& target,