cmCTestConfigureCommand.cxx 5.1 KB

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