diff options
Diffstat (limited to 'Source')
26 files changed, 383 insertions, 322 deletions
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index b2c88df6d1..a7d4455e20 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -256,7 +256,7 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) } int retVal = cm.GetGlobalGenerator()->Build( cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, - this->BuildProject, tar, output, this->BuildMakeProgram, config, + this->BuildProject, { tar }, output, this->BuildMakeProgram, config, !this->BuildNoClean, false, false, remainingTime); out << output; // if the build failed then return diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index c2eb583a93..281d3718ee 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -53,15 +53,16 @@ void cmGlobalBorlandMakefileGenerator::GetDocumentation( entry.Brief = "Generates Borland makefiles."; } -void cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, - int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int /*jobs*/, bool verbose, + std::vector<std::string> const& makeOptions) { - this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeCommand, makeProgram, projectName, projectDir, targetName, config, - fast, cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); + return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeProgram, projectName, projectDir, targetNames, config, fast, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); } void cmGlobalBorlandMakefileGenerator::PrintBuildCommandAdvice( diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index ca04b7b739..02d0d5ffd3 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -46,15 +46,12 @@ public: bool AllowDeleteOnError() const override { return false; } protected: - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; }; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index a9f37b7a7f..6964b62e46 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1763,9 +1763,9 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, this->FirstTimeProgress); } - std::string newTarget; + std::vector<std::string> newTarget = {}; if (!target.empty()) { - newTarget += target; + newTarget = { target }; } std::string config = mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); @@ -1773,14 +1773,16 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, config, false, fast, false, this->TryCompileTimeout); } -void cmGlobalGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& /*unused*/, +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalGenerator::GenerateBuildCommand( const std::string& /*unused*/, const std::string& /*unused*/, - const std::string& /*unused*/, const std::string& /*unused*/, - bool /*unused*/, int /*unused*/, bool /*unused*/, - std::vector<std::string> const& /*unused*/) + const std::string& /*unused*/, std::vector<std::string> const& /*unused*/, + const std::string& /*unused*/, bool /*unused*/, int /*unused*/, + bool /*unused*/, std::vector<std::string> const& /*unused*/) { + GeneratedMakeCommand makeCommand; makeCommand.Add("cmGlobalGenerator::GenerateBuildCommand not implemented"); + return { std::move(makeCommand) }; } void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, @@ -1790,15 +1792,13 @@ void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, // they do not support certain build command line options } -int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, - const std::string& bindir, - const std::string& projectName, - const std::string& target, std::string& output, - const std::string& makeCommandCSTR, - const std::string& config, bool clean, bool fast, - bool verbose, cmDuration timeout, - cmSystemTools::OutputOption outputflag, - std::vector<std::string> const& nativeOptions) +int cmGlobalGenerator::Build( + int jobs, const std::string& /*unused*/, const std::string& bindir, + const std::string& projectName, const std::vector<std::string>& targets, + std::string& output, const std::string& makeCommandCSTR, + const std::string& config, bool clean, bool fast, bool verbose, + cmDuration timeout, cmSystemTools::OutputOption outputflag, + std::vector<std::string> const& nativeOptions) { bool hideconsole = cmSystemTools::GetRunCommandHideConsole(); @@ -1819,32 +1819,37 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, return 1; } - int retVal; + int retVal = 0; cmSystemTools::SetRunCommandHideConsole(true); std::string outputBuffer; std::string* outputPtr = &outputBuffer; - GeneratedMakeCommand makeCommand; - this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir, - target, config, fast, jobs, verbose, - nativeOptions); + std::vector<GeneratedMakeCommand> makeCommand = + this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets, + config, fast, jobs, verbose, nativeOptions); // Workaround to convince some commands to produce output. if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && - makeCommand.RequiresOutputForward) { + makeCommand.back().RequiresOutputForward) { outputflag = cmSystemTools::OUTPUT_FORWARD; } // should we do a clean first? if (clean) { - GeneratedMakeCommand cleanCommand; - this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, - bindir, "clean", config, fast, jobs, verbose); + std::vector<GeneratedMakeCommand> cleanCommand = + this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, + { "clean" }, config, fast, jobs, verbose); output += "\nRun Clean Command:"; - output += cleanCommand.Printable(); + output += cleanCommand.front().Printable(); output += "\n"; - - if (!cmSystemTools::RunSingleCommand(cleanCommand.PrimaryCommand, + if (cleanCommand.size() != 1) { + this->GetCMakeInstance()->IssueMessage(MessageType::INTERNAL_ERROR, + "The generator did not produce " + "exactly one command for the " + "'clean' target"); + return 1; + } + if (!cmSystemTools::RunSingleCommand(cleanCommand.front().PrimaryCommand, outputPtr, outputPtr, &retVal, nullptr, outputflag, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); @@ -1858,25 +1863,33 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, } // now build - std::string makeCommandStr = makeCommand.Printable(); + std::string makeCommandStr; output += "\nRun Build Command(s):"; - output += makeCommandStr; - output += "\n"; - if (!cmSystemTools::RunSingleCommand(makeCommand.PrimaryCommand, outputPtr, - outputPtr, &retVal, nullptr, outputflag, - timeout)) { - cmSystemTools::SetRunCommandHideConsole(hideconsole); - cmSystemTools::Error( - "Generator: execution of make failed. Make command was: " + - makeCommandStr); - output += *outputPtr; - output += "\nGenerator: execution of make failed. Make command was: " + - makeCommandStr + "\n"; + for (auto command = makeCommand.begin(); command != makeCommand.end(); + ++command) { + makeCommandStr = command->Printable(); + if (command != makeCommand.end()) { + makeCommandStr += " && "; + } - return 1; + output += makeCommandStr; + if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr, + outputPtr, &retVal, nullptr, + outputflag, timeout)) { + cmSystemTools::SetRunCommandHideConsole(hideconsole); + cmSystemTools::Error( + "Generator: execution of make failed. Make command was: " + + makeCommandStr); + output += *outputPtr; + output += "\nGenerator: execution of make failed. Make command was: " + + makeCommandStr + "\n"; + + return 1; + } + output += *outputPtr; } - output += *outputPtr; + output += "\n"; cmSystemTools::SetRunCommandHideConsole(hideconsole); // The OpenWatcom tools do not return an error code when a link diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 1eda572f79..17eb340663 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -13,6 +13,7 @@ #include <utility> #include <vector> +#include "cmAlgorithms.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" #include "cmExportSetMap.h" @@ -203,10 +204,10 @@ public: */ int Build( int jobs, const std::string& srcdir, const std::string& bindir, - const std::string& projectName, const std::string& targetName, - std::string& output, const std::string& makeProgram, - const std::string& config, bool clean, bool fast, bool verbose, - cmDuration timeout, + const std::string& projectName, + std::vector<std::string> const& targetNames, std::string& output, + const std::string& makeProgram, const std::string& config, bool clean, + bool fast, bool verbose, cmDuration timeout, cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE, std::vector<std::string> const& nativeOptions = std::vector<std::string>()); @@ -221,11 +222,10 @@ public: { }; - virtual void GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, - int jobs, bool verbose, + virtual std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()); virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const; diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 3511a15092..4f1d06a232 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -369,12 +369,14 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject( fout.Close(); } -void cmGlobalGhsMultiGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& /*config*/, bool /*fast*/, - int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalGhsMultiGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& /*config*/, bool /*fast*/, int jobs, bool /*verbose*/, + std::vector<std::string> const& makeOptions) { + GeneratedMakeCommand makeCommand = {}; const char* gbuild = this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); makeCommand.Add(this->SelectMakeProgram(makeProgram, (std::string)gbuild)); @@ -400,17 +402,23 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand( } makeCommand.Add("-top", proj); - if (!targetName.empty()) { - if (targetName == "clean") { + if (!targetNames.empty()) { + if (std::find(targetNames.begin(), targetNames.end(), "clean") != + targetNames.end()) { makeCommand.Add("-clean"); } else { - if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) { - makeCommand.Add(targetName); - } else { - makeCommand.Add(targetName + ".gpj"); + for (const auto& tname : targetNames) { + if (!tname.empty()) { + if (tname.compare(tname.size() - 4, 4, ".gpj") == 0) { + makeCommand.Add(tname); + } else { + makeCommand.Add(tname + ".gpj"); + } + } } } } + return { makeCommand }; } void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout) diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index bc2b199a00..c39f40fbec 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -88,15 +88,12 @@ public: protected: void Generate() override; - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; private: void GetToolset(cmMakefile* mf, std::string& tsd, const std::string& ts); diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 2b7f486955..43c966649b 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -54,11 +54,12 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice( this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar); } -void cmGlobalJOMMakefileGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, - int jobs, bool verbose, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalJOMMakefileGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions) { std::vector<std::string> jomMakeOptions; @@ -75,7 +76,7 @@ void cmGlobalJOMMakefileGenerator::GenerateBuildCommand( jobs = cmake::NO_BUILD_PARALLEL_LEVEL; } - cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeCommand, makeProgram, projectName, projectDir, targetName, config, - fast, jobs, verbose, jomMakeOptions); + return cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeProgram, projectName, projectDir, targetNames, config, fast, jobs, + verbose, jomMakeOptions); } diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index aa8b5fbb02..341b2dd091 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -40,15 +40,12 @@ public: bool optional) override; protected: - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; private: void PrintCompilerAdvice(std::ostream& os, std::string const& lang, diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index ffe95f905c..a4838bc27e 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -54,11 +54,12 @@ void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice( this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar); } -void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, - int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int /*jobs*/, bool verbose, + std::vector<std::string> const& makeOptions) { std::vector<std::string> nmakeMakeOptions; @@ -68,9 +69,9 @@ void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( nmakeMakeOptions.insert(nmakeMakeOptions.end(), makeOptions.begin(), makeOptions.end()); - this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeCommand, makeProgram, projectName, projectDir, targetName, config, - fast, cmake::NO_BUILD_PARALLEL_LEVEL, verbose, nmakeMakeOptions); + return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeProgram, projectName, projectDir, targetNames, config, fast, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, nmakeMakeOptions); } void cmGlobalNMakeMakefileGenerator::PrintBuildCommandAdvice(std::ostream& os, diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index 06c48e22ba..1fc2f9c770 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -45,15 +45,12 @@ public: bool optional) override; protected: - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 61571f1b99..841587cce7 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -677,12 +677,15 @@ void cmGlobalNinjaGenerator::EnableLanguage( // cmGlobalXCodeGenerator // Called by: // cmGlobalGenerator::Build() -void cmGlobalNinjaGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& /*projectName*/, const std::string& /*projectDir*/, - const std::string& targetName, const std::string& /*config*/, bool /*fast*/, - int jobs, bool verbose, std::vector<std::string> const& makeOptions) -{ +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalNinjaGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& /*projectName*/, + const std::string& /*projectDir*/, + std::vector<std::string> const& targetNames, const std::string& /*config*/, + bool /*fast*/, int jobs, bool verbose, + std::vector<std::string> const& makeOptions) +{ + GeneratedMakeCommand makeCommand; makeCommand.Add(this->SelectMakeProgram(makeProgram)); if (verbose) { @@ -695,13 +698,16 @@ void cmGlobalNinjaGenerator::GenerateBuildCommand( } makeCommand.Add(makeOptions.begin(), makeOptions.end()); - if (!targetName.empty()) { - if (targetName == "clean") { - makeCommand.Add("-t", "clean"); - } else { - makeCommand.Add(targetName); + for (const auto& tname : targetNames) { + if (!tname.empty()) { + if (tname == "clean") { + makeCommand.Add("-t", "clean"); + } else { + makeCommand.Add(tname); + } } } + return { std::move(makeCommand) }; } // Non-virtual public methods. diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 69210ecc55..efd1d8fc3a 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -200,15 +200,12 @@ public: void EnableLanguage(std::vector<std::string> const& languages, cmMakefile* mf, bool optional) override; - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; // Setup target names const char* GetAllTargetName() const override { return "all"; } diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 8f8239ef71..3381c81143 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -494,11 +494,13 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true); } -void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& /*projectName*/, const std::string& /*projectDir*/, - const std::string& targetName, const std::string& /*config*/, bool fast, - int jobs, bool verbose, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + const std::string& makeProgram, const std::string& /*projectName*/, + const std::string& /*projectDir*/, + std::vector<std::string> const& targetNames, const std::string& /*config*/, + bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions) { std::unique_ptr<cmMakefile> mfu; cmMakefile* mf; @@ -515,6 +517,8 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( mf = mfu.get(); } + GeneratedMakeCommand makeCommand; + // Make it possible to set verbosity also from command line if (verbose) { makeCommand.Add(cmSystemTools::GetCMakeCommand()); @@ -532,17 +536,19 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( } makeCommand.Add(makeOptions.begin(), makeOptions.end()); - if (!targetName.empty()) { - std::string tname = targetName; - if (fast) { - tname += "/fast"; + for (auto tname : targetNames) { + if (!tname.empty()) { + if (fast) { + tname += "/fast"; + } + tname = + mf->GetStateSnapshot().GetDirectory().ConvertToRelPathIfNotContained( + mf->GetState()->GetBinaryDirectory(), tname); + cmSystemTools::ConvertToOutputSlashes(tname); + makeCommand.Add(std::move(tname)); } - tname = - mf->GetStateSnapshot().GetDirectory().ConvertToRelPathIfNotContained( - mf->GetState()->GetBinaryDirectory(), tname); - cmSystemTools::ConvertToOutputSlashes(tname); - makeCommand.Add(std::move(tname)); } + return { std::move(makeCommand) }; } void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules( diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 8a80acc057..496104d741 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -127,15 +127,12 @@ public: std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; } // change the build command for speed - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; /** Record per-target progress information. */ void RecordTargetProgress(cmMakefileTargetGenerator* tg); diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 9e83425d98..26fd62b896 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -878,12 +878,14 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) return true; } -void cmGlobalVisualStudio10Generator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, - int jobs, bool verbose, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalVisualStudio10Generator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions) { + std::vector<GeneratedMakeCommand> makeCommands; // Select the caller- or user-preferred make program, else MSBuild. std::string makeProgramSelected = this->SelectMakeProgram(makeProgram, this->GetMSBuildCommand()); @@ -895,7 +897,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( makeProgramLower.find("vcexpress") != std::string::npos); // Workaround to convince VCExpress.exe to produce output. - makeCommand.RequiresOutputForward = + const bool requiresOutputForward = (makeProgramLower.find("vcexpress") != std::string::npos); // MSBuild is preferred (and required for VS Express), but if the .sln has @@ -926,62 +928,71 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( } if (useDevEnv) { // Use devenv to build solutions containing Intel Fortran projects. - cmGlobalVisualStudio7Generator::GenerateBuildCommand( - makeCommand, makeProgram, projectName, projectDir, targetName, config, - fast, jobs, verbose, makeOptions); - return; - } + return cmGlobalVisualStudio7Generator::GenerateBuildCommand( + makeProgram, projectName, projectDir, targetNames, config, fast, jobs, + verbose, makeOptions); + } + + std::vector<std::string> realTargetNames = targetNames; + if (targetNames.empty() || + ((targetNames.size() == 1) && targetNames.front().empty())) { + realTargetNames = { "ALL_BUILD" }; + } + for (const auto& tname : realTargetNames) { + // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug + // /target:ALL_BUILD + // /m + if (tname.empty()) { + continue; + } - makeCommand.Add(makeProgramSelected); + GeneratedMakeCommand makeCommand; + makeCommand.RequiresOutputForward = requiresOutputForward; + makeCommand.Add(makeProgramSelected); - std::string realTarget = targetName; - // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD - // /m - if (realTarget.empty()) { - realTarget = "ALL_BUILD"; - } - if (realTarget == "clean") { - makeCommand.Add(std::string(projectName) + ".sln"); - makeCommand.Add("/t:Clean"); - } else { - std::string targetProject(realTarget); - targetProject += ".vcxproj"; - if (targetProject.find('/') == std::string::npos) { - // it might be in a subdir - if (cmSlnProjectEntry const* proj = - slnData.GetProjectByName(realTarget)) { - targetProject = proj->GetRelativePath(); - cmSystemTools::ConvertToUnixSlashes(targetProject); + if (tname == "clean") { + makeCommand.Add(std::string(projectName) + ".sln"); + makeCommand.Add("/t:Clean"); + } else { + std::string targetProject(tname); + targetProject += ".vcxproj"; + if (targetProject.find('/') == std::string::npos) { + // it might be in a subdir + if (cmSlnProjectEntry const* proj = slnData.GetProjectByName(tname)) { + targetProject = proj->GetRelativePath(); + cmSystemTools::ConvertToUnixSlashes(targetProject); + } } + makeCommand.Add(std::move(targetProject)); } - makeCommand.Add(std::move(targetProject)); - } - std::string configArg = "/p:Configuration="; - if (!config.empty()) { - configArg += config; - } else { - configArg += "Debug"; - } - makeCommand.Add(configArg); - makeCommand.Add(std::string("/p:Platform=") + this->GetPlatformName()); - makeCommand.Add(std::string("/p:VisualStudioVersion=") + - this->GetIDEVersion()); - - if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { - if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { - makeCommand.Add("/m"); + std::string configArg = "/p:Configuration="; + if (!config.empty()) { + configArg += config; } else { - makeCommand.Add(std::string("/m:") + std::to_string(jobs)); + configArg += "Debug"; + } + makeCommand.Add(configArg); + makeCommand.Add(std::string("/p:Platform=") + this->GetPlatformName()); + makeCommand.Add(std::string("/p:VisualStudioVersion=") + + this->GetIDEVersion()); + + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { + makeCommand.Add("/m"); + } else { + makeCommand.Add(std::string("/m:") + std::to_string(jobs)); + } + // Having msbuild.exe and cl.exe using multiple jobs is discouraged + makeCommand.Add("/p:CL_MPCount=1"); } - // Having msbuild.exe and cl.exe using multiple jobs is discouraged - makeCommand.Add("/p:CL_MPCount=1"); - } - - // Respect the verbosity: 'n' normal will show build commands - // 'm' minimal only the build step's title - makeCommand.Add(std::string("/v:") + ((verbose) ? "n" : "m")); - makeCommand.Add(makeOptions.begin(), makeOptions.end()); + // Respect the verbosity: 'n' normal will show build commands + // 'm' minimal only the build step's title + makeCommand.Add(std::string("/v:") + ((verbose) ? "n" : "m")); + makeCommand.Add(makeOptions.begin(), makeOptions.end()); + makeCommands.emplace_back(std::move(makeCommand)); + } + return makeCommands; } bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf) diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 3ef7abfd05..26db92940e 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -22,15 +22,12 @@ public: bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override; bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override; - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; ///! create the correct local generator cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index f091d90938..c694902428 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -190,11 +190,14 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType( } return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; } -void cmGlobalVisualStudio7Generator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& /*projectDir*/, - const std::string& targetName, const std::string& config, bool /*fast*/, - int /*jobs*/, bool /*verbose*/, std::vector<std::string> const& makeOptions) + +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalVisualStudio7Generator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& /*projectDir*/, + std::vector<std::string> const& targetNames, const std::string& config, + bool /*fast*/, int /*jobs*/, bool /*verbose*/, + std::vector<std::string> const& makeOptions) { // Select the caller- or user-preferred make program, else devenv. std::string makeProgramSelected = @@ -210,24 +213,39 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand( } // Workaround to convince VCExpress.exe to produce output. - makeCommand.RequiresOutputForward = + const bool requiresOutputForward = (makeProgramLower.find("vcexpress") != std::string::npos); + std::vector<GeneratedMakeCommand> makeCommands; - makeCommand.Add(makeProgramSelected); - - makeCommand.Add(std::string(projectName) + ".sln"); - std::string realTarget = targetName; - bool clean = false; - if (realTarget == "clean") { - clean = true; - realTarget = "ALL_BUILD"; + std::vector<std::string> realTargetNames = targetNames; + if (targetNames.empty() || + ((targetNames.size() == 1) && targetNames.front().empty())) { + realTargetNames = { "ALL_BUILD" }; } - - makeCommand.Add((clean ? "/clean" : "/build")); - makeCommand.Add((config.empty() ? "Debug" : config)); - makeCommand.Add("/project"); - makeCommand.Add((realTarget.empty() ? "ALL_BUILD" : realTarget)); - makeCommand.Add(makeOptions.begin(), makeOptions.end()); + for (const auto& tname : realTargetNames) { + std::string realTarget; + if (!tname.empty()) { + realTarget = tname; + } else { + continue; + } + bool clean = false; + if (realTarget == "clean") { + clean = true; + realTarget = "ALL_BUILD"; + } + GeneratedMakeCommand makeCommand; + makeCommand.RequiresOutputForward = requiresOutputForward; + makeCommand.Add(makeProgramSelected); + makeCommand.Add(std::string(projectName) + ".sln"); + makeCommand.Add((clean ? "/clean" : "/build")); + makeCommand.Add((config.empty() ? "Debug" : config)); + makeCommand.Add("/project"); + makeCommand.Add(realTarget); + makeCommand.Add(makeOptions.begin(), makeOptions.end()); + makeCommands.emplace_back(std::move(makeCommand)); + } + return makeCommands; } ///! Create a local generator appropriate to this Global Generator diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 3f1c1732d1..954d1d325d 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -52,15 +52,12 @@ public: * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; /** * Generate the DSW workspace file. diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index c02c4711aa..8a27384311 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -3,6 +3,7 @@ #include "cmGlobalWatcomWMakeGenerator.h" #include "cmDocumentationEntry.h" +#include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmState.h" #include "cmake.h" @@ -50,15 +51,16 @@ void cmGlobalWatcomWMakeGenerator::GetDocumentation( entry.Brief = "Generates Watcom WMake makefiles."; } -void cmGlobalWatcomWMakeGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& projectDir, - const std::string& targetName, const std::string& config, bool fast, - int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalWatcomWMakeGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int /*jobs*/, bool verbose, + std::vector<std::string> const& makeOptions) { - this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeCommand, makeProgram, projectName, projectDir, targetName, config, - fast, cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); + return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeProgram, projectName, projectDir, targetNames, config, fast, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); } void cmGlobalWatcomWMakeGenerator::PrintBuildCommandAdvice(std::ostream& os, diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index 6680b193f0..c96dc7245f 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -50,15 +50,12 @@ public: bool AllowDeleteOnError() const override { return false; } protected: - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; }; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 88720b6dc8..53baed58b3 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -334,12 +334,15 @@ bool cmGlobalXCodeGenerator::Open(const std::string& bindir, return ret; } -void cmGlobalXCodeGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& makeProgram, - const std::string& projectName, const std::string& /*projectDir*/, - const std::string& targetName, const std::string& config, bool /*fast*/, - int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) -{ +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalXCodeGenerator::GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& /*projectDir*/, + std::vector<std::string> const& targetNames, const std::string& config, + bool /*fast*/, int jobs, bool /*verbose*/, + std::vector<std::string> const& makeOptions) +{ + GeneratedMakeCommand makeCommand; // now build the test makeCommand.Add( this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand())); @@ -351,16 +354,24 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand( projectArg += "proj"; makeCommand.Add(projectArg); } - - bool clean = false; - std::string realTarget = targetName; - if (realTarget == "clean") { - clean = true; - realTarget = "ALL_BUILD"; + if (std::find(targetNames.begin(), targetNames.end(), "clean") != + targetNames.end()) { + makeCommand.Add("clean"); + makeCommand.Add("-target", "ALL_BUILD"); + } else { + makeCommand.Add("build"); + if (targetNames.empty() || + ((targetNames.size() == 1) && targetNames.front().empty())) { + makeCommand.Add("-target", "ALL_BUILD"); + } else { + for (const auto& tname : targetNames) { + if (!tname.empty()) { + makeCommand.Add("-target", tname); + } + } + } } - makeCommand.Add((clean ? "clean" : "build")); - makeCommand.Add("-target", (realTarget.empty() ? "ALL_BUILD" : realTarget)); makeCommand.Add("-configuration", (config.empty() ? "Debug" : config)); if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { @@ -374,6 +385,7 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand( makeCommand.Add("-hideShellScriptEnvironment"); } makeCommand.Add(makeOptions.begin(), makeOptions.end()); + return { std::move(makeCommand) }; } ///! Create a local generator appropriate to this Global Generator diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index e1e412dca5..95db852caf 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -66,15 +66,12 @@ public: * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. */ - void GenerateBuildCommand(GeneratedMakeCommand& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, int jobs, - bool verbose, - std::vector<std::string> const& makeOptions = - std::vector<std::string>()) override; + std::vector<GeneratedMakeCommand> GenerateBuildCommand( + const std::string& makeProgram, const std::string& projectName, + const std::string& projectDir, std::vector<std::string> const& targetNames, + const std::string& config, bool fast, int jobs, bool verbose, + std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; /** Append the subdirectory for the given configuration. */ void AppendDirectoryForConfig(const std::string& prefix, diff --git a/Source/cmake.cxx b/Source/cmake.cxx index f6f0a953dd..63f5efb81a 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2529,7 +2529,8 @@ cmMessenger* cmake::GetMessenger() const return this->Messenger; } -int cmake::Build(int jobs, const std::string& dir, const std::string& target, +int cmake::Build(int jobs, const std::string& dir, + const std::vector<std::string>& targets, const std::string& config, const std::vector<std::string>& nativeOptions, bool clean, bool verbose) @@ -2648,9 +2649,8 @@ int cmake::Build(int jobs, const std::string& dir, const std::string& target, #endif gen->PrintBuildCommandAdvice(std::cerr, jobs); - - return gen->Build(jobs, "", dir, projName, target, output, "", config, clean, - false, verbose, cmDuration::zero(), + return gen->Build(jobs, "", dir, projName, targets, output, "", config, + clean, false, verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); } diff --git a/Source/cmake.h b/Source/cmake.h index 6fa2d3a947..1ffeabcb9c 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -424,8 +424,8 @@ public: cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const; ///! run the --build option - int Build(int jobs, const std::string& dir, const std::string& target, - const std::string& config, + int Build(int jobs, const std::string& dir, + const std::vector<std::string>& targets, const std::string& config, const std::vector<std::string>& nativeOptions, bool clean, bool verbose); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 3465721729..1c56bcd278 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -63,7 +63,7 @@ static const char* cmDocumentationUsageNote[][2] = { "option\n" \ " is not given.\n" \ " --target <tgt> = Build <tgt> instead of default targets.\n" \ - " May only be specified once.\n" \ + " May be specified multiple times.\n" \ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ " --clean-first = Build target 'clean' first, then build.\n" \ " (To clean only, use --target 'clean'.)\n" \ @@ -394,13 +394,14 @@ static int do_build(int ac, char const* const* av) return -1; #else int jobs = cmake::NO_BUILD_PARALLEL_LEVEL; - std::string target; + std::vector<std::string> targets; std::string config = "Debug"; std::string dir; std::vector<std::string> nativeOptions; - bool clean = false; + bool cleanFirst = false; + bool foundClean = false; + bool foundNonClean = false; bool verbose = cmSystemTools::HasEnv("VERBOSE"); - bool hasTarget = false; enum Doing { @@ -420,25 +421,20 @@ static int do_build(int ac, char const* const* av) if (jobs < 0) { dir.clear(); } + doing = DoingNone; } else if (cmHasLiteralPrefix(av[i], "--parallel")) { const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr); jobs = extract_job_number(i, av[i], nextArg, sizeof("--parallel") - 1); if (jobs < 0) { dir.clear(); } + doing = DoingNone; } else if (strcmp(av[i], "--target") == 0) { - if (!hasTarget) { - doing = DoingTarget; - hasTarget = true; - } else { - std::cerr << "'--target' may not be specified more than once.\n\n"; - dir.clear(); - break; - } + doing = DoingTarget; } else if (strcmp(av[i], "--config") == 0) { doing = DoingConfig; } else if (strcmp(av[i], "--clean-first") == 0) { - clean = true; + cleanFirst = true; doing = DoingNone; } else if ((strcmp(av[i], "--verbose") == 0) || (strcmp(av[i], "-v") == 0)) { @@ -455,8 +451,23 @@ static int do_build(int ac, char const* const* av) doing = DoingNone; break; case DoingTarget: - target = av[i]; - doing = DoingNone; + if (strlen(av[i]) == 0) { + std::cerr << "Warning: Argument number " << i + << " after --target option is empty." << std::endl; + } else { + targets.emplace_back(av[i]); + if (strcmp(av[i], "clean") == 0) { + foundClean = true; + } else { + foundNonClean = true; + } + } + if (foundClean && foundNonClean) { + std::cerr << "Error: Building 'clean' and other targets together " + "is not supported." + << std::endl; + dir.clear(); + } break; case DoingConfig: config = av[i]; @@ -507,7 +518,8 @@ static int do_build(int ac, char const* const* av) cm.SetProgressCallback([&cm](const std::string& msg, float prog) { cmakemainProgressCallback(msg, prog, &cm); }); - return cm.Build(jobs, dir, target, config, nativeOptions, clean, verbose); + return cm.Build(jobs, dir, targets, config, nativeOptions, cleanFirst, + verbose); #endif } |