ENH: big cleanup and fix for jump commands

This commit is contained in:
Ken Martin 2005-10-20 13:40:28 -04:00
parent 097debb55a
commit 929553a02e
4 changed files with 177 additions and 249 deletions

View File

@ -101,73 +101,10 @@ void cmGlobalUnixMakefileGenerator3::Generate()
this->cmGlobalGenerator::Generate(); this->cmGlobalGenerator::Generate();
// write the main makefile // write the main makefile
this->WriteMainMakefile();
this->WriteMainMakefile2(); this->WriteMainMakefile2();
this->WriteMainCMakefile(); this->WriteMainCMakefile();
} }
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile()
{
// Open the output file. This should not be copy-if-different
// because the check-build-system step compares the makefile time to
// see if the build system must be regenerated.
std::string makefileName =
this->GetCMakeInstance()->GetHomeOutputDirectory();
makefileName += "/Makefile";
cmGeneratedFileStream makefileStream(makefileName.c_str());
if(!makefileStream)
{
return;
}
// get a local generator for some useful methods
cmLocalUnixMakefileGenerator3 *lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
// Write the do not edit header.
lg->WriteDisclaimer(makefileStream);
// Write the main entry point target. This must be the VERY first
// target so that make with no arguments will run it.
// Just depend on the all target to drive the build.
std::vector<std::string> depends;
std::vector<std::string> no_commands;
depends.push_back("all");
// Write the rule.
lg->WriteMakeRule(makefileStream,
"Default target executed when no arguments are "
"given to make.",
"default_target",
depends,
no_commands);
lg->WriteMakeVariables(makefileStream);
lg->WriteSpecialTargetsTop(makefileStream);
this->WriteAllRules(lg,makefileStream);
// Keep track of targets already listed.
std::set<cmStdString> emittedTargets;
// write the target convenience rules
unsigned int i;
for (i = 0; i < m_LocalGenerators.size(); ++i)
{
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
this->WriteConvenienceRules(makefileStream,lg,emittedTargets);
}
// add a help target as long as there isn;t a real target named help
if(emittedTargets.insert("help").second)
{
this->WriteHelpRule(makefileStream);
}
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
lg->WriteSpecialTargetsBottom(makefileStream);
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2() void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
{ {
// Open the output file. This should not be copy-if-different // Open the output file. This should not be copy-if-different
@ -368,51 +305,6 @@ void cmGlobalUnixMakefileGenerator3
cmakefileStream << " )\n"; cmakefileStream << " )\n";
} }
//----------------------------------------------------------------------------
void cmGlobalUnixMakefileGenerator3
::WriteAllRules(cmLocalUnixMakefileGenerator3 *lg,
std::ostream& makefileStream)
{
// Write section header.
lg->WriteDivider(makefileStream);
makefileStream
<< "# Rules to build dependencies and targets.\n"
<< "\n";
std::vector<std::string> depends;
std::vector<std::string> commands;
// Check the build system in this directory.
depends.push_back("cmake_check_build_system");
commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2","all"));
// Write the rule.
lg->WriteMakeRule(makefileStream, "The main all target", "all", depends, commands);
// write the clean
depends.clear();
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2","clean"));
lg->WriteMakeRule(makefileStream, "The main clean target", "clean",
depends, commands);
// write the depend rule, really a recompute depends rule
depends.clear();
commands.clear();
std::string cmakefileName = "CMakeFiles/Makefile.cmake";
std::string runRule =
"$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
runRule += " --check-build-system ";
runRule += lg->Convert(cmakefileName.c_str(),cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
runRule += " 1";
commands.push_back(runRule);
lg->WriteMakeRule(makefileStream, "clear depends",
"depend",
depends, commands);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void
@ -680,17 +572,20 @@ cmGlobalUnixMakefileGenerator3
void void
cmGlobalUnixMakefileGenerator3 cmGlobalUnixMakefileGenerator3
::WriteConvenienceRules(std::ostream& ruleFileStream, ::WriteConvenienceRules(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg,
std::set<cmStdString> &emitted) std::set<cmStdString> &emitted)
{ {
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> commands; std::vector<std::string> commands;
// write the directory level rules for this local gen
//this->WriteDirectoryRules(ruleFileStream,lg);
depends.push_back("cmake_check_build_system"); depends.push_back("cmake_check_build_system");
// write the target convenience rules
unsigned int i;
cmLocalUnixMakefileGenerator3 *lg;
for (i = 0; i < m_LocalGenerators.size(); ++i)
{
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
// for each target Generate the rule files for each target. // for each target Generate the rule files for each target.
cmTargets& targets = lg->GetMakefile()->GetTargets(); cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
@ -725,6 +620,7 @@ cmGlobalUnixMakefileGenerator3
} }
} }
} }
}
} }
@ -947,12 +843,9 @@ cmGlobalUnixMakefileGenerator3
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void cmGlobalUnixMakefileGenerator3::WriteHelpRule
cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream) (std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *lg)
{ {
cmLocalUnixMakefileGenerator3 *lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
// add the help target // add the help target
std::string path; std::string path;
std::vector<std::string> no_depends; std::vector<std::string> no_depends;
@ -970,10 +863,14 @@ cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
// for each local generator // for each local generator
unsigned int i; unsigned int i;
cmLocalUnixMakefileGenerator3 *lg2;
for (i = 0; i < m_LocalGenerators.size(); ++i) for (i = 0; i < m_LocalGenerators.size(); ++i)
{ {
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]); lg2 = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
// for the passed in makefile or if this is the top Makefile wripte out
// the targets
if (lg2 == lg || !lg->GetParent())
{
// for each target Generate the rule files for each target. // for each target Generate the rule files for each target.
cmTargets& targets = lg->GetMakefile()->GetTargets(); cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t) for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
@ -993,6 +890,7 @@ cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
} }
} }
} }
}
lg->WriteMakeRule(ruleFileStream, "Help Target", lg->WriteMakeRule(ruleFileStream, "Help Target",
"help:", "help:",
no_depends, commands); no_depends, commands);

