ENH: Cleaned up generation of directory-level rules and their support structure. The directorystart rule has been removed in favor of checking the build system in the subdirectory makefile first. The "directory" rule has been renamed "all" since it corresponds to the "all" pass anyway (as against "clean"). Also fixed directory-level rule for preinstall.

This commit is contained in:
Brad King 2006-03-01 18:54:17 -05:00
parent 007421e19c
commit 8d9a997beb
3 changed files with 122 additions and 298 deletions

View File

@ -325,266 +325,107 @@ void cmGlobalUnixMakefileGenerator3
cmakefileStream << " )\n";
}
//----------------------------------------------------------------------------
void
cmGlobalUnixMakefileGenerator3
::WriteDirectoryRules(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg)
::WriteDirectoryRule2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg,
const char* pass, bool check_all,
bool check_relink)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
std::string localName;
std::string makeTargetName;
// Get the relative path to the subdirectory from the top.
std::string makeTarget = lg->GetMakefile()->GetStartOutputDirectory();
makeTarget += "/";
makeTarget += pass;
makeTarget = lg->Convert(makeTarget.c_str(),
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
depends.push_back("cmake_check_build_system");
if (lg->GetParent())
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
std::vector<std::string> depends;
for(cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
l != lg->GetMakefile()->GetTargets().end(); ++l)
{
std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Directory level rules for directory "
<< dir << "\n\n";
localName = dir;
localName += "/directorystart";
makeTargetName = dir;
makeTargetName += "/directory";
std::vector<std::string> all_tgts;
// for all of out targets
for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
l != lg->GetMakefile()->GetTargets().end(); l++)
if((l->second.GetType() == cmTarget::EXECUTABLE) ||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
if((l->second.GetType() == cmTarget::EXECUTABLE) ||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
// Add this to the list of depends rules in this directory.
if((!check_all || l->second.IsInAll()) &&
(!check_relink || l->second.NeedRelinkBeforeInstall()))
{
// Add this to the list of depends rules in this directory.
if(l->second.IsInAll())
{
std::string tname = lg->GetRelativeTargetDirectory(l->second);
tname += "/all";
all_tgts.push_back(tname);
}
}
}
// write the directory rule add in the subdirs
std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
// for each subdir add the directory depend
std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
for (; sdi != subdirs.end(); ++sdi)
{
cmLocalUnixMakefileGenerator3 * lg2 =
static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
dir = lg2->GetMakefile()->GetStartOutputDirectory();
dir += "/directory";
dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
all_tgts.push_back(dir);
}
// write the directory rule
commands.clear();
commands.push_back
(lg->GetRecursiveMakeCall
("CMakeFiles/Makefile2",makeTargetName.c_str()));
// Write the rule.
lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
localName.c_str(), depends, commands, true);
// Write the rule.
commands.clear();
lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
makeTargetName.c_str(), all_tgts, commands, true);
}
// now do the clean targets
if (lg->GetParent())
{
std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
makeTargetName = dir;
makeTargetName += "/clean";
std::vector<std::string> all_tgts;
// for all of out targets
for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
l != lg->GetMakefile()->GetTargets().end(); l++)
{
if((l->second.GetType() == cmTarget::EXECUTABLE) ||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
// Add this to the list of depends rules in this directory.
std::string tname = lg->GetRelativeTargetDirectory(l->second);
tname += "/clean";
all_tgts.push_back(tname);
tname += "/";
tname += pass;
depends.push_back(tname);
}
}
// write the directory rule add in the subdirs
std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
// for each subdir add the directory depend
std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
for (; sdi != subdirs.end(); ++sdi)
{
cmLocalUnixMakefileGenerator3 * lg2 =
static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
dir = lg2->GetMakefile()->GetStartOutputDirectory();
dir += "/clean";
dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
all_tgts.push_back(dir);
}
// write the directory clean rule
commands.clear();
lg->WriteMakeRule(ruleFileStream, "Convenience name for directory clean.",
makeTargetName.c_str(), all_tgts, commands, true);
}
// The directory-level rule should depend on the directory-level
// rules of the subdirectories.
for(std::vector<cmLocalGenerator*>::iterator sdi = lg->GetChildren().begin();
sdi != lg->GetChildren().end(); ++sdi)
{
cmLocalUnixMakefileGenerator3* slg =
static_cast<cmLocalUnixMakefileGenerator3*>(*sdi);
std::string subdir = slg->GetMakefile()->GetStartOutputDirectory();
subdir += "/";
subdir += pass;
subdir = slg->Convert(subdir.c_str(),
cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
depends.push_back(subdir);
}
// Work-around for makes that drop rules that have no dependencies
// or commands.
if(depends.empty() && m_EmptyRuleHackDepends != "")
{
depends.push_back(m_EmptyRuleHackDepends);
}
// Write the rule.
std::string doc = "Convenience name for \"";
doc += pass;
doc += "\" pass in the directory.";
std::vector<std::string> no_commands;
lg->WriteMakeRule(ruleFileStream, doc.c_str(),
makeTarget.c_str(), depends, no_commands, true);
}
//----------------------------------------------------------------------------
void
cmGlobalUnixMakefileGenerator3
::WriteDirectoryRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg)
::WriteDirectoryRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
std::string localName;
std::string makeTargetName;
depends.push_back("cmake_check_build_system");
if (lg->GetParent())
// Only subdirectories need these rules.
if(!lg->GetParent())
{
std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Directory level rules for directory "
<< dir << "\n\n";
localName = dir;
localName += "/directorystart";
makeTargetName = dir;
makeTargetName += "/directory";
std::vector<std::string> all_tgts;
// for all of out targets
for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
l != lg->GetMakefile()->GetTargets().end(); l++)
{
if((l->second.GetType() == cmTarget::EXECUTABLE) ||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
// Add this to the list of depends rules in this directory.
if(l->second.IsInAll())
{
std::string tname = lg->GetRelativeTargetDirectory(l->second);
tname += "/all";
all_tgts.push_back(tname);
}
}
}
// write the directory rule add in the subdirs
std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
// for each subdir add the directory depend
std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
for (; sdi != subdirs.end(); ++sdi)
{
cmLocalUnixMakefileGenerator3 * lg2 =
static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
dir = lg2->GetMakefile()->GetStartOutputDirectory();
dir += "/directory";
dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
all_tgts.push_back(dir);
}
// write the directory rule
commands.clear();
commands.push_back(lg->GetRecursiveMakeCall
("CMakeFiles/Makefile2",makeTargetName.c_str()));
// Write the rule.
lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
localName.c_str(), depends, commands, true);
// Write the rule.
commands.clear();
lg->WriteMakeRule(ruleFileStream, "Convenience name for directory.",
makeTargetName.c_str(), all_tgts, commands, true);
return;
}
// now do the clean targets
if (lg->GetParent())
{
std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
dir = lg->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,cmLocalGenerator::MAKEFILE);
makeTargetName = dir;
makeTargetName += "/clean";
std::vector<std::string> all_tgts;
// for all of out targets
for (cmTargets::iterator l = lg->GetMakefile()->GetTargets().begin();
l != lg->GetMakefile()->GetTargets().end(); l++)
{
if((l->second.GetType() == cmTarget::EXECUTABLE) ||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
// Add this to the list of depends rules in this directory.
std::string tname = lg->GetRelativeTargetDirectory(l->second);
tname += "/clean";
all_tgts.push_back(tname);
}
}
// write the directory rule add in the subdirs
std::vector<cmLocalGenerator *> subdirs = lg->GetChildren();
// for each subdir add the directory depend
std::vector<cmLocalGenerator *>::iterator sdi = subdirs.begin();
for (; sdi != subdirs.end(); ++sdi)
{
cmLocalUnixMakefileGenerator3 * lg2 =
static_cast<cmLocalUnixMakefileGenerator3 *>(*sdi);
dir = lg2->GetMakefile()->GetStartOutputDirectory();
dir += "/clean";
dir = lg2->Convert(dir.c_str(),cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
all_tgts.push_back(dir);
}
// write the directory clean rule
commands.clear();
lg->WriteMakeRule(ruleFileStream, "Convenience name for directory clean.",
makeTargetName.c_str(), all_tgts, commands, true);
}
// Begin the directory-level rules section.
std::string dir = lg->GetMakefile()->GetStartOutputDirectory();
dir = lg->Convert(dir.c_str(), cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::MAKEFILE);
lg->WriteDivider(ruleFileStream);
ruleFileStream
<< "# Directory level rules for directory "
<< dir << "\n\n";
// Write directory-level rules for "all".
this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false);
// Write directory-level rules for "clean".
this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false);
// Write directory-level rules for "preinstall".
this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", false, true);
}
//----------------------------------------------------------------------------
@ -752,7 +593,7 @@ cmGlobalUnixMakefileGenerator3
commands.push_back(lg->GetRecursiveMakeCall
(makefileName.c_str(), localName.c_str()));
this->AppendGlobalTargetDepends(depends,t->second);
lg->WriteMakeRule(ruleFileStream, "Pre-intsall relink rule for target.",
lg->WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.",
localName.c_str(), depends, commands, true);
depends.clear();
depends.push_back(localName);

