Explorar o código

ENH: add re run cmake if inputs change

Bill Hoffman %!s(int64=20) %!d(string=hai) anos
pai
achega
b7ef8149e8
Modificáronse 2 ficheiros con 107 adicións e 74 borrados
  1. 101 74
      Source/cmGlobalXCodeGenerator.cxx
  2. 6 0
      Source/cmGlobalXCodeGenerator.h

+ 101 - 74
Source/cmGlobalXCodeGenerator.cxx

@@ -25,7 +25,6 @@
 
 //TODO
 // add a group for Sources Headers, and other cmake group stuff
-// add rebuild when cmake changes
 
 //----------------------------------------------------------------------------
 cmGlobalXCodeGenerator::cmGlobalXCodeGenerator()
@@ -227,6 +226,10 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
   commandLines.push_back(makecommand);
   mf->AddUtilityCommand("XCODE_DEPEND_HELPER", false, no_output, no_depends,
                         commandLines);
+
+  // Add Re-Run CMake rules
+  this->CreateReRunCMakeFile(root);
+
   // now make the allbuild depend on all the non-utility targets
   // in the project
   for(std::vector<cmLocalGenerator*>::iterator i = gens.begin();
@@ -249,7 +252,6 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
         {
         target.AddUtility("XCODE_DEPEND_HELPER");
         }
-      
       if(target.IsInAll())
         {
         allbuild->AddUtility(target.GetName());
@@ -259,6 +261,37 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
 }
 
 
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::CreateReRunCMakeFile(cmLocalGenerator* root)
+{
+  cmMakefile* mf = root->GetMakefile();
+  std::vector<std::string> lfiles = mf->GetListFiles();
+  // sort the array
+  std::sort(lfiles.begin(), lfiles.end(), std::less<std::string>()); 
+  std::vector<std::string>::iterator new_end = 
+    std::unique(lfiles.begin(), lfiles.end());
+  lfiles.erase(new_end, lfiles.end());
+  std::string dir = mf->GetHomeOutputDirectory();
+  m_CurrentReRunCMakeMakefile = dir;
+  m_CurrentReRunCMakeMakefile += "/CMakeScripts";
+  cmSystemTools::MakeDirectory(m_CurrentReRunCMakeMakefile.c_str());
+  m_CurrentReRunCMakeMakefile += "/ReRunCMake.make";
+  cmGeneratedFileStream makefileStream(m_CurrentReRunCMakeMakefile.c_str());
+  makefileStream << "# Generated by CMake, DO NOT EDIT\n";
+  makefileStream << "cmake.check_cache: ";
+  for(std::vector<std::string>::const_iterator i = lfiles.begin();
+      i !=  lfiles.end(); ++i)
+    {
+    makefileStream << "\\\n" << *i;
+    }
+  std::string cmake = mf->GetRequiredDefinition("CMAKE_COMMAND");
+  makefileStream << "\n\t" << this->ConvertToRelativeForMake(cmake.c_str()) 
+                 << " -H" << this->ConvertToRelativeForMake(
+                   mf->GetHomeDirectory())
+                 << " -B" << this->ConvertToRelativeForMake(
+                   mf->GetHomeOutputDirectory()) << "\n";
+}
+
 //----------------------------------------------------------------------------
 void cmGlobalXCodeGenerator::ClearXCodeObjects()
 {
@@ -370,7 +403,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
 bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
 {
   if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" ||
-     tname == "install" || tname == "RUN_TESTS")
+     tname == "install" || tname == "RUN_TESTS" )
     {
     if(m_TargetDoneSet.find(tname) != m_TargetDoneSet.end())
       {
@@ -492,6 +525,35 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
     }
 }
 
+//----------------------------------------------------------------------------
+cmXCodeObject*
+cmGlobalXCodeGenerator::CreateBuildPhase(const char* name, 
+                                         const char* name2,
+                                         cmTarget& cmtarget,
+                                         const std::vector<cmCustomCommand>&
+                                         commands)
+{
+  if(commands.size() == 0 && strcmp(name, "CMake ReRun") != 0)
+    {
+    return 0;
+    }
+  cmXCodeObject* buildPhase = 
+    this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
+  buildPhase->AddAttribute("buildActionMask",
+                                     this->CreateString("2147483647"));
+  cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
+  buildPhase->AddAttribute("files", buildFiles);
+  buildPhase->AddAttribute("name", 
+                           this->CreateString(name));
+  buildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
+                           this->CreateString("0"));
+  buildPhase->AddAttribute("shellPath",
+                           this->CreateString("/bin/sh"));
+  this->AddCommandsToBuildPhase(buildPhase, cmtarget, commands,
+                                name2);
+  return buildPhase;
+}
+
 //----------------------------------------------------------------------------
 void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
                                                   cmXCodeObject*
