From ae10b3578d3234db1e379b663657fbdb9d1ac543 Mon Sep 17 00:00:00 2001
From: Bill Hoffman <bill.hoffman@kitware.com>
Date: Fri, 31 Mar 2006 13:17:23 -0500
Subject: [PATCH] ENH: add a wrapper for xcodebuild to get around bug and
 verbose output

---
 Source/CMakeLists.txt             |  9 +++++++++
 Source/cmGlobalGenerator.cxx      | 23 ++++++++++++++++++++---
 Source/cmGlobalXCodeGenerator.cxx |  8 +++++---
 Source/cmTryCompileCommand.cxx    | 14 --------------
 Source/cmakemain.cxx              | 11 ++---------
 Source/cmakexbuild.cxx            | 25 ++++++++++++++++---------
 bootstrap                         |  2 +-
 7 files changed, 53 insertions(+), 39 deletions(-)

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 077872bf0e..03f5155de3 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -282,6 +282,11 @@ SET(CPACK_SRCS
 ADD_LIBRARY(CPackLib ${CPACK_SRCS})
 TARGET_LINK_LIBRARIES(CPackLib CMakeLib)
 
+IF(APPLE)
+  ADD_EXECUTABLE(cmakexbuild cmakexbuild.cxx)
+  TARGET_LINK_LIBRARIES(cmakexbuild CMakeLib)
+ENDIF(APPLE)
+
 # Build CMake executable
 ADD_EXECUTABLE(cmake cmakemain.cxx)
 TARGET_LINK_LIBRARIES(cmake CMakeLib)
@@ -1088,4 +1093,8 @@ INCLUDE (${CMAKE_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
 INSTALL_TARGETS(/bin cmake)
 INSTALL_TARGETS(/bin ctest)
 INSTALL_TARGETS(/bin cpack)
+IF(APPLE)
+  INSTALL_TARGETS(/bin cmakexbuild)
+ENDIF(APPLE)
+
 INSTALL_FILES(${CMAKE_DATA_DIR}/include cmCPluginAPI.h)
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 29ac5b140d..51dac3a8fd 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -99,7 +99,25 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
                                             "make program",
                                             cmCacheManager::FILEPATH);
     }
-  
+  if(makeProgram.find("xcodebuild") != makeProgram.npos)
+    {
+    // due to the text file busy /bin/sh problem with xcodebuild
+    // use the cmakexbuild wrapper instead.  This program
+    // will run xcodebuild and if it sees the error text file busy
+    // it will stop forwarding output, and let the build finish.
+    // Then it will retry the build.  It will continue this
+    // untill no text file busy errors occur.
+    std::string cmakexbuild = 
+      this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
+    cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
+    cmakexbuild += "cmakexbuild";
+    
+    this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", 
+                                            cmakexbuild.c_str(),
+                                            "make program",
+                                            cmCacheManager::FILEPATH);
+    
+    }
 }
 
 // enable the given language
@@ -1313,9 +1331,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
     else
       {
       singleLine.push_back(cmakeCommand);
-      singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
-      singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
       singleLine.push_back("-i");
+      singleLine.push_back(".");
       cpackCommandLines.push_back(singleLine);
       (*targets)[editCacheTargetName] =
         this->CreateGlobalTarget(
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 3d5dce70ed..5e01987ce9 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1148,8 +1148,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
                                   this->CreateString("mh_bundle"));
       buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC", 
                                   this->CreateString("NO"));
-      buildSettings->AddAttribute("PREBINDING", 
-                                  this->CreateString("NO"));
       buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN", 
                                   this->CreateString("NO"));
       buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN", 
@@ -1245,7 +1243,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     default:
       break;
     }
