Commit 1a45266c authored by Robert Maynard's avatar Robert Maynard Committed by Brad King

cmGlobalGenerator: Add a class that represent the build command

This refactors a std::vector<std::string> into a class so that
we can extend the features to represent things such as multiple
chained commands in the future.
parent 378473f9
...@@ -54,7 +54,7 @@ void cmGlobalBorlandMakefileGenerator::GetDocumentation( ...@@ -54,7 +54,7 @@ void cmGlobalBorlandMakefileGenerator::GetDocumentation(
} }
void cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( void cmGlobalBorlandMakefileGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir, const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& config, bool fast, const std::string& targetName, const std::string& config, bool fast,
int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions)
......
...@@ -46,7 +46,7 @@ public: ...@@ -46,7 +46,7 @@ public:
bool AllowDeleteOnError() const override { return false; } bool AllowDeleteOnError() const override { return false; }
protected: protected:
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -1751,14 +1751,13 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, ...@@ -1751,14 +1751,13 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir,
} }
void cmGlobalGenerator::GenerateBuildCommand( void cmGlobalGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& /*unused*/, GeneratedMakeCommand& makeCommand, const std::string& /*unused*/,
const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/,
const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/,
bool /*unused*/, int /*unused*/, bool /*unused*/, bool /*unused*/, int /*unused*/, bool /*unused*/,
std::vector<std::string> const& /*unused*/) std::vector<std::string> const& /*unused*/)
{ {
makeCommand.emplace_back( makeCommand.add("cmGlobalGenerator::GenerateBuildCommand not implemented");
"cmGlobalGenerator::GenerateBuildCommand not implemented");
} }
void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/,
...@@ -1802,31 +1801,29 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, ...@@ -1802,31 +1801,29 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/,
std::string outputBuffer; std::string outputBuffer;
std::string* outputPtr = &outputBuffer; std::string* outputPtr = &outputBuffer;
std::vector<std::string> makeCommand; GeneratedMakeCommand makeCommand;
this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir, this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir,
target, config, fast, jobs, verbose, target, config, fast, jobs, verbose,
nativeOptions); nativeOptions);
// Workaround to convince VCExpress.exe to produce output. // Workaround to convince some commands to produce output.
if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
!makeCommand.empty() && makeCommand.RequiresOutputForward) {
cmSystemTools::LowerCase(
cmSystemTools::GetFilenameName(makeCommand[0])) == "vcexpress.exe") {
outputflag = cmSystemTools::OUTPUT_FORWARD; outputflag = cmSystemTools::OUTPUT_FORWARD;
} }
// should we do a clean first? // should we do a clean first?
if (clean) { if (clean) {
std::vector<std::string> cleanCommand; GeneratedMakeCommand cleanCommand;
this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName,
bindir, "clean", config, fast, jobs, verbose); bindir, "clean", config, fast, jobs, verbose);
output += "\nRun Clean Command:"; output += "\nRun Clean Command:";
output += cmSystemTools::PrintSingleCommand(cleanCommand); output += cleanCommand.printable();
output += "\n"; output += "\n";
if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr, outputPtr, if (!cmSystemTools::RunSingleCommand(cleanCommand.PrimaryCommand,
&retVal, nullptr, outputflag, outputPtr, outputPtr, &retVal,
timeout)) { nullptr, outputflag, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed."); cmSystemTools::Error("Generator: execution of make clean failed.");
output += *outputPtr; output += *outputPtr;
...@@ -1838,13 +1835,13 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, ...@@ -1838,13 +1835,13 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/,
} }
// now build // now build
std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand); std::string makeCommandStr = makeCommand.printable();
output += "\nRun Build Command:"; output += "\nRun Build Command(s):";
output += makeCommandStr; output += makeCommandStr;
output += "\n"; output += "\n";
if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr, outputPtr, if (!cmSystemTools::RunSingleCommand(makeCommand.PrimaryCommand, outputPtr,
&retVal, nullptr, outputflag, outputPtr, &retVal, nullptr, outputflag,
timeout)) { timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole); cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error( cmSystemTools::Error(
......
...@@ -41,6 +41,54 @@ class cmSourceFile; ...@@ -41,6 +41,54 @@ class cmSourceFile;
class cmStateDirectory; class cmStateDirectory;
class cmake; class cmake;
namespace detail {
inline void AppendStrs(std::vector<std::string>&)
{
}
template <typename T, typename... Ts>
inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts)
{
command.emplace_back(std::forward<T>(s));
AppendStrs(command, std::forward<Ts>(ts)...);
}
struct GeneratedMakeCommand
{
// Add each argument as a separate element to the vector
template <typename... T>
void add(T&&... args)
{
// iterate the args and append each one
AppendStrs(PrimaryCommand, std::forward<T>(args)...);
}
// Add each value in the iterators as a separate element to the vector
void add(std::vector<std::string>::const_iterator start,
std::vector<std::string>::const_iterator end)
{
PrimaryCommand.insert(PrimaryCommand.end(), start, end);
}
std::string printable() const
{
std::size_t size = PrimaryCommand.size();
for (auto&& i : PrimaryCommand) {
size += i.size();
}
std::string buffer;
buffer.reserve(size);
for (auto&& i : PrimaryCommand) {
buffer.append(i);
buffer.append(1, ' ');
}
return buffer;
}
std::vector<std::string> PrimaryCommand;
bool RequiresOutputForward = false;
};
}
/** \class cmGlobalGenerator /** \class cmGlobalGenerator
* \brief Responsible for overseeing the generation process for the entire tree * \brief Responsible for overseeing the generation process for the entire tree
* *
...@@ -182,8 +230,12 @@ public: ...@@ -182,8 +230,12 @@ public:
virtual bool Open(const std::string& bindir, const std::string& projectName, virtual bool Open(const std::string& bindir, const std::string& projectName,
bool dryRun); bool dryRun);
struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand
{
};
virtual void GenerateBuildCommand( virtual void GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir, const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& config, bool fast, const std::string& targetName, const std::string& config, bool fast,
int jobs, bool verbose, int jobs, bool verbose,
......
...@@ -370,25 +370,23 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject( ...@@ -370,25 +370,23 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
} }
void cmGlobalGhsMultiGenerator::GenerateBuildCommand( void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir, const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& /*config*/, bool /*fast*/, const std::string& targetName, const std::string& /*config*/, bool /*fast*/,
int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions)
{ {
const char* gbuild = const char* gbuild =
this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM"); this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
makeCommand.push_back( makeCommand.add(this->SelectMakeProgram(makeProgram, (std::string)gbuild));
this->SelectMakeProgram(makeProgram, (std::string)gbuild));
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
makeCommand.push_back("-parallel"); makeCommand.add("-parallel");
if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
makeCommand.push_back(std::to_string(jobs)); makeCommand.add(std::to_string(jobs));
} }
} }
makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeCommand.add(makeOptions.begin(), makeOptions.end());
makeOptions.end());
/* determine which top-project file to use */ /* determine which top-project file to use */
std::string proj = projectName + ".top" + FILE_EXTENSION; std::string proj = projectName + ".top" + FILE_EXTENSION;
...@@ -401,16 +399,15 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand( ...@@ -401,16 +399,15 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
} }
} }
makeCommand.push_back("-top"); makeCommand.add("-top", proj);
makeCommand.push_back(proj);
if (!targetName.empty()) { if (!targetName.empty()) {
if (targetName == "clean") { if (targetName == "clean") {
makeCommand.push_back("-clean"); makeCommand.add("-clean");
} else { } else {
if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) { if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) {
makeCommand.push_back(targetName); makeCommand.add(targetName);
} else { } else {
makeCommand.push_back(targetName + ".gpj"); makeCommand.add(targetName + ".gpj");
} }
} }
} }
......
...@@ -88,7 +88,7 @@ public: ...@@ -88,7 +88,7 @@ public:
protected: protected:
void Generate() override; void Generate() override;
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -55,7 +55,7 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice( ...@@ -55,7 +55,7 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(
} }
void cmGlobalJOMMakefileGenerator::GenerateBuildCommand( void cmGlobalJOMMakefileGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir, const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& config, bool fast, const std::string& targetName, const std::string& config, bool fast,
int jobs, bool verbose, std::vector<std::string> const& makeOptions) int jobs, bool verbose, std::vector<std::string> const& makeOptions)
......
...@@ -40,7 +40,7 @@ public: ...@@ -40,7 +40,7 @@ public:
bool optional) override; bool optional) override;
protected: protected:
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -55,7 +55,7 @@ void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice( ...@@ -55,7 +55,7 @@ void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(
} }
void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir, const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& config, bool fast, const std::string& targetName, const std::string& config, bool fast,
int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions)
......
...@@ -45,7 +45,7 @@ public: ...@@ -45,7 +45,7 @@ public:
bool optional) override; bool optional) override;
protected: protected:
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -673,31 +673,28 @@ void cmGlobalNinjaGenerator::EnableLanguage( ...@@ -673,31 +673,28 @@ void cmGlobalNinjaGenerator::EnableLanguage(
// Called by: // Called by:
// cmGlobalGenerator::Build() // cmGlobalGenerator::Build()
void cmGlobalNinjaGenerator::GenerateBuildCommand( void cmGlobalNinjaGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& /*projectName*/, const std::string& /*projectDir*/,
const std::string& targetName, const std::string& /*config*/, bool /*fast*/, const std::string& targetName, const std::string& /*config*/, bool /*fast*/,
int jobs, bool verbose, std::vector<std::string> const& makeOptions) int jobs, bool verbose, std::vector<std::string> const& makeOptions)
{ {
makeCommand.push_back(this->SelectMakeProgram(makeProgram)); makeCommand.add(this->SelectMakeProgram(makeProgram));
if (verbose) { if (verbose) {
makeCommand.emplace_back("-v"); makeCommand.add("-v");
} }
if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) && if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) &&
(jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) { (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) {
makeCommand.emplace_back("-j"); makeCommand.add("-j", std::to_string(jobs));
makeCommand.push_back(std::to_string(jobs));
} }
makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeCommand.add(makeOptions.begin(), makeOptions.end());
makeOptions.end());
if (!targetName.empty()) { if (!targetName.empty()) {
if (targetName == "clean") { if (targetName == "clean") {
makeCommand.emplace_back("-t"); makeCommand.add("-t", "clean");
makeCommand.emplace_back("clean");
} else { } else {
makeCommand.push_back(targetName); makeCommand.add(targetName);
} }
} }
} }
......
...@@ -202,7 +202,7 @@ public: ...@@ -202,7 +202,7 @@ public:
void EnableLanguage(std::vector<std::string> const& languages, void EnableLanguage(std::vector<std::string> const& languages,
cmMakefile* mf, bool optional) override; cmMakefile* mf, bool optional) override;
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -490,7 +490,7 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( ...@@ -490,7 +490,7 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
} }
void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& /*projectName*/, const std::string& /*projectDir*/,
const std::string& targetName, const std::string& /*config*/, bool fast, const std::string& targetName, const std::string& /*config*/, bool fast,
int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions)
...@@ -510,17 +510,16 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( ...@@ -510,17 +510,16 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
mf = mfu.get(); mf = mfu.get();
} }
makeCommand.push_back(this->SelectMakeProgram(makeProgram)); makeCommand.add(this->SelectMakeProgram(makeProgram));
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
makeCommand.emplace_back("-j"); makeCommand.add("-j");
if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
makeCommand.push_back(std::to_string(jobs)); makeCommand.add(std::to_string(jobs));
} }
} }
makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeCommand.add(makeOptions.begin(), makeOptions.end());
makeOptions.end());
if (!targetName.empty()) { if (!targetName.empty()) {
std::string tname = targetName; std::string tname = targetName;
if (fast) { if (fast) {
...@@ -530,7 +529,7 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( ...@@ -530,7 +529,7 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
tname = tname =
conv.ConvertToRelativePath(mf->GetState()->GetBinaryDirectory(), tname); conv.ConvertToRelativePath(mf->GetState()->GetBinaryDirectory(), tname);
cmSystemTools::ConvertToOutputSlashes(tname); cmSystemTools::ConvertToOutputSlashes(tname);
makeCommand.push_back(std::move(tname)); makeCommand.add(std::move(tname));
} }
} }
......
...@@ -127,7 +127,7 @@ public: ...@@ -127,7 +127,7 @@ public:
std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; } std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
// change the build command for speed // change the build command for speed
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -864,7 +864,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf) ...@@ -864,7 +864,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
} }
void cmGlobalVisualStudio10Generator::GenerateBuildCommand( void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& projectDir, const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& config, bool fast, const std::string& targetName, const std::string& config, bool fast,
int jobs, bool verbose, std::vector<std::string> const& makeOptions) int jobs, bool verbose, std::vector<std::string> const& makeOptions)
...@@ -879,6 +879,10 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( ...@@ -879,6 +879,10 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
bool useDevEnv = (makeProgramLower.find("devenv") != std::string::npos || bool useDevEnv = (makeProgramLower.find("devenv") != std::string::npos ||
makeProgramLower.find("vcexpress") != std::string::npos); makeProgramLower.find("vcexpress") != std::string::npos);
// Workaround to convince VCExpress.exe to produce output.
makeCommand.RequiresOutputForward =
(makeProgramLower.find("vcexpress") != std::string::npos);
// MSBuild is preferred (and required for VS Express), but if the .sln has // MSBuild is preferred (and required for VS Express), but if the .sln has
// an Intel Fortran .vfproj then we have to use devenv. Parse it to find out. // an Intel Fortran .vfproj then we have to use devenv. Parse it to find out.
cmSlnData slnData; cmSlnData slnData;
...@@ -912,7 +916,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( ...@@ -912,7 +916,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
return; return;
} }
makeCommand.push_back(makeProgramSelected); makeCommand.add(makeProgramSelected);
std::string realTarget = targetName; std::string realTarget = targetName;
// msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD
...@@ -921,8 +925,8 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( ...@@ -921,8 +925,8 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
realTarget = "ALL_BUILD"; realTarget = "ALL_BUILD";
} }
if (realTarget == "clean") { if (realTarget == "clean") {
makeCommand.push_back(std::string(projectName) + ".sln"); makeCommand.add(std::string(projectName) + ".sln");
makeCommand.push_back("/t:Clean"); makeCommand.add("/t:Clean");
} else { } else {
std::string targetProject(realTarget); std::string targetProject(realTarget);
targetProject += ".vcxproj"; targetProject += ".vcxproj";
...@@ -934,7 +938,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( ...@@ -934,7 +938,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
cmSystemTools::ConvertToUnixSlashes(targetProject); cmSystemTools::ConvertToUnixSlashes(targetProject);
} }
} }
makeCommand.push_back(targetProject); makeCommand.add(std::move(targetProject));
} }
std::string configArg = "/p:Configuration="; std::string configArg = "/p:Configuration=";
if (!config.empty()) { if (!config.empty()) {
...@@ -942,23 +946,22 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( ...@@ -942,23 +946,22 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
} else { } else {
configArg += "Debug"; configArg += "Debug";
} }
makeCommand.push_back(configArg); makeCommand.add(configArg);
makeCommand.push_back("/p:Platform=" + this->GetPlatformName()); makeCommand.add(std::string("/p:Platform=") + this->GetPlatformName());
makeCommand.push_back(std::string("/p:VisualStudioVersion=") + makeCommand.add(std::string("/p:VisualStudioVersion=") +
this->GetIDEVersion()); this->GetIDEVersion());
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
makeCommand.push_back("/m"); makeCommand.add("/m");
} else { } else {
makeCommand.push_back(std::string("/m:") + std::to_string(jobs)); makeCommand.add(std::string("/m:") + std::to_string(jobs));
} }
// Having msbuild.exe and cl.exe using multiple jobs is discouraged // Having msbuild.exe and cl.exe using multiple jobs is discouraged
makeCommand.push_back("/p:CL_MPCount=1"); makeCommand.add("/p:CL_MPCount=1");
} }
makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeCommand.add(makeOptions.begin(), makeOptions.end());
makeOptions.end());
} }
bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf) bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)
......
...@@ -22,7 +22,7 @@ public: ...@@ -22,7 +22,7 @@ public:
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override; bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override; bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
void GenerateBuildCommand(std::vector<std::string>& makeCommand, void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
const std::string& makeProgram, const std::string& makeProgram,
const std::string& projectName, const std::string& projectName,
const std::string& projectDir, const std::string& projectDir,
......
...@@ -191,7 +191,7 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType( ...@@ -191,7 +191,7 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
} }
void cmGlobalVisualStudio7Generator::GenerateBuildCommand( void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram, GeneratedMakeCommand& makeCommand, const std::string& makeProgram,
const std::string& projectName, const std::string& /*projectDir*/, const std::string& projectName, const std::string& /*projectDir*/,
const std::string& targetName, const std::string& config, bool /*fast*/, const std::string& targetName, const std::string& config, bool /*fast*/,
int /*jobs*/, bool /*verbose*/, std::vector<std::string> const& makeOptions) int /*jobs*/, bool /*verbose*/, std::vector<std::string> const& makeOptions)
...@@ -209,35 +209,25 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand( ...@@ -209,35 +209,25 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
makeProgramSelected = this->GetDevEnvCommand(); makeProgramSelected = this->GetDevEnvCommand();
} }
makeCommand.push_back(makeProgramSelected); // Workaround to convince VCExpress.exe to produce output.
makeCommand.RequiresOutputForward =
(makeProgramLower.find("vcexpress") != std::string::npos);
makeCommand.push_back(std::string(projectName) + ".sln"); makeCommand.add(makeProgramSelected);
makeCommand.add(std::string(projectName) + ".sln");
std::string realTarget = targetName; std::string realTarget = targetName;
bool clean = false; bool clean = false;
if (realTarget == "clean") { if (realTarget == "clean") {
clean = true; clean = true;
realTarget = "ALL_BUILD"; realTarget = "ALL_BUILD";
} }
if (clean) {
makeCommand.push_back("/clean");
} else {
makeCommand.push_back("/build");
}
if (!config.empty()) {
makeCommand.push_back(config);
} else {
makeCommand.push_back("Debug");
}
makeCommand.push_back("/project");
if (!realTarget.empty()) { makeCommand.add((clean ? "/clean" : "/build"));
makeCommand.push_back(realTarget); makeCommand.add((config.empty() ? "Debug" : config));