소스 검색

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.

Brad King 20 년 전
부모
커밋
8d9a997beb
3개의 변경된 파일121개의 추가작업 그리고 297개의 파일을 삭제
  1. 80 239
      Source/cmGlobalUnixMakefileGenerator3.cxx
  2. 6 4
      Source/cmGlobalUnixMakefileGenerator3.h
  3. 35 54
      Source/cmLocalUnixMakefileGenerator3.cxx

+ 80 - 239
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<std::string> depends;  
-  std::vector<std::string> commands;
-  std::string localName;
-  std::string makeTargetName;
-
-  depends.push_back("cmake_check_build_system");
-  if (lg->GetParent())
+  // 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);
+
+  // 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);
-          }
+        std::string tname = lg->GetRelativeTargetDirectory(l->second);
+        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 += "/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())
+  // 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)
     {
-    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);
+    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);

+ 6 - 4
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<std::string>& depends,
                                  cmTarget& target);

+ 35 - 54
Source/cmLocalUnixMakefileGenerator3.cxx

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