Browse Source

ENH: Add a notion of a global target

Andy Cedilnik 19 years ago
parent
commit
12dc64c7f5
3 changed files with 214 additions and 75 deletions
  1. 159 0
      Source/cmGlobalGenerator.cxx
  2. 15 0
      Source/cmGlobalGenerator.h
  3. 40 75
      Source/cmLocalUnixMakefileGenerator3.cxx

+ 159 - 0
Source/cmGlobalGenerator.cxx

@@ -671,8 +671,36 @@ void cmGlobalGenerator::Generate()
 {
   // For each existing cmLocalGenerator
   unsigned int i;
+
+  // Consolidate global targets
+  cmTargets globalTargets;
+  this->CreateDefaultGlobalTargets(&globalTargets);
   for (i = 0; i < m_LocalGenerators.size(); ++i)
     {
+    cmTargets* targets = &(m_LocalGenerators[i]->GetMakefile()->GetTargets());
+    cmTargets::iterator tarIt;
+    for ( tarIt = targets->begin(); tarIt != targets->end(); ++ tarIt )
+      {
+      if ( tarIt->second.GetType() == cmTarget::GLOBAL_TARGET )
+        {
+        globalTargets[tarIt->first] = tarIt->second;
+        }
+      }
+    }
+    {
+    cmTargets::iterator tarIt;
+    std::cout << "Global targets:" << std::endl;
+    for ( tarIt = globalTargets.begin(); tarIt != globalTargets.end(); ++ tarIt )
+      {
+      std::cout << "* " << tarIt->first.c_str() << std::endl;
+      }
+    }
+  
+  // Generate project files
+  for (i = 0; i < m_LocalGenerators.size(); ++i)
+    {
+    cmTargets* targets = &(m_LocalGenerators[i]->GetMakefile()->GetTargets());
+    targets->insert(globalTargets.begin(), globalTargets.end());
     m_LocalGenerators[i]->Generate();
     m_LocalGenerators[i]->GenerateInstallRules();
     m_LocalGenerators[i]->GenerateTestFiles();
@@ -1186,6 +1214,137 @@ void cmGlobalGenerator::SetupTests()
     }
 }
 
