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:
parent
53763e14d4
commit
37ae7d6acf
|
@ -65,12 +65,9 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop)
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmLocalUnixMakefileGenerator2::GenerateMakefile()
|
void cmLocalUnixMakefileGenerator2::GenerateMakefile()
|
||||||
{
|
{
|
||||||
|
// Open the output file.
|
||||||
std::string makefileName = m_Makefile->GetStartOutputDirectory();
|
std::string makefileName = m_Makefile->GetStartOutputDirectory();
|
||||||
makefileName += "/Makefile2";
|
makefileName += "/Makefile2";
|
||||||
std::string cmakefileName = makefileName;
|
|
||||||
cmakefileName += ".cmake";
|
|
||||||
|
|
||||||
// Open the output files.
|
|
||||||
std::ofstream makefileStream(makefileName.c_str());
|
std::ofstream makefileStream(makefileName.c_str());
|
||||||
if(!makefileStream)
|
if(!makefileStream)
|
||||||
{
|
{
|
||||||
|
@ -83,127 +80,23 @@ void cmLocalUnixMakefileGenerator2::GenerateMakefile()
|
||||||
// Write the do not edit header.
|
// Write the do not edit header.
|
||||||
this->WriteDisclaimer(makefileStream);
|
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.
|
// Write standard variables to the makefile.
|
||||||
this->OutputMakeVariables(makefileStream);
|
this->WriteMakeVariables(makefileStream);
|
||||||
|
|
||||||
// Build command to run CMake to check if anything needs regenerating.
|
// Write special targets that belong at the top of the file.
|
||||||
std::string runRule =
|
this->WriteSpecialTargetsTop(makefileStream);
|
||||||
"@$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
|
|
||||||
runRule += " --check-rerun ";
|
|
||||||
runRule += this->ConvertToRelativeOutputPath(cmakefileName.c_str());
|
|
||||||
|
|
||||||
// Construct recursive calls for the "all" rules.
|
// Write the directory-level build rules.
|
||||||
std::string depRule;
|
this->WriteAllRule(makefileStream);
|
||||||
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 include statements to get rules for each target.
|
// Write include statements to get rules for each target.
|
||||||
makefileStream
|
this->WriteTargetIncludes(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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write jump-and-build rules that were recorded in the map.
|
// Write jump-and-build rules that were recorded in the map.
|
||||||
this->WriteJumpAndBuildRules(makefileStream);
|
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> depends;
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
std::string depComment = "dependencies for ";
|
std::string depEcho = "Building dependencies for ";
|
||||||
depComment += target.GetName();
|
depEcho += target.GetName();
|
||||||
|
depEcho += "...";
|
||||||
std::string depTarget = dir;
|
std::string depTarget = dir;
|
||||||
depTarget += "/";
|
depTarget += "/";
|
||||||
depTarget += target.GetName();
|
depTarget += target.GetName();
|
||||||
|
@ -363,30 +257,10 @@ cmLocalUnixMakefileGenerator2
|
||||||
depends.push_back((*obj)+".depends");
|
depends.push_back((*obj)+".depends");
|
||||||
}
|
}
|
||||||
depends.push_back(ruleFileName);
|
depends.push_back(ruleFileName);
|
||||||
this->OutputMakeRule(ruleFileStream, depComment.c_str(), depTarget.c_str(),
|
this->WriteMakeRule(ruleFileStream, 0, depEcho.c_str(),
|
||||||
depends, commands);
|
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.
|
// Write the build rule.
|
||||||
switch(target.GetType())
|
switch(target.GetType())
|
||||||
{
|
{
|
||||||
|
@ -491,8 +365,11 @@ cmLocalUnixMakefileGenerator2
|
||||||
std::string depTarget = obj;
|
std::string depTarget = obj;
|
||||||
depTarget += ".depends";
|
depTarget += ".depends";
|
||||||
{
|
{
|
||||||
std::string depComment = "dependencies for ";
|
std::string depEcho = "Scanning ";
|
||||||
depComment += obj;
|
depEcho += lang;
|
||||||
|
depEcho += " dependencies of ";
|
||||||
|
depEcho += obj;
|
||||||
|
depEcho += "...";
|
||||||
cmOStringStream depCmd;
|
cmOStringStream depCmd;
|
||||||
// TODO: Account for source file properties and directory-level
|
// TODO: Account for source file properties and directory-level
|
||||||
// definitions when scanning for dependencies.
|
// definitions when scanning for dependencies.
|
||||||
|
@ -511,8 +388,8 @@ cmLocalUnixMakefileGenerator2
|
||||||
std::string touchCmd = "@touch ";
|
std::string touchCmd = "@touch ";
|
||||||
touchCmd += this->ConvertToRelativeOutputPath(depTarget.c_str());
|
touchCmd += this->ConvertToRelativeOutputPath(depTarget.c_str());
|
||||||
commands.push_back(touchCmd);
|
commands.push_back(touchCmd);
|
||||||
this->OutputMakeRule(ruleFileStream, depComment.c_str(), depTarget.c_str(),
|
this->WriteMakeRule(ruleFileStream, 0, depEcho.c_str(),
|
||||||
depends, commands);
|
depTarget.c_str(), depends, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the build rule.
|
// Write the build rule.
|
||||||
|
@ -580,13 +457,113 @@ cmLocalUnixMakefileGenerator2
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the rule.
|
// Write the rule.
|
||||||
std::string buildComment = lang;
|
std::string buildEcho = "Building ";
|
||||||
buildComment += " object";
|
buildEcho += lang;
|
||||||
this->OutputMakeRule(ruleFileStream, buildComment.c_str(), obj.c_str(),
|
buildEcho += " object ";
|
||||||
depends, commands);
|
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)
|
void cmLocalUnixMakefileGenerator2::WriteDisclaimer(std::ostream& os)
|
||||||
{
|
{
|
||||||
|
@ -598,6 +575,331 @@ void cmLocalUnixMakefileGenerator2::WriteDisclaimer(std::ostream& os)
|
||||||
<< cmMakefile::GetMinorVersion() << "\n\n";
|
<< 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
|
void
|
||||||
cmLocalUnixMakefileGenerator2
|
cmLocalUnixMakefileGenerator2
|
||||||
|
@ -636,7 +938,7 @@ cmLocalUnixMakefileGenerator2
|
||||||
std::string targetFullPath = m_ExecutableOutputPath;
|
std::string targetFullPath = m_ExecutableOutputPath;
|
||||||
if(targetFullPath.length() == 0)
|
if(targetFullPath.length() == 0)
|
||||||
{
|
{
|
||||||
targetFullPath = m_Makefile->GetCurrentOutputDirectory();
|
targetFullPath = m_Makefile->GetStartOutputDirectory();
|
||||||
if(targetFullPath.size() && targetFullPath[targetFullPath.size()-1] != '/')
|
if(targetFullPath.size() && targetFullPath[targetFullPath.size()-1] != '/')
|
||||||
{
|
{
|
||||||
targetFullPath += "/";
|
targetFullPath += "/";
|
||||||
|
@ -737,25 +1039,17 @@ cmLocalUnixMakefileGenerator2
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the build rule.
|
// Write the build rule.
|
||||||
std::string buildComment = linkLanguage;
|
std::string buildEcho = "Linking ";
|
||||||
buildComment += " executable";
|
buildEcho += linkLanguage;
|
||||||
this->OutputMakeRule(ruleFileStream, buildComment.c_str(),
|
buildEcho += " executable ";
|
||||||
targetFullPath.c_str(),
|
buildEcho += targetFullPath;
|
||||||
depends, commands);
|
buildEcho += "...";
|
||||||
|
this->WriteMakeRule(ruleFileStream, 0, buildEcho.c_str(),
|
||||||
|
targetFullPath.c_str(), depends, commands);
|
||||||
// TODO: Add "local" target and canonical target name as rules.
|
// TODO: Add "local" target and canonical target name as rules.
|
||||||
|
|
||||||
// Write the requires rule.
|
// Write driver rule for this target.
|
||||||
{
|
this->WriteRequiresRule(ruleFileStream, target, targetFullPath.c_str());
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -980,26 +1274,28 @@ cmLocalUnixMakefileGenerator2
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the build rule.
|
// Write the build rule.
|
||||||
std::string buildComment = linkLanguage;
|
std::string buildEcho = "Linking ";
|
||||||
buildComment += " static library";
|
buildEcho += linkLanguage;
|
||||||
this->OutputMakeRule(ruleFileStream, buildComment.c_str(),
|
switch(target.GetType())
|
||||||
targetFullPath.c_str(),
|
{
|
||||||
depends, commands);
|
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.
|
// TODO: Add "local" target and canonical target name as rules.
|
||||||
|
|
||||||
// Write the requires rule.
|
// Write driver rule for this target.
|
||||||
{
|
this->WriteRequiresRule(ruleFileStream, target, targetFullPath.c_str());
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -1028,7 +1324,7 @@ cmLocalUnixMakefileGenerator2
|
||||||
m_Makefile->GetCurrentDirectory()) == 0)
|
m_Makefile->GetCurrentDirectory()) == 0)
|
||||||
|| (cmSystemTools::GetFilenamePath(
|
|| (cmSystemTools::GetFilenamePath(
|
||||||
source.GetFullPath()).find(
|
source.GetFullPath()).find(
|
||||||
m_Makefile->GetCurrentOutputDirectory()) == 0))
|
m_Makefile->GetStartOutputDirectory()) == 0))
|
||||||
{
|
{
|
||||||
objectName = source.GetSourceName();
|
objectName = source.GetSourceName();
|
||||||
}
|
}
|
||||||
|
@ -1067,7 +1363,7 @@ std::string
|
||||||
cmLocalUnixMakefileGenerator2
|
cmLocalUnixMakefileGenerator2
|
||||||
::ConvertToFullPath(const std::string& localPath)
|
::ConvertToFullPath(const std::string& localPath)
|
||||||
{
|
{
|
||||||
std::string dir = m_Makefile->GetCurrentOutputDirectory();
|
std::string dir = m_Makefile->GetStartOutputDirectory();
|
||||||
dir += "/";
|
dir += "/";
|
||||||
dir += localPath;
|
dir += localPath;
|
||||||
return dir;
|
return dir;
|
||||||
|
@ -1164,7 +1460,7 @@ cmLocalUnixMakefileGenerator2
|
||||||
|
|
||||||
// Get the path to the library.
|
// Get the path to the library.
|
||||||
std::string libPath;
|
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
|
// The target is in the current directory so this makefile will
|
||||||
// know about it already.
|
// know about it already.
|
||||||
|
@ -1244,9 +1540,14 @@ cmLocalUnixMakefileGenerator2
|
||||||
// Call make on the given file.
|
// Call make on the given file.
|
||||||
cmd += "$(MAKE) -f ";
|
cmd += "$(MAKE) -f ";
|
||||||
cmd += file;
|
cmd += file;
|
||||||
|
cmd += " ";
|
||||||
|
|
||||||
// Pass down verbosity level.
|
// 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
|
// Most unix makes will pass the command line flags to make down to
|
||||||
// sub-invoked makes via an environment variable. However, some
|
// sub-invoked makes via an environment variable. However, some
|
||||||
|
@ -1288,8 +1589,17 @@ cmLocalUnixMakefileGenerator2
|
||||||
tgt += ".requires";
|
tgt += ".requires";
|
||||||
this->AppendRecursiveMake(cmd, "Makefile2", tgt.c_str());
|
this->AppendRecursiveMake(cmd, "Makefile2", tgt.c_str());
|
||||||
}
|
}
|
||||||
this->OutputMakeRule(makefileStream, "jump rule for",
|
std::string jumpPreEcho = "Jumping to ";
|
||||||
rt.m_FilePath.c_str(), depends, commands);
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,22 @@ protected:
|
||||||
void GenerateTargetRuleFile(const cmTarget& target);
|
void GenerateTargetRuleFile(const cmTarget& target);
|
||||||
void GenerateObjectRuleFile(const cmTarget& target,
|
void GenerateObjectRuleFile(const cmTarget& target,
|
||||||
const cmSourceFile& source);
|
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 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,
|
void WriteExecutableRule(std::ostream& ruleFileStream,
|
||||||
const char* ruleFileName,
|
const char* ruleFileName,
|
||||||
const cmTarget& target,
|
const cmTarget& target,
|
||||||
|
|
Loading…
Reference in New Issue