cmCTestBuildCommand.cxx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmCTestBuildCommand.h"
  11. #include "cmCTest.h"
  12. #include "cmCTestBuildHandler.h"
  13. #include "cmCTestGenericHandler.h"
  14. #include "cmGlobalGenerator.h"
  15. #include "cmake.h"
  16. cmCTestBuildCommand::cmCTestBuildCommand()
  17. {
  18. this->GlobalGenerator = CM_NULLPTR;
  19. this->Arguments[ctb_NUMBER_ERRORS] = "NUMBER_ERRORS";
  20. this->Arguments[ctb_NUMBER_WARNINGS] = "NUMBER_WARNINGS";
  21. this->Arguments[ctb_TARGET] = "TARGET";
  22. this->Arguments[ctb_CONFIGURATION] = "CONFIGURATION";
  23. this->Arguments[ctb_FLAGS] = "FLAGS";
  24. this->Arguments[ctb_PROJECT_NAME] = "PROJECT_NAME";
  25. this->Arguments[ctb_LAST] = CM_NULLPTR;
  26. this->Last = ctb_LAST;
  27. }
  28. cmCTestBuildCommand::~cmCTestBuildCommand()
  29. {
  30. if (this->GlobalGenerator) {
  31. delete this->GlobalGenerator;
  32. this->GlobalGenerator = CM_NULLPTR;
  33. }
  34. }
  35. cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
  36. {
  37. cmCTestGenericHandler* handler = this->CTest->GetInitializedHandler("build");
  38. if (!handler) {
  39. this->SetError("internal CTest error. Cannot instantiate build handler");
  40. return CM_NULLPTR;
  41. }
  42. this->Handler = (cmCTestBuildHandler*)handler;
  43. const char* ctestBuildCommand =
  44. this->Makefile->GetDefinition("CTEST_BUILD_COMMAND");
  45. if (ctestBuildCommand && *ctestBuildCommand) {
  46. this->CTest->SetCTestConfiguration("MakeCommand", ctestBuildCommand,
  47. this->Quiet);
  48. } else {
  49. const char* cmakeGeneratorName =
  50. this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
  51. const char* cmakeProjectName =
  52. (this->Values[ctb_PROJECT_NAME] && *this->Values[ctb_PROJECT_NAME])
  53. ? this->Values[ctb_PROJECT_NAME]
  54. : this->Makefile->GetDefinition("CTEST_PROJECT_NAME");
  55. // Build configuration is determined by: CONFIGURATION argument,
  56. // or CTEST_BUILD_CONFIGURATION script variable, or
  57. // CTEST_CONFIGURATION_TYPE script variable, or ctest -C command
  58. // line argument... in that order.
  59. //
  60. const char* ctestBuildConfiguration =
  61. this->Makefile->GetDefinition("CTEST_BUILD_CONFIGURATION");
  62. const char* cmakeBuildConfiguration =
  63. (this->Values[ctb_CONFIGURATION] && *this->Values[ctb_CONFIGURATION])
  64. ? this->Values[ctb_CONFIGURATION]
  65. : ((ctestBuildConfiguration && *ctestBuildConfiguration)
  66. ? ctestBuildConfiguration
  67. : this->CTest->GetConfigType().c_str());
  68. const char* cmakeBuildAdditionalFlags =
  69. (this->Values[ctb_FLAGS] && *this->Values[ctb_FLAGS])
  70. ? this->Values[ctb_FLAGS]
  71. : this->Makefile->GetDefinition("CTEST_BUILD_FLAGS");
  72. const char* cmakeBuildTarget =
  73. (this->Values[ctb_TARGET] && *this->Values[ctb_TARGET])
  74. ? this->Values[ctb_TARGET]
  75. : this->Makefile->GetDefinition("CTEST_BUILD_TARGET");
  76. if (cmakeGeneratorName && *cmakeGeneratorName && cmakeProjectName &&
  77. *cmakeProjectName) {
  78. if (!cmakeBuildConfiguration) {
  79. cmakeBuildConfiguration = "Release";
  80. }
  81. if (this->GlobalGenerator) {
  82. if (this->GlobalGenerator->GetName() != cmakeGeneratorName) {
  83. delete this->GlobalGenerator;
  84. this->GlobalGenerator = CM_NULLPTR;
  85. }
  86. }
  87. if (!this->GlobalGenerator) {
  88. this->GlobalGenerator =
  89. this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
  90. cmakeGeneratorName);
  91. if (!this->GlobalGenerator) {
  92. std::string e = "could not create generator named \"";
  93. e += cmakeGeneratorName;
  94. e += "\"";
  95. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e);
  96. cmSystemTools::SetFatalErrorOccured();
  97. return CM_NULLPTR;
  98. }
  99. }
  100. if (strlen(cmakeBuildConfiguration) == 0) {
  101. const char* config = CM_NULLPTR;
  102. #ifdef CMAKE_INTDIR
  103. config = CMAKE_INTDIR;
  104. #endif
  105. if (!config) {
  106. config = "Debug";
  107. }
  108. cmakeBuildConfiguration = config;
  109. }
  110. std::string dir = this->CTest->GetCTestConfiguration("BuildDirectory");
  111. std::string buildCommand =
  112. this->GlobalGenerator->GenerateCMakeBuildCommand(
  113. cmakeBuildTarget ? cmakeBuildTarget : "", cmakeBuildConfiguration,
  114. cmakeBuildAdditionalFlags ? cmakeBuildAdditionalFlags : "",
  115. this->Makefile->IgnoreErrorsCMP0061());
  116. cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  117. "SetMakeCommand:" << buildCommand << "\n",
  118. this->Quiet);
  119. this->CTest->SetCTestConfiguration("MakeCommand", buildCommand.c_str(),
  120. this->Quiet);
  121. } else {
  122. std::ostringstream ostr;
  123. /* clang-format off */
  124. ostr << "has no project to build. If this is a "
  125. "\"built with CMake\" project, verify that CTEST_CMAKE_GENERATOR "
  126. "and CTEST_PROJECT_NAME are set."
  127. "\n"
  128. "CTEST_PROJECT_NAME is usually set in CTestConfig.cmake. Verify "
  129. "that CTestConfig.cmake exists, or CTEST_PROJECT_NAME "
  130. "is set in the script, or PROJECT_NAME is passed as an argument "
  131. "to ctest_build."
  132. "\n"
  133. "Alternatively, set CTEST_BUILD_COMMAND to build the project "
  134. "with a custom command line.";
  135. /* clang-format on */
  136. this->SetError(ostr.str());
  137. return CM_NULLPTR;
  138. }
  139. }
  140. if (const char* useLaunchers =
  141. this->Makefile->GetDefinition("CTEST_USE_LAUNCHERS")) {
  142. this->CTest->SetCTestConfiguration("UseLaunchers", useLaunchers,
  143. this->Quiet);
  144. }
  145. handler->SetQuiet(this->Quiet);
  146. return handler;
  147. }
  148. bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args,
  149. cmExecutionStatus& status)
  150. {
  151. bool ret = cmCTestHandlerCommand::InitialPass(args, status);
  152. if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) {
  153. std::ostringstream str;
  154. str << this->Handler->GetTotalErrors();
  155. this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS],
  156. str.str().c_str());
  157. }
  158. if (this->Values[ctb_NUMBER_WARNINGS] &&
  159. *this->Values[ctb_NUMBER_WARNINGS]) {
  160. std::ostringstream str;
  161. str << this->Handler->GetTotalWarnings();
  162. this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS],
  163. str.str().c_str());
  164. }
  165. return ret;
  166. }