+void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
+{
+  cmMakefile* mf = m_LocalGenerators[0]->GetMakefile();
+  // CPack
+  cmCustomCommandLines cpackCommandLines;
+  std::vector<std::string> depends;
+  cmCustomCommandLine singleLine;
+  cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end());
+  singleLine.erase(singleLine.begin(), singleLine.end());
+  depends.erase(depends.begin(), depends.end());
+  singleLine.push_back(this->GetCMakeInstance()->GetCPackCommand());
+  singleLine.push_back("--config");
+  std::string configFile = mf->GetStartOutputDirectory();;
+  configFile += "/CPackConfig.cmake";
+  singleLine.push_back(configFile);
+  cpackCommandLines.push_back(singleLine);
+  (*targets)[this->GetPackageTargetName()]
+    = this->CreateGlobalTarget(this->GetPackageTargetName(),
+      "Run CPack packaging tool...", &cpackCommandLines, depends);
+
+  // Test
+  cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end());
+  singleLine.erase(singleLine.begin(), singleLine.end());
+  depends.erase(depends.begin(), depends.end());
+  singleLine.push_back(this->GetCMakeInstance()->GetCTestCommand());
+  singleLine.push_back("--force-new-ctest-process");
+  cpackCommandLines.push_back(singleLine);
+  (*targets)[this->GetPackageTargetName()]
+    = this->CreateGlobalTarget(this->GetPackageTargetName(),
+      "Running tests...", &cpackCommandLines, depends);
+
+  //Edit Cache
+  cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end());
+  singleLine.erase(singleLine.begin(), singleLine.end());
+  depends.erase(depends.begin(), depends.end());
+  // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined.
+  // Otherwise default to the interactive command-line interface.
+  if(mf->GetDefinition("CMAKE_EDIT_COMMAND"))
+    {
+    singleLine.push_back("$(CMAKE_EDIT_COMMAND)");
+    singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
+    singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
+    cpackCommandLines.push_back(singleLine);
+    (*targets)[this->GetEditCacheTargetName()] =
+      this->CreateGlobalTarget(
+        this->GetEditCacheTargetName(), "Running CMake cache editor...",
+        &cpackCommandLines, depends);
+    }
+  else
+    {
+    singleLine.push_back("$(CMAKE_COMMAND)");
+    singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
+    singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
+    singleLine.push_back("-i");
+    cpackCommandLines.push_back(singleLine);
+    (*targets)[this->GetEditCacheTargetName()] =
+      this->CreateGlobalTarget(
+        this->GetEditCacheTargetName(), "Running interactive CMake command-line interface...",
+        &cpackCommandLines, depends);
+    }
+
+  //Rebuild Cache
+  cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end());
+  singleLine.erase(singleLine.begin(), singleLine.end());
+  depends.erase(depends.begin(), depends.end());
+  singleLine.push_back("$(CMAKE_COMMAND)");
+  singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
+  singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
+  cpackCommandLines.push_back(singleLine);
+  (*targets)[this->GetRebuildCacheTargetName()] =
+    this->CreateGlobalTarget(
+      this->GetRebuildCacheTargetName(), "Running CMake to regenerate build system...",
+      &cpackCommandLines, depends);
+
+  //Install
+  std::string cmd;
+  cpackCommandLines.erase(cpackCommandLines.begin(), cpackCommandLines.end());
+  singleLine.erase(singleLine.begin(), singleLine.end());
+  depends.erase(depends.begin(), depends.end());
+  depends.push_back("preinstall");
+  if(mf->GetDefinition("CMake_BINARY_DIR"))
+    {
+    // We are building CMake itself.  We cannot use the original
+    // executable to install over itself.
+    cmd = mf->GetDefinition("EXECUTABLE_OUTPUT_PATH");
+    cmd += "/";
+    cmd += "cmake";
+    }
+  else
+    {
+    cmd = "$(CMAKE_COMMAND)";
+    }
+  singleLine.push_back(cmd.c_str());
+  singleLine.push_back("-P");
+  singleLine.push_back("cmake_install.cmake");
+  cpackCommandLines.push_back(singleLine);
+  const char* noall =
+    mf->GetDefinition("CMAKE_SKIP_INSTALL_ALL_DEPENDENCY");
+  bool dependsOnAll = false;
+  if(!noall || cmSystemTools::IsOff(noall))
+    {
+    dependsOnAll = true;
+    }
+  (*targets)[this->GetInstallTargetName()] =
+    this->CreateGlobalTarget(
+      this->GetInstallTargetName(), "Install the project...",
+      &cpackCommandLines, depends, dependsOnAll);
+}
+
+cmTarget cmGlobalGenerator::CreateGlobalTarget(
+  const char* name, const char* message,
+  const cmCustomCommandLines* commandLines,
+  std::vector<std::string> depends,
+  bool depends_on_all /* = false */)
+{
+  // Package
+  cmTarget target;
+  target.SetType(cmTarget::GLOBAL_TARGET, name);
+  target.SetInAll(false);
+
+  // Store the custom command in the target.
+  cmCustomCommand cc(0, depends, *commandLines, 0, 0);
+  target.GetPostBuildCommands().push_back(cc);
+  target.SetProperty("EchoString", message);
+  if ( depends_on_all )
+    {
+    target.SetProperty("DependsOnAll", "ON");
+    }
+  return target;
+}
+
 //----------------------------------------------------------------------------
 void cmGlobalGenerator::AppendDirectoryForConfig(const char*, std::string&)
 {

+ 15 - 0
Source/cmGlobalGenerator.h

@@ -20,6 +20,8 @@
 
 #include "cmStandardIncludes.h"
 
+#include "cmTarget.h" // For cmTargets
+
 class cmake;
 class cmMakefile;
 class cmLocalGenerator;
@@ -111,6 +113,7 @@ public:
     return this->m_CMakeInstance; };
 
   void SetConfiguredFilesPath(const char* s){m_ConfiguredFilesPath = s;}
+  cmLocalGenerator* GetLocalGenerator(int p) { return m_LocalGenerators[p];}
   void GetLocalGenerators(std::vector<cmLocalGenerator *>&g) { g = m_LocalGenerators;}
   void AddLocalGenerator(cmLocalGenerator *lg);
   
@@ -160,6 +163,18 @@ protected:
   void ConfigureRelativePaths();
   void SetupTests();
 
+  void CreateDefaultGlobalTargets(cmTargets* targets);
+  cmTarget CreateGlobalTarget(const char* name, const char* message,
+    const cmCustomCommandLines* commandLines,
+    std::vector<std::string> depends, bool depends_on_all = false);
+
+  virtual const char* GetInstallTargetName()      { return "install"; }
+  virtual const char* GetPreinstallTargetName()   { return "preinstall"; }
+  virtual const char* GetTestTargetName()         { return "test"; }
+  virtual const char* GetPackageTargetName()      { return "package"; }
+  virtual const char* GetEditCacheTargetName()    { return "edit_cache"; }
+  virtual const char* GetRebuildCacheTargetName() { return "rebuild_cache"; }
+
   bool m_ForceUnixPaths;
   cmStdString m_FindMakeProgramFile;
   cmStdString m_ConfiguredFilesPath;

+ 40 - 75
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -1250,41 +1250,50 @@ void cmLocalUnixMakefileGenerator3
                       no_commands, true);
   }
 
