| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmBuildCommand.h" |
| |
| #include <sstream> |
| |
| #include "cmGlobalGenerator.h" |
| #include "cmMakefile.h" |
| #include "cmMessageType.h" |
| #include "cmStateTypes.h" |
| #include "cmSystemTools.h" |
| |
| class cmExecutionStatus; |
| |
| bool cmBuildCommand::InitialPass(std::vector<std::string> const& args, |
| cmExecutionStatus&) |
| { |
| // Support the legacy signature of the command: |
| // |
| if (2 == args.size()) { |
| return this->TwoArgsSignature(args); |
| } |
| |
| return this->MainSignature(args); |
| } |
| |
| bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) |
| { |
| if (args.empty()) { |
| this->SetError("requires at least one argument naming a CMake variable"); |
| return false; |
| } |
| |
| // The cmake variable in which to store the result. |
| std::string const& variable = args[0]; |
| |
| // Parse remaining arguments. |
| std::string configuration; |
| std::string project_name; |
| std::string target; |
| enum Doing |
| { |
| DoingNone, |
| DoingConfiguration, |
| DoingProjectName, |
| DoingTarget |
| }; |
| Doing doing = DoingNone; |
| for (unsigned int i = 1; i < args.size(); ++i) { |
| if (args[i] == "CONFIGURATION") { |
| doing = DoingConfiguration; |
| } else if (args[i] == "PROJECT_NAME") { |
| doing = DoingProjectName; |
| } else if (args[i] == "TARGET") { |
| doing = DoingTarget; |
| } else if (doing == DoingConfiguration) { |
| doing = DoingNone; |
| configuration = args[i]; |
| } else if (doing == DoingProjectName) { |
| doing = DoingNone; |
| project_name = args[i]; |
| } else if (doing == DoingTarget) { |
| doing = DoingNone; |
| target = args[i]; |
| } else { |
| std::ostringstream e; |
| e << "unknown argument \"" << args[i] << "\""; |
| this->SetError(e.str()); |
| return false; |
| } |
| } |
| |
| // If null/empty CONFIGURATION argument, cmake --build uses 'Debug' |
| // in the currently implemented multi-configuration global generators... |
| // so we put this code here to end up with the same default configuration |
| // as the original 2-arg build_command signature: |
| // |
| if (configuration.empty()) { |
| cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configuration); |
| } |
| if (configuration.empty()) { |
| configuration = "Release"; |
| } |
| |
| if (!project_name.empty()) { |
| this->Makefile->IssueMessage( |
| MessageType::AUTHOR_WARNING, |
| "Ignoring PROJECT_NAME option because it has no effect."); |
| } |
| |
| std::string makecommand = |
| this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand( |
| target, configuration, "", this->Makefile->IgnoreErrorsCMP0061()); |
| |
| this->Makefile->AddDefinition(variable, makecommand); |
| |
| return true; |
| } |
| |
| bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args) |
| { |
| if (args.size() < 2) { |
| this->SetError("called with less than two arguments"); |
| return false; |
| } |
| |
| std::string const& define = args[0]; |
| const char* cacheValue = this->Makefile->GetDefinition(define); |
| |
| std::string configType; |
| if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) || |
| configType.empty()) { |
| configType = "Release"; |
| } |
| |
| std::string makecommand = |
| this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand( |
| "", configType, "", this->Makefile->IgnoreErrorsCMP0061()); |
| |
| if (cacheValue) { |
| return true; |
| } |
| this->Makefile->AddCacheDefinition(define, makecommand.c_str(), |
| "Command used to build entire project " |
| "from the command line.", |
| cmStateEnums::STRING); |
| return true; |
| } |