View File

@ -104,10 +104,12 @@ protected:
cmLocalUnixMakefileGenerator3 *,
bool exclude);
void WriteDirectoryRules(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg);
void WriteDirectoryRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg);
void WriteDirectoryRule2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg,
const char* pass, bool check_all,
bool check_relink);
void WriteDirectoryRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg);
void AppendGlobalTargetDepends(std::vector<std::string>& depends,
cmTarget& target);

View File

@ -631,10 +631,16 @@ cmLocalUnixMakefileGenerator3
runRule += " --check-build-system ";
runRule += this->Convert(cmakefileName.c_str(),NONE,SHELL);
runRule += " 0";
std::vector<std::string> no_depends;
std::vector<std::string> commands;
commands.push_back(runRule);
if(m_Parent)
{
this->CreateCDCommand(commands,
m_Makefile->GetHomeOutputDirectory(),
m_Makefile->GetStartOutputDirectory());
}
this->WriteMakeRule(makefileStream,
"Special rule to run CMake to check the build system "
"integrity.\n"
@ -1284,52 +1290,6 @@ void cmLocalUnixMakefileGenerator3
}
}
// Write special "install" target to run cmake_install.cmake script.
{
std::vector<std::string> depends;
depends.push_back("preinstall");
std::vector<std::string> commands;
std::string cmd;
if(m_Makefile->GetDefinition("CMake_BINARY_DIR"))
{
// We are building CMake itself. We cannot use the original
// executable to install over itself.
cmd = m_ExecutableOutputPath;
cmd += "cmake";
cmd = this->Convert(cmd.c_str(),START_OUTPUT,SHELL);
}
else
{
cmd = "$(CMAKE_COMMAND)";
}
cmd += " -P cmake_install.cmake";
commands.push_back(cmd);
this->WriteMakeRule(ruleFileStream,
"Special rule to run installation script.",
"old_install", depends, commands, true);
commands.clear();
depends.clear();
const char* noall =
m_Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
if(!noall || cmSystemTools::IsOff(noall))
{
// Drive the build before installing.
depends.push_back("all");
}
else
{
// At least make sure the build system is up to date.
depends.push_back("cmake_check_build_system");
}
commands.push_back(this->GetRecursiveMakeCall
("CMakeFiles/Makefile2", "preinstall"));
this->WriteMakeRule(ruleFileStream,
"Prepare targets for installation.",
"preinstall", depends, commands, true);
}
this->WriteSpecialTargetsTop(ruleFileStream);
std::vector<std::string> depends;
@ -1337,14 +1297,9 @@ void cmLocalUnixMakefileGenerator3
// Write the all rule.
std::string dir = m_Makefile->GetStartOutputDirectory();
dir += "/directorystart";
dir += "/all";
dir = this->Convert(dir.c_str(),HOME_OUTPUT,MAKEFILE);
// if at the top the rule is called all
if (!m_Parent)
{
dir = "all";
depends.push_back("cmake_check_build_system");
}
depends.push_back("cmake_check_build_system");
commands.push_back
(this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str()));
this->CreateCDCommand(commands,
@ -1367,6 +1322,32 @@ void cmLocalUnixMakefileGenerator3
this->WriteMakeRule(ruleFileStream, "The main clean target", "clean",
depends, commands, true);
// Write the preinstall rule.
dir = m_Makefile->GetStartOutputDirectory();
dir += "/preinstall";
dir = this->Convert(dir.c_str(), HOME_OUTPUT,MAKEFILE);
commands.clear();
depends.clear();
const char* noall =
m_Makefile->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
if(!noall || cmSystemTools::IsOff(noall))
{
// Drive the build before installing.
depends.push_back("all");
}
else
{
// At least make sure the build system is up to date.
depends.push_back("cmake_check_build_system");
}
commands.push_back
(this->GetRecursiveMakeCall("CMakeFiles/Makefile2", dir.c_str()));
this->CreateCDCommand(commands,
m_Makefile->GetHomeOutputDirectory(),
m_Makefile->GetStartOutputDirectory());
this->WriteMakeRule(ruleFileStream, "Prepare targets for installation.",
"preinstall", depends, commands, true);
// write the depend rule, really a recompute depends rule
depends.clear();
commands.clear();