cmTryRunCommand.cxx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmTryRunCommand.h"
  14. #include "cmCacheManager.h"
  15. #include "cmTryCompileCommand.h"
  16. // cmTryRunCommand
  17. bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv)
  18. {
  19. if(argv.size() < 4)
  20. {
  21. return false;
  22. }
  23. if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING"))
  24. {
  25. this->SetError("doesn't work when crosscompiling.");
  26. cmSystemTools::SetFatalErrorOccured();
  27. return false;
  28. }
  29. // build an arg list for TryCompile and extract the runArgs
  30. std::vector<std::string> tryCompile;
  31. std::string outputVariable;
  32. std::string runArgs;
  33. unsigned int i;
  34. for (i = 1; i < argv.size(); ++i)
  35. {
  36. if (argv[i] == "ARGS")
  37. {
  38. ++i;
  39. while (i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
  40. argv[i] != "CMAKE_FLAGS")
  41. {
  42. runArgs += " ";
  43. runArgs += argv[i];
  44. ++i;
  45. }
  46. if (i < argv.size())
  47. {
  48. tryCompile.push_back(argv[i]);
  49. }
  50. }
  51. else
  52. {
  53. tryCompile.push_back(argv[i]);
  54. if (argv[i] == "OUTPUT_VARIABLE")
  55. {
  56. if ( argv.size() <= (i+1) )
  57. {
  58. cmSystemTools::Error(
  59. "OUTPUT_VARIABLE specified but there is no variable");
  60. return false;
  61. }
  62. outputVariable = argv[i+1];
  63. }
  64. }
  65. }
  66. // do the try compile
  67. int res = this->TryCompileCode(tryCompile);
  68. printf("TryCompile: %d outputFile: -%s-\n", res, this->OutputFile.c_str());
  69. // now try running the command if it compiled
  70. if (!res)
  71. {
  72. if (this->OutputFile.size() == 0)
  73. {
  74. cmSystemTools::Error(this->FindErrorMessage.c_str());
  75. }
  76. else
  77. {
  78. int retVal = -1;
  79. std::string output;
  80. std::string finalCommand = cmSystemTools::ConvertToRunCommandPath(
  81. this->OutputFile.c_str());
  82. if(runArgs.size())
  83. {
  84. finalCommand += runArgs;
  85. }
  86. int timeout = 0;
  87. bool worked = cmSystemTools::RunSingleCommand(finalCommand.c_str(),
  88. &output, &retVal,
  89. 0, false, timeout);
  90. printf("worked: %d output: -%s-\n", worked?1:0, output.c_str());
  91. if(outputVariable.size())
  92. {
  93. // if the TryCompileCore saved output in this outputVariable then
  94. // prepend that output to this output
  95. const char* compileOutput
  96. = this->Makefile->GetDefinition(outputVariable.c_str());
  97. if(compileOutput)
  98. {
  99. output = std::string(compileOutput) + output;
  100. }
  101. this->Makefile->AddDefinition(outputVariable.c_str(), output.c_str());
  102. }
  103. // set the run var
  104. char retChar[1000];
  105. if(worked)
  106. {
  107. sprintf(retChar,"%i",retVal);
  108. }
  109. else
  110. {
  111. strcpy(retChar, "FAILED_TO_RUN");
  112. }
  113. this->Makefile->AddCacheDefinition(argv[0].c_str(), retChar,
  114. "Result of TRY_RUN",
  115. cmCacheManager::INTERNAL);
  116. }
  117. }
  118. // if we created a directory etc, then cleanup after ourselves
  119. if(!this->Makefile->GetCMakeInstance()->GetDebugTryCompile())
  120. {
  121. this->CleanupFiles(this->BinaryDirectory.c_str());
  122. }
  123. return true;
  124. }