-  // Write special "test" target to run ctest.
-  if(m_Makefile->IsOn("CMAKE_TESTING_ENABLED"))
+  // Write all global targets
+  cmTargets* targets = &(m_Makefile->GetTargets());
+  cmTargets::iterator glIt;
+  for ( glIt = targets->begin(); glIt != targets->end(); ++ glIt )
     {
-    std::string ctest;
-    if(m_Makefile->GetDefinition("CMake_BINARY_DIR"))
+    if ( glIt->second.GetType() == cmTarget::GLOBAL_TARGET )
       {
-      // We are building CMake itself.  Use the ctest that comes with
-      // this version of CMake instead of the one used to build it.
-      ctest = m_ExecutableOutputPath;
-      ctest += "ctest";
-      ctest += cmSystemTools::GetExecutableExtension();
-      ctest = this->Convert(ctest.c_str(),START_OUTPUT,SHELL);
-      ctest += " --force-new-ctest-process";
-      }
-    else
-      {
-      // We are building another project.  Use the ctest that comes with
-      // the CMake building it.
-      ctest = m_Makefile->GetRequiredDefinition("CMAKE_COMMAND");
-      ctest = cmSystemTools::GetFilenamePath(ctest.c_str());
-      ctest += "/";
-      ctest += "ctest";
-      ctest += cmSystemTools::GetExecutableExtension();
-      ctest = this->ConvertToOutputForExisting(ctest.c_str());
+      std::string targetString = "Special rule for the target " + glIt->first;
+      std::vector<std::string> commands;
+      std::vector<std::string> depends;
+
+      const char* text = glIt->second.GetProperty("EchoString");
+      if ( !text )
+        {
+        text = "Running external command ...";
+        }
+      const char* dependsOnAll = glIt->second.GetProperty("DependsOnAll");
+      if ( dependsOnAll || cmSystemTools::IsOn(dependsOnAll) )
+        {
+        depends.push_back("all");
+        }
+      this->AppendEcho(commands, text);
+      size_t cc;
+      std::cout << "Target: " << text << std::endl;
+      for ( cc = 0; cc < depends.size(); ++ cc )
+        {
+        std::cout << "  Depends [" << depends[cc].c_str() << "]" << std::endl;
+        }
+
+      // Utility targets store their rules in pre- and post-build commands.
+      this->AppendCustomDepends(depends,   glIt->second.GetPreBuildCommands());
+      this->AppendCustomDepends(depends,   glIt->second.GetPostBuildCommands());
+      std::cout << "Target: " << text << std::endl;
+      for ( cc = 0; cc < depends.size(); ++ cc )
+        {
+        std::cout << "  Depends [" << depends[cc].c_str() << "]" << std::endl;
+        }
+      this->AppendCustomCommands(commands, glIt->second.GetPreBuildCommands());
+      this->AppendCustomCommands(commands, glIt->second.GetPostBuildCommands());
+      this->WriteMakeRule(ruleFileStream, targetString.c_str(), glIt->first.c_str(), depends, commands, false);
       }
-    std::vector<std::string> no_depends;
-    std::vector<std::string> commands;
-    this->AppendEcho(commands, "Running tests...");
-    ctest += " $(ARGS)";
-    commands.push_back(ctest);
-    this->WriteMakeRule(ruleFileStream,
-                        "Special rule to drive testing with ctest.",
-                        "test", no_depends, commands, true);
     }
 
+
   // Write special "install" target to run cmake_install.cmake script.
   {
   std::vector<std::string> depends;
@@ -1307,7 +1316,7 @@ void cmLocalUnixMakefileGenerator3
   commands.push_back(cmd);
   this->WriteMakeRule(ruleFileStream,
                       "Special rule to run installation script.",
-                      "install", depends, commands, true);
+                      "old_install", depends, commands, true);
 
   commands.clear();
   depends.clear();
@@ -1330,50 +1339,6 @@ void cmLocalUnixMakefileGenerator3
                       "preinstall", depends, commands, true);
   }
 
-  // Write special "rebuild_cache" target to re-run cmake.
-  {
-  std::vector<std::string> no_depends;
-  std::vector<std::string> commands;
-  this->AppendEcho(commands, "Running CMake to regenerate build system...");
-  commands.push_back(
-    "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
-  this->WriteMakeRule(ruleFileStream,
-                      "Special rule to re-run CMake using make.",
-                      "rebuild_cache",
-                      no_depends,
-                      commands, true);
-  }
-
-  // Use CMAKE_EDIT_COMMAND for the edit_cache rule if it is defined.
-  // Otherwise default to the interactive command-line interface.
-  if(m_Makefile->GetDefinition("CMAKE_EDIT_COMMAND"))
-    {
-    std::vector<std::string> no_depends;
-    std::vector<std::string> commands;
-    this->AppendEcho(commands, "Running CMake cache editor...");
-    commands.push_back(
-      "$(CMAKE_EDIT_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)");
-    this->WriteMakeRule(ruleFileStream,
-                        "Special rule to re-run CMake cache editor using make.",
-                        "edit_cache",
-                        no_depends,
-                        commands, true);
-    }
-  else
-    {
-    std::vector<std::string> no_depends;
-    std::vector<std::string> commands;
-    this->AppendEcho(commands,
-                     "Running interactive CMake command-line interface...");
-    commands.push_back(
-      "$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) -i");
-    this->WriteMakeRule(ruleFileStream,
-                        "Special rule to re-run CMake cache editor using make.",
-                        "edit_cache",
-                        no_depends,
-                        commands, true);
-    }
-
   this->WriteSpecialTargetsTop(ruleFileStream);
 
   std::vector<std::string> depends;