/* 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 "cmExecutionStatus.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmValue.h" namespace { bool MainSignature(std::vector const& args, cmExecutionStatus& status) { if (args.empty()) { status.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; std::string parallel; enum Doing { DoingNone, DoingConfiguration, DoingProjectName, DoingTarget, DoingParallel }; 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 (args[i] == "PARALLEL_LEVEL") { doing = DoingParallel; } 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 if (doing == DoingParallel) { doing = DoingNone; parallel = args[i]; } else { status.SetError(cmStrCat("unknown argument \"", args[i], "\"")); 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"; } cmMakefile& mf = status.GetMakefile(); if (!project_name.empty()) { mf.IssueMessage(MessageType::AUTHOR_WARNING, "Ignoring PROJECT_NAME option because it has no effect."); } std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand( target, configuration, parallel, "", mf.IgnoreErrorsCMP0061()); mf.AddDefinition(variable, makecommand); return true; } bool TwoArgsSignature(std::vector const& args, cmExecutionStatus& status) { if (args.size() < 2) { status.SetError("called with less than two arguments"); return false; } cmMakefile& mf = status.GetMakefile(); std::string const& define = args[0]; cmValue cacheValue = mf.GetDefinition(define); std::string configType; if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) || configType.empty()) { configType = "Release"; } std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand( "", configType, "", "", mf.IgnoreErrorsCMP0061()); if (cacheValue) { return true; } mf.AddCacheDefinition(define, makecommand, "Command used to build entire project " "from the command line.", cmStateEnums::STRING); return true; } } // namespace bool cmBuildCommand(std::vector const& args, cmExecutionStatus& status) { // Support the legacy signature of the command: if (args.size() == 2) { return TwoArgsSignature(args, status); } return MainSignature(args, status); }