@@ -520,80 +582,29 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
       commands.push_back(*(*i)->GetCustomCommand());
       }
     }
-  
+  std::vector<cmCustomCommand> reruncom;
+  cmXCodeObject* cmakeReRunPhase =  this->CreateBuildPhase("CMake ReRun",
+                                                           "cmakeReRunPhase",
+                                                           cmtarget, reruncom);
+  buildPhases->AddObject(cmakeReRunPhase);
   // create prebuild phase
-  cmXCodeObject* cmakeRulesBuildPhase = 0;
-  if(commands.size())
-    {
-    cmakeRulesBuildPhase = 
-      this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
-    cmakeRulesBuildPhase->AddAttribute("buildActionMask",
-                                this->CreateString("2147483647"));
-    cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    cmakeRulesBuildPhase->AddAttribute("files", buildFiles);
-    cmakeRulesBuildPhase->AddAttribute("name", 
-                                this->CreateString("CMake Rules"));
-    cmakeRulesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
-                                this->CreateString("0"));
-    cmakeRulesBuildPhase->AddAttribute("shellPath",
-                                       this->CreateString("/bin/sh"));
-    this->AddCommandsToBuildPhase(cmakeRulesBuildPhase, cmtarget, commands,
-      "cmakeRulesCommands");
-    }
+  cmXCodeObject* cmakeRulesBuildPhase =
+    this->CreateBuildPhase("CMake Rules",
+                           "cmakeRulesBuildPhase",
+                           cmtarget, commands);
   // create prebuild phase
-  cmXCodeObject* preBuildPhase = 0;
-  if(prebuild.size())
-    {
-    preBuildPhase = 
-      this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
-    preBuildPhase->AddAttribute("buildActionMask",
-                                this->CreateString("2147483647"));
-    cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    preBuildPhase->AddAttribute("files", buildFiles);
-    preBuildPhase->AddAttribute("name", 
-                                this->CreateString("CMake PreBuild Rules"));
-    preBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
-                                this->CreateString("0"));
-    preBuildPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
-    this->AddCommandsToBuildPhase(preBuildPhase, cmtarget, prebuild,
-      "preBuildCommands");
-    }
+  cmXCodeObject* preBuildPhase = this->CreateBuildPhase("CMake PreBuild Rules",
+                                                        "preBuildCommands",
+                                                        cmtarget, prebuild);
   // create prebuild phase
-  cmXCodeObject* preLinkPhase = 0;
-  if(prelink.size())
-    {
-    preLinkPhase = 
-      this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
-    preLinkPhase->AddAttribute("buildActionMask",
-                               this->CreateString("2147483647"));
-    cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    preLinkPhase->AddAttribute("files", buildFiles);
-    preLinkPhase->AddAttribute("name", 
-                               this->CreateString("CMake PreLink Rules"));
-    preLinkPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
-                               this->CreateString("0"));
-    preLinkPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
-    this->AddCommandsToBuildPhase(preLinkPhase, cmtarget, prelink,
-                                  "preLinkCommands");
-    }
+  cmXCodeObject* preLinkPhase = this->CreateBuildPhase("CMake PreLink Rules",
+                                                       "preLinkCommands",
+                                                       cmtarget, prelink);
   // create prebuild phase
