/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestConfigureCommand.h" #include #include #include #include #include "cmCTest.h" #include "cmCTestConfigureHandler.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmValue.h" #include "cmake.h" void cmCTestConfigureCommand::BindArguments() { this->cmCTestHandlerCommand::BindArguments(); this->Bind("OPTIONS"_s, this->Options); } cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() { std::vector options; if (!this->Options.empty()) { cmExpandList(this->Options, options); } if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) { this->SetError( "Build directory not specified. Either use BUILD " "argument to CTEST_CONFIGURE command or set CTEST_BINARY_DIRECTORY " "variable"); return nullptr; } cmValue ctestConfigureCommand = this->Makefile->GetDefinition("CTEST_CONFIGURE_COMMAND"); if (cmNonempty(ctestConfigureCommand)) { this->CTest->SetCTestConfiguration("ConfigureCommand", *ctestConfigureCommand, this->Quiet); } else { cmValue cmakeGeneratorName = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR"); if (cmNonempty(cmakeGeneratorName)) { const std::string& source_dir = this->CTest->GetCTestConfiguration("SourceDirectory"); if (source_dir.empty()) { this->SetError( "Source directory not specified. Either use SOURCE " "argument to CTEST_CONFIGURE command or set CTEST_SOURCE_DIRECTORY " "variable"); return nullptr; } const std::string cmakelists_file = source_dir + "/CMakeLists.txt"; if (!cmSystemTools::FileExists(cmakelists_file)) { std::ostringstream e; e << "CMakeLists.txt file does not exist [" << cmakelists_file << "]"; this->SetError(e.str()); return nullptr; } bool multiConfig = false; bool cmakeBuildTypeInOptions = false; auto gg = this->Makefile->GetCMakeInstance()->CreateGlobalGenerator( *cmakeGeneratorName); if (gg) { multiConfig = gg->IsMultiConfig(); gg.reset(); } std::string cmakeConfigureCommand = cmStrCat('"', cmSystemTools::GetCMakeCommand(), '"'); for (std::string const& option : options) { cmakeConfigureCommand += " \""; cmakeConfigureCommand += option; cmakeConfigureCommand += "\""; if ((nullptr != strstr(option.c_str(), "CMAKE_BUILD_TYPE=")) || (nullptr != strstr(option.c_str(), "CMAKE_BUILD_TYPE:STRING="))) { cmakeBuildTypeInOptions = true; } } if (!multiConfig && !cmakeBuildTypeInOptions && !this->CTest->GetConfigType().empty()) { cmakeConfigureCommand += " \"-DCMAKE_BUILD_TYPE:STRING="; cmakeConfigureCommand += this->CTest->GetConfigType(); cmakeConfigureCommand += "\""; } if (this->Makefile->IsOn("CTEST_USE_LAUNCHERS")) { cmakeConfigureCommand += " \"-DCTEST_USE_LAUNCHERS:BOOL=TRUE\""; } cmakeConfigureCommand += " \"-G"; cmakeConfigureCommand += *cmakeGeneratorName; cmakeConfigureCommand += "\""; cmValue cmakeGeneratorPlatform = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_PLATFORM"); if (cmNonempty(cmakeGeneratorPlatform)) { cmakeConfigureCommand += " \"-A"; cmakeConfigureCommand += *cmakeGeneratorPlatform; cmakeConfigureCommand += "\""; } cmValue cmakeGeneratorToolset = this->Makefile->GetDefinition("CTEST_CMAKE_GENERATOR_TOOLSET"); if (cmNonempty(cmakeGeneratorToolset)) { cmakeConfigureCommand += " \"-T"; cmakeConfigureCommand += *cmakeGeneratorToolset; cmakeConfigureCommand += "\""; } cmakeConfigureCommand += " \""; cmakeConfigureCommand += source_dir; cmakeConfigureCommand += "\""; this->CTest->SetCTestConfiguration("ConfigureCommand", cmakeConfigureCommand, this->Quiet); } else { this->SetError( "Configure command is not specified. If this is a " "\"built with CMake\" project, set CTEST_CMAKE_GENERATOR. If not, " "set CTEST_CONFIGURE_COMMAND."); return nullptr; } } if (cmValue labelsForSubprojects = this->Makefile->GetDefinition("CTEST_LABELS_FOR_SUBPROJECTS")) { this->CTest->SetCTestConfiguration("LabelsForSubprojects", *labelsForSubprojects, this->Quiet); } cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler(); handler->Initialize(); handler->SetQuiet(this->Quiet); return handler; }