summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-05-31 13:33:07 (GMT)
committerKitware Robot <kwrobot@kitware.com>2023-05-31 13:33:26 (GMT)
commit5b063510f9a60bb775e9554866fce7edc286fb3c (patch)
tree6478002771d02d160db7a2da207d7b2cc5b3b7a0
parent3332fdab9daefe0cc1de8cf50dc8cd78dfe221b0 (diff)
parent8451a3f0b545347a812288e66d757692c770097d (diff)
downloadCMake-5b063510f9a60bb775e9554866fce7edc286fb3c.zip
CMake-5b063510f9a60bb775e9554866fce7edc286fb3c.tar.gz
CMake-5b063510f9a60bb775e9554866fce7edc286fb3c.tar.bz2
Merge topic 'cmake-verbose-print-build-tool-command'
8451a3f0b5 cmGlobalGenerator: use a stream for output in `Build` e060666531 cmake: write the build command itself with `--verbose` b017c9f127 cmGlobalGenerator: fix off-by-one for `&&` command joining c715fd8d76 cmGlobalGenerator: quote commands in `::Build` output d6c0e827bc cmGlobalGenerator: add a `QuotedPrintable` method for commands 28ee3bef34 cmGlobalGenerator: add missing spaces in output 465ab8d872 cmGlobalGenerator: use `cmStrCat` in `::Build` 81d45dabc4 cmOutputConverter: add a `static` version of `EscapeForShell` Acked-by: Kitware Robot <kwrobot@kitware.com> Tested-by: buildbot <buildbot@kitware.com> Acked-by: Alex <leha-bot@yandex.ru> Merge-request: !8183
-rw-r--r--Help/release/dev/cmake-verbose-print-build-tool-command.rst5
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx4
-rw-r--r--Source/cmGlobalGenerator.cxx76
-rw-r--r--Source/cmGlobalGenerator.h3
-rw-r--r--Source/cmOutputConverter.cxx15
-rw-r--r--Source/cmOutputConverter.h1
-rw-r--r--Source/cmake.cxx12
-rw-r--r--Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt2
8 files changed, 80 insertions, 38 deletions
diff --git a/Help/release/dev/cmake-verbose-print-build-tool-command.rst b/Help/release/dev/cmake-verbose-print-build-tool-command.rst
new file mode 100644
index 0000000..4f13231
--- /dev/null
+++ b/Help/release/dev/cmake-verbose-print-build-tool-command.rst
@@ -0,0 +1,5 @@
+cmake-verbose-print-build-tool-command
+--------------------------------------
+
+* ``cmake --build $dir --verbose`` will now print the working directory and
+ command line used to perform the build.
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index cece98e..5feb953 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -246,7 +246,6 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
return 1;
}
}
- std::string output;
const char* config = nullptr;
if (!this->CTest->GetConfigType().empty()) {
config = this->CTest->GetConfigType().c_str();
@@ -259,9 +258,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
PackageResolveMode::Disable);
int retVal = cm.GetGlobalGenerator()->Build(
cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir,
- this->BuildProject, { tar }, output, this->BuildMakeProgram, config,
+ this->BuildProject, { tar }, out, this->BuildMakeProgram, config,
buildOptions, false, remainingTime);
- out << output;
// if the build failed then return
if (retVal) {
if (outstring) {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 22d5aeb..7e6b16a 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -47,6 +47,7 @@
#include "cmMSVC60LinkLineComputer.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmSourceFile.h"
@@ -73,6 +74,23 @@ const std::string kCMAKE_PLATFORM_INFO_INITIALIZED =
class cmInstalledFile;
+namespace detail {
+std::string GeneratedMakeCommand::QuotedPrintable() const
+{
+ std::string output;
+ const char* sep = "";
+ int flags = 0;
+#if !defined(_WIN32)
+ flags |= cmOutputConverter::Shell_Flag_IsUnix;
+#endif
+ for (auto const& arg : this->PrimaryCommand) {
+ output += cmStrCat(sep, cmOutputConverter::EscapeForShell(arg, flags));
+ sep = " ";
+ }
+ return output;
+}
+}
+
bool cmTarget::StrictTargetComparison::operator()(cmTarget const* t1,
cmTarget const* t2) const
{
@@ -2058,9 +2076,12 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir,
mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
cmBuildOptions defaultBuildOptions(false, fast, PackageResolveMode::Disable);
- return this->Build(jobs, srcdir, bindir, projectName, newTarget, output, "",
- config, defaultBuildOptions, true,
- this->TryCompileTimeout);
+ std::stringstream ostr;
+ auto ret =
+ this->Build(jobs, srcdir, bindir, projectName, newTarget, ostr, "", config,
+ defaultBuildOptions, true, this->TryCompileTimeout);
+ output = ostr.str();
+ return ret;
}
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
@@ -2085,7 +2106,7 @@ void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/,
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,
+ std::ostream& ostr, const std::string& makeCommandCSTR,
const std::string& config, const cmBuildOptions& buildOptions, bool verbose,
cmDuration timeout, cmSystemTools::OutputOption outputflag,
std::vector<std::string> const& nativeOptions)
@@ -2096,16 +2117,13 @@ int cmGlobalGenerator::Build(
* Run an executable command and put the stdout in output.
*/
cmWorkingDirectory workdir(bindir);
- output += "Change Dir: ";
- output += bindir;
- output += "\n";
+ ostr << "Change Dir: '" << bindir << '\'' << std::endl;
if (workdir.Failed()) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
std::string err = cmStrCat("Failed to change directory: ",
std::strerror(workdir.GetLastResult()));
cmSystemTools::Error(err);
- output += err;
- output += "\n";
+ ostr << err << std::endl;
return 1;
}
std::string realConfig = config;
@@ -2134,9 +2152,8 @@ int cmGlobalGenerator::Build(
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
{ "clean" }, realConfig, jobs, verbose,
buildOptions);
- output += "\nRun Clean Command:";
- output += cleanCommand.front().Printable();
- output += "\n";
+ ostr << "\nRun Clean Command: " << cleanCommand.front().QuotedPrintable()
+ << std::endl;
if (cleanCommand.size() != 1) {
this->GetCMakeInstance()->IssueMessage(MessageType::INTERNAL_ERROR,
"The generator did not produce "
@@ -2149,27 +2166,33 @@ int cmGlobalGenerator::Build(
nullptr, outputflag, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed.");
- output += *outputPtr;
- output += "\nGenerator: execution of make clean failed.\n";
+ ostr << *outputPtr << "\nGenerator: execution of make clean failed."
+ << std::endl;
return 1;
}
- output += *outputPtr;
+ ostr << *outputPtr;
}
// now build
std::string makeCommandStr;
- output += "\nRun Build Command(s):";
+ std::string outputMakeCommandStr;
+ bool isWatcomWMake = this->CMakeInstance->GetState()->UseWatcomWMake();
+ bool needBuildOutput = isWatcomWMake;
+ std::string buildOutput;
+ ostr << "\nRun Build Command(s): ";
retVal = 0;
for (auto command = makeCommand.begin();
command != makeCommand.end() && retVal == 0; ++command) {
makeCommandStr = command->Printable();
- if (command != makeCommand.end()) {
+ outputMakeCommandStr = command->QuotedPrintable();
+ if ((command + 1) != makeCommand.end()) {
makeCommandStr += " && ";
+ outputMakeCommandStr += " && ";
}
- output += makeCommandStr;
+ ostr << outputMakeCommandStr << std::endl;
if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr,
outputPtr, &retVal, nullptr,
outputflag, timeout)) {
@@ -2177,21 +2200,24 @@ int cmGlobalGenerator::Build(
cmSystemTools::Error(
"Generator: execution of make failed. Make command was: " +
makeCommandStr);
- output += *outputPtr;
- output += "\nGenerator: execution of make failed. Make command was: " +
- makeCommandStr + "\n";
+ ostr << *outputPtr
+ << "\nGenerator: execution of make failed. Make command was: "
+ << outputMakeCommandStr << std::endl;
return 1;
}
- output += *outputPtr;
+ ostr << *outputPtr << std::flush;
+ if (needBuildOutput) {
+ buildOutput += *outputPtr;
+ }
}
- output += "\n";
+ ostr << std::endl;
cmSystemTools::SetRunCommandHideConsole(hideconsole);
// The OpenWatcom tools do not return an error code when a link
// library is not found!
- if (this->CMakeInstance->GetState()->UseWatcomWMake() && retVal == 0 &&
- output.find("W1008: cannot open") != std::string::npos) {
+ if (isWatcomWMake && retVal == 0 &&
+ buildOutput.find("W1008: cannot open") != std::string::npos) {
retVal = 1;
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index d657fc8..01afabd 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -85,6 +85,7 @@ struct GeneratedMakeCommand
}
std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); }
+ std::string QuotedPrintable() const;
std::vector<std::string> PrimaryCommand;
bool RequiresOutputForward = false;
@@ -233,7 +234,7 @@ public:
int Build(
int jobs, const std::string& srcdir, const std::string& bindir,
const std::string& projectName,
- std::vector<std::string> const& targetNames, std::string& output,
+ std::vector<std::string> const& targetNames, std::ostream& ostr,
const std::string& makeProgram, const std::string& config,
const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout,
cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE,
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 53cb21e..02981ae 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -243,11 +243,6 @@ std::string cmOutputConverter::EscapeForShell(cm::string_view str,
bool unescapeNinjaConfiguration,
bool forResponse) const
{
- // Do not escape shell operators.
- if (cmOutputConverterIsShellOperator(str)) {
- return std::string(str);
- }
-
// Compute the flags for the target shell environment.
int flags = 0;
if (this->GetState()->UseWindowsVSIDE()) {
@@ -283,6 +278,16 @@ std::string cmOutputConverter::EscapeForShell(cm::string_view str,
flags |= Shell_Flag_IsUnix;
}
+ return cmOutputConverter::EscapeForShell(str, flags);
+}
+
+std::string cmOutputConverter::EscapeForShell(cm::string_view str, int flags)
+{
+ // Do not escape shell operators.
+ if (cmOutputConverterIsShellOperator(str)) {
+ return std::string(str);
+ }
+
return Shell_GetArgument(str, flags);
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 625d897..0ee7afb 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -107,6 +107,7 @@ public:
bool forEcho = false, bool useWatcomQuote = false,
bool unescapeNinjaConfiguration = false,
bool forResponse = false) const;
+ static std::string EscapeForShell(cm::string_view str, int flags);
enum class WrapQuotes
{
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 0a1e7ab..3792791 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -3732,7 +3732,6 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
return 1;
}
}
- std::string output;
std::string projName;
cmValue cachedProjectName =
this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
@@ -3806,10 +3805,17 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
}
this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs);
- return this->GlobalGenerator->Build(
- jobs, "", dir, projName, targets, output, "", config, buildOptions,
+ std::stringstream ostr;
+ // `cmGlobalGenerator::Build` logs metadata about what directory and commands
+ // are being executed to the `output` parameter. If CMake is verbose, print
+ // this out.
+ std::ostream& verbose_ostr = verbose ? std::cout : ostr;
+ int buildresult = this->GlobalGenerator->Build(
+ jobs, "", dir, projName, targets, verbose_ostr, "", config, buildOptions,
verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH,
nativeOptions);
+
+ return buildresult;
}
bool cmake::Open(const std::string& dir, bool dryRun)
diff --git a/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt b/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt
index 60a9228..40b4527 100644
--- a/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt
+++ b/Tests/RunCMake/Ninja/VerboseBuild-nowork-stdout.txt
@@ -1 +1 @@
-^ninja: no work to do
+ninja: no work to do