-  cmXCodeObject* postBuildPhase = 0;
-  if(postbuild.size())
-    {
-    postBuildPhase = 
-      this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase);
-    postBuildPhase->AddAttribute("buildActionMask",
-                                 this->CreateString("2147483647"));
-    cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
-    postBuildPhase->AddAttribute("files", buildFiles);
-    postBuildPhase->AddAttribute("name", 
-                                 this->CreateString("CMake PostBuild Rules"));
-    postBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", 
-                                 this->CreateString("0"));
-    postBuildPhase->AddAttribute("shellPath", this->CreateString("/bin/sh"));
-    this->AddCommandsToBuildPhase(postBuildPhase, cmtarget, postbuild,
-                                  "postBuildCommands");
-    }
+  cmXCodeObject* postBuildPhase = 
+    this->CreateBuildPhase("CMake PostBuild Rules",
+                           "postBuildPhase",
+                           cmtarget, postbuild);
   // the order here is the order they will be built in
   if(preBuildPhase)
     {
@@ -633,6 +644,21 @@ cmGlobalXCodeGenerator::AddCommandsToBuildPhase(cmXCodeObject* buildphase,
                                                 const & commands,
                                                 const char* name)
 {
+  if(strcmp(name, "cmakeReRunPhase") == 0)
+    {
+    std::string cdir = m_CurrentMakefile->GetHomeOutputDirectory();
+    cdir = this->ConvertToRelativeForMake(cdir.c_str());
+    std::string makecmd = "make -C ";
+    makecmd += cdir;? 
+    makecmd += " -f ";
+    makecmd += 
+      this->ConvertToRelativeForMake(m_CurrentReRunCMakeMakefile.c_str());
+    cmSystemTools::ReplaceString(makecmd, "\\ ", "\\\\ ");
+    buildphase->AddAttribute("shellScript",
+                             this->CreateString(makecmd.c_str()));
+    return;
+    }
+  
   std::string dir = m_CurrentMakefile->GetCurrentOutputDirectory();
   dir += "/CMakeScripts";
   cmSystemTools::MakeDirectory(dir.c_str());
@@ -1183,7 +1209,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
   if(bset)
     {
     bset->AddAttribute("LIBRARY_SEARCH_PATHS", 
-                                this->CreateString(linkDirs.c_str()));
+                       this->CreateString(linkDirs.c_str()));
     }
   // now add the link libraries
   for(std::vector<cmStdString>::iterator lib = linkItems.begin();
@@ -1222,6 +1248,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
     else
       {
       std::cerr << "Error Utility: " << i->c_str() << "\n";
+      std::cerr << "cmtarget " << t << "\n";
       std::cerr << "Is on the target " << cmtarget->GetName() << "\n";
       std::cerr << "But it has no xcode target created yet??\n";
       std::cerr << "Current project is "

+ 6 - 0
Source/cmGlobalXCodeGenerator.h

@@ -123,6 +123,11 @@ private:
   bool SpecialTargetEmitted(std::string const& tname);
   void AddExtraTargets(cmLocalGenerator* root, 
                        std::vector<cmLocalGenerator*>& gens);
+  cmXCodeObject* CreateBuildPhase(const char* name, 
+                                  const char* name2,
+                                  cmTarget& cmtarget,
+                                  const std::vector<cmCustomCommand>&);
+  void CreateReRunCMakeFile(cmLocalGenerator* root);
 private:
   std::vector<cmXCodeObject*> m_XCodeObjects;
   cmXCodeObject* m_RootObject;
@@ -136,6 +141,7 @@ private:
   std::set<cmStdString> m_TargetDoneSet;
   bool m_DoneAllBuild;
   bool m_DoneXCodeHack;
+  std::string m_CurrentReRunCMakeMakefile;
   std::string m_CurrentXCodeHackMakefile;
   std::string m_OutputDir; 
   std::vector<std::string> m_CurrentOutputDirectoryComponents;