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();