From 8d9a997beb03e1ac668b4aaabe363f1d3d552b00 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 1 Mar 2006 18:54:17 -0500 Subject: [PATCH] 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. --- Source/cmGlobalUnixMakefileGenerator3.cxx | 321 ++++++---------------- Source/cmGlobalUnixMakefileGenerator3.h | 10 +- Source/cmLocalUnixMakefileGenerator3.cxx | 89 +++--- 3 files changed, 122 insertions(+), 298 deletions(-) diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index d74ebf987..f9a6daac4 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -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 depends; - std::vector 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 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 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 subdirs = lg->GetChildren(); - - // for each subdir add the directory depend - std::vector::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - cmLocalUnixMakefileGenerator3 * lg2 = - static_cast(*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 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 subdirs = lg->GetChildren(); - - // for each subdir add the directory depend - std::vector::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - cmLocalUnixMakefileGenerator3 * lg2 = - static_cast(*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::iterator sdi = lg->GetChildren().begin(); + sdi != lg->GetChildren().end(); ++sdi) + { + cmLocalUnixMakefileGenerator3* slg = + static_cast(*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 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 depends; - std::vector 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 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 subdirs = lg->GetChildren(); - - // for each subdir add the directory depend - std::vector::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - cmLocalUnixMakefileGenerator3 * lg2 = - static_cast(*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 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 subdirs = lg->GetChildren(); - - // for each subdir add the directory depend - std::vector::iterator sdi = subdirs.begin(); - for (; sdi != subdirs.end(); ++sdi) - { - cmLocalUnixMakefileGenerator3 * lg2 = - static_cast(*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); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 23ad6f1f2..33083ecd6 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -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& depends, cmTarget& target); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index a052c86a7..c95832218 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -631,10 +631,16 @@ cmLocalUnixMakefileGenerator3 runRule += " --check-build-system "; runRule += this->Convert(cmakefileName.c_str(),NONE,SHELL); runRule += " 0"; - + std::vector no_depends; std::vector 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 depends; - depends.push_back("preinstall"); - std::vector 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 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();