-  
+  if(this->XcodeVersion >= 22)
+    {
+    buildSettings->AddAttribute("PREBINDING", 
+                                this->CreateString("NO"));
+    }
   std::string dirs;
   std::vector<std::string> includes;
   this->CurrentLocalGenerator->GetIncludeDirectories(includes);
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index 1094664f6d..e524b776c5 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -231,20 +231,6 @@ int cmTryCompileCommand::CoreTryCompileCode(
   // actually do the try compile now that everything is setup
   int res = mf->TryCompile(sourceDirectory, binaryDirectory,
                            projectName, targetName, &cmakeFlags, &output);
-  // for the xcode generator 
-  if(strcmp(mf->GetCMakeInstance()->GetGlobalGenerator()->GetName() ,
-            "Xcode") == 0)
-    {
-    int numTrys = 0;
-    while(output.find("/bin/sh: bad interpreter: Text file busy") 
-          != output.npos && numTrys < 4)
-      {
-      output = "";
-      res = mf->TryCompile(sourceDirectory, binaryDirectory,
-                           projectName, targetName, &cmakeFlags, &output);
-      numTrys++;
-      }
-    }
   if ( erroroc )
     {
     cmSystemTools::SetErrorOccured();
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index d4bbd8d76e..a3bb75c0e5 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -17,9 +17,9 @@
 #include "cmake.h"
 #include "cmCacheManager.h"
 #include "cmListFileCache.h"
+#include "cmakewizard.h"
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
-#include "cmakewizard.h"
 #include "cmDynamicLoader.h"
 #include "cmDocumentation.h"
 
@@ -182,9 +182,7 @@ int do_cmake(int ac, char** av)
     }
 #endif
   
-#if defined(CMAKE_BUILD_WITH_CMAKE)
   bool wiz = false;
-#endif
   bool command = false;
   bool list_cached = false;
   bool list_all_cached = false;
@@ -194,16 +192,13 @@ int do_cmake(int ac, char** av)
   std::vector<std::string> args;
   for(int i =0; i < ac; ++i)
     {
-#if defined(CMAKE_BUILD_WITH_CMAKE)
     if(strcmp(av[i], "-i") == 0)
       {
       wiz = true;
       }
-    else
-#endif
     // if command has already been set, then
     // do not eat the -E 
-    if (!command && strcmp(av[i], "-E") == 0)
+    else if (!command && strcmp(av[i], "-E") == 0)
       {
       command = true;
       }
@@ -251,13 +246,11 @@ int do_cmake(int ac, char** av)
     int ret = cmake::ExecuteCMakeCommand(args);
     return ret;
     }
-#if defined(CMAKE_BUILD_WITH_CMAKE)
   if (wiz)
     {
     cmakewizard wizard;
     return wizard.RunWizard(args); 
     }
-#endif
   cmake cm;  
   cm.SetProgressCallback(updateProgress, 0);
   cm.SetScriptMode(script_mode);
diff --git a/Source/cmakexbuild.cxx b/Source/cmakexbuild.cxx
index b0728aa7a4..6bf4da49a1 100644
--- a/Source/cmakexbuild.cxx
+++ b/Source/cmakexbuild.cxx
@@ -1,6 +1,13 @@
 #include <cmsys/Process.h>
 #include "cmStandardIncludes.h"
 
+// This is a wrapper program for xcodebuild
+// it calls xcodebuild, and does two things
+// it removes much of the output, all the setevn
+// stuff.  Also, it checks for the text file busy
+// error, and re-runs xcodebuild until that error does
+// not show up.
+
 int WaitForLine(cmsysProcess* process, std::string& line,
                 double timeout,
                 std::vector<char>& out,
@@ -113,29 +120,31 @@ int RunXCode(std::vector<const char*>& argv, bool& hitbug)
   std::vector<char> out;
   std::vector<char> err;
   std::string line;
-  int pipe =WaitForLine(cp, line, 0, out, err);
+  int pipe =WaitForLine(cp, line, 100.0, out, err);
   while(pipe != cmsysProcess_Pipe_None)
     {
     if(line.find("/bin/sh: bad interpreter: Text file busy") 
        != line.npos)
       {
       hitbug = true;
-      std::cerr << "Found xcodebuild bug: " << line << "\n";
+      std::cerr << "Hit xcodebuild bug : " << line << "\n";
       }
     // if the bug is hit, no more output should be generated
     // because it may contain bogus errors
-    if(!hitbug)
+    // also remove all output with setenv in it to tone down
+    // the verbosity of xcodebuild
+    if(!hitbug && (line.find("setenv") == line.npos))
       {
       if(pipe == cmsysProcess_Pipe_STDERR)
         {
-        std::cerr << line;
+        std::cerr << line << "\n";
         }
       else if(pipe == cmsysProcess_Pipe_STDOUT)
         {
-        std::cout << line;
+        std::cout << line << "\n";
         }
-      pipe =WaitForLine(cp, line, 0, out, err);
       }
+    pipe =WaitForLine(cp, line, 100, out, err);
     }
   cmsysProcess_WaitForExit(cp, 0);
   if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
@@ -144,7 +153,6 @@ int RunXCode(std::vector<const char*>& argv, bool& hitbug)
     }
   if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
     {
-    std::cerr << "error\n";
     return -1;
     }
   return -1;
@@ -160,12 +168,11 @@ int main(int ac, char*av[])
     }
   argv.push_back(0);
   bool hitbug = true;
-  int ret;
+  int ret = 0;
   while(hitbug)
     {
     ret = RunXCode(argv, hitbug);
     }
-  std::cerr << "ret " << ret << "\n";
   if(ret < 0)
     {
     return 255;
diff --git a/bootstrap b/bootstrap
index 2f01341765..f00d92ef11 100755
--- a/bootstrap
+++ b/bootstrap
@@ -83,7 +83,6 @@ CMAKE_PROBLEMATIC_FILES="\
   "
 
 CMAKE_UNUSED_SOURCES="\
-  cmakewizard  \
   cmGlobalXCodeGenerator \
   cmLocalXCodeGenerator \
   cmXCodeObject \
@@ -94,6 +93,7 @@ CMAKE_UNUSED_SOURCES="\
 CMAKE_CXX_SOURCES="\
   cmake  \
   cmakemain \
+  cmakewizard  \
   cmCommandArgumentLexer \
   cmCommandArgumentParser \
   cmCommandArgumentParserHelper \
-- 
GitLab