cmakexbuild.cxx 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmConfigure.h" // IWYU pragma: keep
  4. #include "cmsys/Process.h"
  5. #include <iostream>
  6. #include <string>
  7. #include <vector>
  8. #include "cmDuration.h"
  9. #include "cmSystemTools.h"
  10. // This is a wrapper program for xcodebuild
  11. // it calls xcodebuild, and does two things
  12. // it removes much of the output, all the setenv
  13. // stuff. Also, it checks for the text file busy
  14. // error, and re-runs xcodebuild until that error does
  15. // not show up.
  16. int RunXCode(std::vector<const char*>& argv, bool& hitbug)
  17. {
  18. hitbug = false;
  19. cmsysProcess* cp = cmsysProcess_New();
  20. cmsysProcess_SetCommand(cp, &*argv.begin());
  21. cmsysProcess_SetTimeout(cp, 0);
  22. cmsysProcess_Execute(cp);
  23. std::vector<char> out;
  24. std::vector<char> err;
  25. std::string line;
  26. int pipe =
  27. cmSystemTools::WaitForLine(cp, line, std::chrono::seconds(100), out, err);
  28. while (pipe != cmsysProcess_Pipe_None) {
  29. if (line.find("/bin/sh: bad interpreter: Text file busy") !=
  30. std::string::npos) {
  31. hitbug = true;
  32. std::cerr << "Hit xcodebuild bug : " << line << "\n";
  33. }
  34. // if the bug is hit, no more output should be generated
  35. // because it may contain bogus errors
  36. // also remove all output with setenv in it to tone down
  37. // the verbosity of xcodebuild
  38. if (!hitbug && (line.find("setenv") == std::string::npos)) {
  39. if (pipe == cmsysProcess_Pipe_STDERR) {
  40. std::cerr << line << "\n";
  41. } else if (pipe == cmsysProcess_Pipe_STDOUT) {
  42. std::cout << line << "\n";
  43. }
  44. }
  45. pipe = cmSystemTools::WaitForLine(cp, line, std::chrono::seconds(100), out,
  46. err);
  47. }
  48. cmsysProcess_WaitForExit(cp, nullptr);
  49. if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) {
  50. return cmsysProcess_GetExitValue(cp);
  51. }
  52. if (cmsysProcess_GetState(cp) == cmsysProcess_State_Error) {
  53. return -1;
  54. }
  55. return -1;
  56. }
  57. int main(int ac, char* av[])
  58. {
  59. std::vector<const char*> argv;
  60. argv.push_back("xcodebuild");
  61. for (int i = 1; i < ac; i++) {
  62. argv.push_back(av[i]);
  63. }
  64. argv.push_back(nullptr);
  65. bool hitbug = true;
  66. int ret = 0;
  67. while (hitbug) {
  68. ret = RunXCode(argv, hitbug);
  69. }
  70. if (ret < 0) {
  71. return 255;
  72. }
  73. return ret;
  74. }