cmCTestConfigureCommand.cxx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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 "cmCTestConfigureCommand.h"
  4. #include <cstring>
  5. #include <sstream>
  6. #include <vector>
  7. #include <cmext/string_view>
  8. #include "cmCTest.h"
  9. #include "cmCTestConfigureHandler.h"
  10. #include "cmGlobalGenerator.h"
  11. #include "cmList.h"
  12. #include "cmMakefile.h"
  13. #include "cmStringAlgorithms.h"
  14. #include "cmSystemTools.h"
  15. #include "cmValue.h"
  16. #include "cmake.h"
  17. void cmCTestConfigureCommand::BindArguments()
  18. {
  19. this->cmCTestHandlerCommand::BindArguments();
  20. this->Bind("OPTIONS"_s, this->Options);
  21. }
  22. cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
  23. {
  24. cmList options;
  25. if (!this->Options.empty()) {
  26. options.assign(this->Options);
  27. }
  28. if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) {
  29. this->SetError(
  30. "Build directory not specified. Either use BUILD "
  31. "argument to CTEST_CONFIGURE command or set CTEST_BINARY_DIRECTORY "
  32. "variable");
  33. return nullptr;
  34. }
  35. cmValue ctestConfigureCommand =
  36. this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND");
  37. if (cmNonempty(ctestConfigureCommand)) {
  38. this->CTest->SetCTestConfiguration("ConfigureCommand",
  39. *ctestConfigureCommand, this->Quiet);
  40. } else {
  41. cmValue cmakeGeneratorName =
  42. this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR");
  43. if (cmNonempty(cmakeGeneratorName)) {
  44. const std::string& source_dir =
  45. this->CTest->GetCTestConfiguration("SourceDirectory");
  46. if (source_dir.empty()) {
  47. this->SetError(
  48. "Source directory not specified. Either use SOURCE "
  49. "argument to CTEST_CONFIGURE command or set CTEST_SOURCE_DIRECTORY "
  50. "variable");
  51. return nullptr;
  52. }
  53. const std::string cmakelists_file = source_dir + "/CMakeLists.txt";
  54. if (!cmSystemTools::FileExists(cmakelists_file)) {
  55. std::ostringstream e;
  56. e << "CMakeLists.txt file does not exist [" << cmakelists_file << "]";
  57. this->SetError(e.str());
  58. return nullptr;
  59. }
  60. bool multiConfig = false;
  61. bool cmakeBuildTypeInOptions = false;
  62. auto gg = this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
  63. *cmakeGeneratorName);
  64. if (gg) {
  65. multiConfig = gg->IsMultiConfig();
  66. gg.reset();
  67. }
  68. std::string cmakeConfigureCommand =
  69. cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"');
  70. for (std::string const& option : options) {
  71. cmakeConfigureCommand += " \"";
  72. cmakeConfigureCommand += option;
  73. cmakeConfigureCommand += "\"";
  74. if ((nullptr != strstr(option.c_str(), "CMAKE_BUILD_TYPE=")) ||
  75. (nullptr != strstr(option.c_str(), "CMAKE_BUILD_TYPE:STRING="))) {
  76. cmakeBuildTypeInOptions = true;
  77. }
  78. }
  79. if (!multiConfig && !cmakeBuildTypeInOptions &&
  80. !this->CTest->GetConfigType().empty()) {
  81. cmakeConfigureCommand += " \"-DCMAKE_BUILD_TYPE:STRING=";
  82. cmakeConfigureCommand += this->CTest->GetConfigType();
  83. cmakeConfigureCommand += "\"";
  84. }
  85. if (this->Makefile->IsOn("CTEST_USE_LAUNCHERS")) {
  86. cmakeConfigureCommand += " \"-DCTEST_USE_LAUNCHERS:BOOL=TRUE\"";
  87. }
  88. cmakeConfigureCommand += " \"-G";
  89. cmakeConfigureCommand += *cmakeGeneratorName;
  90. cmakeConfigureCommand += "\"";
  91. cmValue cmakeGeneratorPlatform =
  92. this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM");
  93. if (cmNonempty(cmakeGeneratorPlatform)) {
  94. cmakeConfigureCommand += " \"-A";
  95. cmakeConfigureCommand += *cmakeGeneratorPlatform;
  96. cmakeConfigureCommand += "\"";
  97. }
  98. cmValue cmakeGeneratorToolset =
  99. this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET");
  100. if (cmNonempty(cmakeGeneratorToolset)) {
  101. cmakeConfigureCommand += " \"-T";
  102. cmakeConfigureCommand += *cmakeGeneratorToolset;
  103. cmakeConfigureCommand += "\"";
  104. }
  105. cmakeConfigureCommand += " \"-S";
  106. cmakeConfigureCommand += source_dir;
  107. cmakeConfigureCommand += "\"";
  108. cmakeConfigureCommand += " \"-B";
  109. cmakeConfigureCommand +=
  110. this->CTest->GetCTestConfiguration("BuildDirectory");
  111. cmakeConfigureCommand += "\"";
  112. this->CTest->SetCTestConfiguration("ConfigureCommand",
  113. cmakeConfigureCommand, this->Quiet);
  114. } else {
  115. this->SetError(
  116. "Configure command is not specified. If this is a "
  117. "\"built with CMake\" project, set CTEST_CMAKE_GENERATOR. If not, "
  118. "set CTEST_CONFIGURE_COMMAND.");
  119. return nullptr;
  120. }
  121. }
  122. if (cmValue labelsForSubprojects =
  123. this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) {
  124. this->CTest->SetCTestConfiguration("LabelsForSubprojects",
  125. *labelsForSubprojects, this->Quiet);
  126. }
  127. cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler();
  128. handler->Initialize();
  129. handler->SetQuiet(this->Quiet);
  130. return handler;
  131. }