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();
// write the main makefile
this->WriteMainMakefile();
this->WriteMainMakefile2();
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()
{
// Open the output file. This should not be copy-if-different
@ -368,51 +305,6 @@ void cmGlobalUnixMakefileGenerator3
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
@ -680,48 +572,52 @@ cmGlobalUnixMakefileGenerator3
void
cmGlobalUnixMakefileGenerator3
::WriteConvenienceRules(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg,
std::set<cmStdString> &emitted)
{
std::vector<std::string> depends;
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");
// for each target Generate the rule files for each target.
cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
// write the target convenience rules
unsigned int i;
cmLocalUnixMakefileGenerator3 *lg;
for (i = 0; i < m_LocalGenerators.size(); ++i)
{
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))
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[i]);
// for each target Generate the rule files for each target.
cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{
// 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)
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
<< "# Target rules for targets named "
<< t->second.GetName() << "\n\n";
// Write the rule.
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
t->second.GetName()));
depends.clear();
depends.push_back("cmake_check_build_system");
lg->WriteMakeRule(ruleFileStream,
"Build rule for target.",
t->second.GetName(), depends, commands);
// 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)
{
// Add a rule to build the target by name.
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Target rules for targets named "
<< t->second.GetName() << "\n\n";
// Write the rule.
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall("CMakeFiles/Makefile2",
t->second.GetName()));
depends.clear();
depends.push_back("cmake_check_build_system");
lg->WriteMakeRule(ruleFileStream,
"Build rule for target.",
t->second.GetName(), depends, commands);
}
}
}
}
@ -947,12 +843,9 @@ cmGlobalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
void
cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
void cmGlobalUnixMakefileGenerator3::WriteHelpRule
(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3 *lg)
{
cmLocalUnixMakefileGenerator3 *lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(m_LocalGenerators[0]);
// add the help target
std::string path;
std::vector<std::string> no_depends;
@ -970,25 +863,30 @@ cmGlobalUnixMakefileGenerator3::WriteHelpRule(std::ostream& ruleFileStream)
// for each local generator
unsigned int i;
cmLocalUnixMakefileGenerator3 *lg2;
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.
cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
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())
{
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))
// for each target Generate the rule files for each target.
cmTargets& targets = lg->GetMakefile()->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{
if(emittedTargets.insert(t->second.GetName()).second)
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))
{
path = "... ";
path += t->second.GetName();
lg->AppendEcho(commands,path.c_str());
if(emittedTargets.insert(t->second.GetName()).second)
{
path = "... ";
path += t->second.GetName();
lg->AppendEcho(commands,path.c_str());
}
}
}
}

View File

@ -88,17 +88,18 @@ public:
void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
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:
void WriteMainMakefile();
void WriteMainMakefile2();
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,
cmLocalUnixMakefileGenerator3 *,
bool exclude);

View File

@ -1390,7 +1390,8 @@ cmLocalUnixMakefileGenerator3
m_Makefile->GetRequiredDefinition(linkRuleVar.c_str());
std::vector<std::string> 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());
// Add a rule to create necessary symlinks for the library.
@ -1720,7 +1721,8 @@ cmLocalUnixMakefileGenerator3
std::string linkRule = m_Makefile->GetRequiredDefinition(linkRuleVar);
std::vector<std::string> 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());
// Add a rule to create necessary symlinks for the library.
@ -2346,7 +2348,8 @@ cmLocalUnixMakefileGenerator3
}
// 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());
}
@ -2814,39 +2817,25 @@ cmLocalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
void cmLocalUnixMakefileGenerator3
::WriteLocalAllRules(std::ostream& ruleFileStream)
{
// only write the local Makefile if we are not at the top
if (!m_Parent)
{
return;
}
// generate the includes
std::string ruleFileName = "Makefile";
// Open the rule file. This should be copy-if-different because the
// rules may depend on this file itself.
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
ruleFileStream.SetCopyIfDifferent(true);
if(!ruleFileStream)
{
return;
}
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)
{
dir = "all";
}
this->CreateJumpCommand(commands,"CMakeFiles/Makefile2",dir);
this->WriteMakeRule(ruleFileStream, "The main all target", "all", depends, commands);
@ -2858,10 +2847,61 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
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);
// 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
std::string ruleFileName = "Makefile";
// Open the rule file. This should be copy-if-different because the
// rules may depend on this file itself.
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
ruleFileStream.SetCopyIfDifferent(true);
if(!ruleFileStream)
{
return;
}
// write the all rules
this->WriteLocalAllRules(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> commands;
// now write out the object rules
// for each object file name
for (std::map<cmStdString,std::vector<cmTarget *> >::iterator lo =
@ -2885,11 +2925,20 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
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
::WriteLocalMakefileTargets(std::ostream& ruleFileStream)
::WriteLocalMakefileTargets(std::ostream& ruleFileStream,
std::set<cmStdString> &emitted)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
@ -2906,16 +2955,24 @@ void cmLocalUnixMakefileGenerator3
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(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 += "/rule";
commands.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.",
localName.c_str(), depends, commands);
// Add a target with the canonical name (no prefix, suffix or path).
if(localName != t->second.GetName())
{
@ -2929,21 +2986,27 @@ 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)
{
// On Windows we must perform each step separately and then change
// back because the shell keeps the working directory between
// commands.
std::string cmd = "cd ";
cmd += this->ConvertToOutputForExisting
(m_Makefile->GetStartOutputDirectory());
cmd += this->ConvertToOutputForExisting(tgtDir);
commands.insert(commands.begin(),cmd);
// Change back to the starting directory. Any trailing slash must be
// removed to avoid problems with Borland Make.
std::string back = m_Makefile->GetHomeOutputDirectory();
std::string back = retDir;
if(back.size() && back[back.size()-1] == '/')
{
back = back.substr(0, back.size()-1);
@ -2961,7 +3024,7 @@ void cmLocalUnixMakefileGenerator3
for (; i != commands.end(); ++i)
{
std::string cmd = "cd ";
cmd += this->ConvertToOutputForExisting(m_Makefile->GetStartOutputDirectory());
cmd += this->ConvertToOutputForExisting(tgtDir);
cmd += " && ";
cmd += *i;
*i = cmd;
@ -2978,7 +3041,9 @@ void cmLocalUnixMakefileGenerator3
commands.push_back(this->GetRecursiveMakeCall
(MakefileName,localName.c_str()));
this->CreateCDCommand(commands);
this->CreateCDCommand(commands,
m_Makefile->GetHomeOutputDirectory(),
m_Makefile->GetStartOutputDirectory());
}
//----------------------------------------------------------------------------
@ -3055,47 +3120,6 @@ cmLocalUnixMakefileGenerator3
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
::WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &target)

View File

@ -154,13 +154,17 @@ public:
void AppendEcho(std::vector<std::string>& commands,
const char* text);
// write the target rules for the local Makefile into the stream
void WriteLocalAllRules(std::ostream& ruleFileStream);
protected:
// write the depend info
void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
// 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
void WriteHelpRule(std::ostream& ruleFileStream);
@ -171,7 +175,8 @@ protected:
std::string & localName);
// 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
// and m_ExecutableOutputPath