View File

@ -88,17 +88,18 @@ public:
void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream, void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
std::vector<cmLocalGenerator *> &); std::vector<cmLocalGenerator *> &);
// write out the help rule listing the valid targets
void WriteHelpRule(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *);
// write the top lvel target rules
void WriteConvenienceRules(std::ostream& ruleFileStream,
std::set<cmStdString> &emitted);
protected: protected:
void WriteMainMakefile();
void WriteMainMakefile2(); void WriteMainMakefile2();
void WriteMainCMakefile(); void WriteMainCMakefile();
void WriteAllRules(cmLocalUnixMakefileGenerator3 *lg,
std::ostream& makefileStream);
void WriteHelpRule(std::ostream& ruleFileStream);
void WriteConvenienceRules(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *,
std::set<cmStdString> &emitted);
void WriteConvenienceRules2(std::ostream& ruleFileStream, void WriteConvenienceRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *, cmLocalUnixMakefileGenerator3 *,
bool exclude); bool exclude);

View File

@ -1390,7 +1390,8 @@ cmLocalUnixMakefileGenerator3
m_Makefile->GetRequiredDefinition(linkRuleVar.c_str()); m_Makefile->GetRequiredDefinition(linkRuleVar.c_str());
std::vector<std::string> commands1; std::vector<std::string> commands1;
cmSystemTools::ExpandListArgument(linkRule, commands1); cmSystemTools::ExpandListArgument(linkRule, commands1);
this->CreateCDCommand(commands1); this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeOutputDirectory());
commands.insert(commands.end(), commands1.begin(), commands1.end()); commands.insert(commands.end(), commands1.begin(), commands1.end());
// Add a rule to create necessary symlinks for the library. // Add a rule to create necessary symlinks for the library.
@ -1720,7 +1721,8 @@ cmLocalUnixMakefileGenerator3
std::string linkRule = m_Makefile->GetRequiredDefinition(linkRuleVar); std::string linkRule = m_Makefile->GetRequiredDefinition(linkRuleVar);
std::vector<std::string> commands1; std::vector<std::string> commands1;
cmSystemTools::ExpandListArgument(linkRule, commands1); cmSystemTools::ExpandListArgument(linkRule, commands1);
this->CreateCDCommand(commands1); this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeOutputDirectory());
commands.insert(commands.end(), commands1.begin(), commands1.end()); commands.insert(commands.end(), commands1.begin(), commands1.end());
// Add a rule to create necessary symlinks for the library. // Add a rule to create necessary symlinks for the library.
@ -2346,7 +2348,8 @@ cmLocalUnixMakefileGenerator3
} }
// push back the custom commands // push back the custom commands
this->CreateCDCommand(commands1); this->CreateCDCommand(commands1,m_Makefile->GetStartOutputDirectory(),
m_Makefile->GetHomeOutputDirectory());
commands.insert(commands.end(), commands1.begin(), commands1.end()); commands.insert(commands.end(), commands1.begin(), commands1.end());
} }
@ -2814,14 +2817,55 @@ cmLocalUnixMakefileGenerator3
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::WriteLocalMakefile() void cmLocalUnixMakefileGenerator3
::WriteLocalAllRules(std::ostream& ruleFileStream)
{ {
// only write the local Makefile if we are not at the top this->WriteDisclaimer(ruleFileStream);
this->WriteMakeVariables(ruleFileStream);
this->WriteSpecialTargetsTop(ruleFileStream);
std::vector<std::string> depends;
std::vector<std::string> commands;
// Write the all rule.
std::string dir = m_Makefile->GetStartOutputDirectory();
dir += "/directorystart";
dir = this->Convert(dir.c_str(),HOME_OUTPUT,MAKEFILE);
// if at the top the rule is called all
if (!m_Parent) if (!m_Parent)
{ {
return; dir = "all";
} }
this->CreateJumpCommand(commands,"CMakeFiles/Makefile2",dir);
this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands);
// Write the clean rule.
dir = m_Makefile->GetStartOutputDirectory();
dir += "/clean";
dir = this->Convert(dir.c_str(),HOME_OUTPUT,MAKEFILE);
commands.clear();
this->CreateJumpCommand(commands,"CMakeFiles/Makefile2",dir);
this->WriteMakeRule(ruleFileStream, "The main clean target", "clean", depends, commands);
// write the depend rule, really a recompute depends rule
depends.clear();
commands.clear();
std::string cmakefileName = "CMakeFiles/Makefile.cmake";
std::string runRule =
"$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)";
runRule += " --check-build-system ";
runRule += this->Convert(cmakefileName.c_str(),cmLocalGenerator::NONE,
cmLocalGenerator::SHELL);
runRule += " 1";
commands.push_back(runRule);
this->WriteMakeRule(ruleFileStream, "clear depends",
"depend",
depends, commands);
}
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
{
// generate the includes // generate the includes
std::string ruleFileName = "Makefile"; std::string ruleFileName = "Makefile";
@ -2834,34 +2878,30 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
{ {
return; return;
} }
this->WriteDisclaimer(ruleFileStream);
this->WriteMakeVariables(ruleFileStream); // write the all rules
this->WriteLocalAllRules(ruleFileStream);
this->WriteSpecialTargetsTop(ruleFileStream); // Keep track of targets already listed.
std::set<cmStdString> emittedTargets;
// only write local targets unless at the top
if (m_Parent)
{
// write our targets, and while doing it collect up the object
// file rules
this->WriteLocalMakefileTargets(ruleFileStream,emittedTargets);
}
else
{
cmGlobalUnixMakefileGenerator3 *gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(m_GlobalGenerator);
gg->WriteConvenienceRules(ruleFileStream,emittedTargets);
}
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> commands; std::vector<std::string> commands;
// Write the all rule.
std::string dir = m_Makefile->GetStartOutputDirectory();
dir += "/directorystart";
dir = this->Convert(dir.c_str(),HOME_OUTPUT,MAKEFILE);
this->CreateJumpCommand(commands,"CMakeFiles/Makefile2",dir);
this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands);
// Write the clean rule.
dir = m_Makefile->GetStartOutputDirectory();
dir += "/clean";
dir = this->Convert(dir.c_str(),HOME_OUTPUT,MAKEFILE);
commands.clear();
this->CreateJumpCommand(commands,"CMakeFiles/Makefile2",dir);
this->WriteMakeRule(ruleFileStream, "The main clean target", "clean", depends, commands);
// write our targets, and while doing it collect up the object
// file rules
this->WriteLocalMakefileTargets(ruleFileStream);
// now write out the object rules // now write out the object rules
// for each object file name // for each object file name
for (std::map<cmStdString,std::vector<cmTarget *> >::iterator lo = for (std::map<cmStdString,std::vector<cmTarget *> >::iterator lo =
@ -2885,11 +2925,20 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
lo->first.c_str(), depends, commands); lo->first.c_str(), depends, commands);
} }
this->WriteHelpRule(ruleFileStream); // add a help target as long as there isn;t a real target named help
if(emittedTargets.insert("help").second)
{
cmGlobalUnixMakefileGenerator3 *gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(m_GlobalGenerator);
gg->WriteHelpRule(ruleFileStream,this);
}
this->WriteSpecialTargetsBottom(ruleFileStream);
} }
void cmLocalUnixMakefileGenerator3 void cmLocalUnixMakefileGenerator3
::WriteLocalMakefileTargets(std::ostream& ruleFileStream) ::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
std::set<cmStdString> &emitted)
{ {
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> commands; std::vector<std::string> commands;
@ -2906,13 +2955,21 @@ void cmLocalUnixMakefileGenerator3
(t->second.GetType() == cmTarget::MODULE_LIBRARY) || (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(t->second.GetType() == cmTarget::UTILITY)) (t->second.GetType() == cmTarget::UTILITY))
{ {
// Add a rule to build the target by name. emitted.insert(t->second.GetName());
// for subdirs add a rule to build this specific target by name.
localName = this->GetRelativeTargetDirectory(t->second); localName = this->GetRelativeTargetDirectory(t->second);
localName += "/rule"; localName += "/rule";
commands.clear(); commands.clear();
depends.clear(); depends.clear();
this->CreateJumpCommand(commands,"CMakeFiles/Makefile2",localName); // Build the target for this pass.
commands.push_back(this->GetRecursiveMakeCall
("CMakeFiles/Makefile2",localName.c_str()));
this->CreateCDCommand(commands,
m_Makefile->GetHomeOutputDirectory(),
m_Makefile->GetStartOutputDirectory());
this->WriteMakeRule(ruleFileStream, "Convenience name for target.", this->WriteMakeRule(ruleFileStream, "Convenience name for target.",
localName.c_str(), depends, commands); localName.c_str(), depends, commands);
@ -2929,21 +2986,27 @@ void cmLocalUnixMakefileGenerator3
} }
void cmLocalUnixMakefileGenerator3 void cmLocalUnixMakefileGenerator3
::CreateCDCommand(std::vector<std::string>& commands) ::CreateCDCommand(std::vector<std::string>& commands, const char *tgtDir,
const char *retDir)
{ {
// do we need to cd?
if (!strcmp(tgtDir,retDir))
{
return;
}
if(m_WindowsShell) if(m_WindowsShell)
{ {
// On Windows we must perform each step separately and then change // On Windows we must perform each step separately and then change
// back because the shell keeps the working directory between // back because the shell keeps the working directory between
// commands. // commands.
std::string cmd = "cd "; std::string cmd = "cd ";
cmd += this->ConvertToOutputForExisting cmd += this->ConvertToOutputForExisting(tgtDir);
(m_Makefile->GetStartOutputDirectory());
commands.insert(commands.begin(),cmd); commands.insert(commands.begin(),cmd);
// Change back to the starting directory. Any trailing slash must be // Change back to the starting directory. Any trailing slash must be
// removed to avoid problems with Borland Make. // removed to avoid problems with Borland Make.
std::string back = m_Makefile->GetHomeOutputDirectory(); std::string back = retDir;
if(back.size() && back[back.size()-1] == '/') if(back.size() && back[back.size()-1] == '/')
{ {
back = back.substr(0, back.size()-1); back = back.substr(0, back.size()-1);
@ -2961,7 +3024,7 @@ void cmLocalUnixMakefileGenerator3
for (; i != commands.end(); ++i) for (; i != commands.end(); ++i)
{ {
std::string cmd = "cd "; std::string cmd = "cd ";
cmd += this->ConvertToOutputForExisting(m_Makefile->GetStartOutputDirectory()); cmd += this->ConvertToOutputForExisting(tgtDir);
cmd += " && "; cmd += " && ";
cmd += *i; cmd += *i;
*i = cmd; *i = cmd;
@ -2978,7 +3041,9 @@ void cmLocalUnixMakefileGenerator3
commands.push_back(this->GetRecursiveMakeCall commands.push_back(this->GetRecursiveMakeCall
(MakefileName,localName.c_str())); (MakefileName,localName.c_str()));
this->CreateCDCommand(commands); this->CreateCDCommand(commands,
m_Makefile->GetHomeOutputDirectory(),
m_Makefile->GetStartOutputDirectory());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -3055,47 +3120,6 @@ cmLocalUnixMakefileGenerator3
return cmd; return cmd;
} }
//----------------------------------------------------------------------------
void
cmLocalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
{
// add the help target
std::string path;
std::vector<std::string> no_depends;
std::vector<std::string> commands;
this->AppendEcho(commands,
"The following are some of the valid targets for this Makefile:");
this->AppendEcho(commands,"... all (the default if no target is provided)");
this->AppendEcho(commands,"... clean");
this->AppendEcho(commands,"... install");
this->AppendEcho(commands,"... rebuild_cache");
// Keep track of targets already listed.
std::set<cmStdString> emittedTargets;
// for each target Generate the rule files for each target.
cmTargets& targets = this->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))
{
if(emittedTargets.insert(t->second.GetName()).second)
{
path = "... ";
path += t->second.GetName();
this->AppendEcho(commands,path.c_str());
}
}
}
this->WriteMakeRule(ruleFileStream, "Help Target",
"help:",
no_depends, commands);
ruleFileStream << "\n\n";
}
void cmLocalUnixMakefileGenerator3 void cmLocalUnixMakefileGenerator3
::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target) ::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)

View File

@ -154,13 +154,17 @@ public:
void AppendEcho(std::vector<std::string>& commands, void AppendEcho(std::vector<std::string>& commands,
const char* text); const char* text);
// write the target rules for the local Makefile into the stream
void WriteLocalAllRules(std::ostream& ruleFileStream);
protected: protected:
// write the depend info // write the depend info
void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt); void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
// write the target rules for the local Makefile into the stream // write the target rules for the local Makefile into the stream
void WriteLocalMakefileTargets(std::ostream& ruleFileStream); void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
std::set<cmStdString> &emitted);
// write the local help rule // write the local help rule
void WriteHelpRule(std::ostream& ruleFileStream); void WriteHelpRule(std::ostream& ruleFileStream);
@ -171,7 +175,8 @@ protected:
std::string & localName); std::string & localName);
// create a command that cds to the start dir then runs the commands // create a command that cds to the start dir then runs the commands
void CreateCDCommand(std::vector<std::string>& commands); void CreateCDCommand(std::vector<std::string>& commands,
const char *targetDir, const char *returnDir);
// these two methods just compute reasonable values for m_LibraryOutputPath // these two methods just compute reasonable values for m_LibraryOutputPath
// and m_ExecutableOutputPath // and m_ExecutableOutputPath