cmGlobalGenerator: use a stream for output in Build

This allows output to show up in output immediately instead of being
batched.
This commit is contained in:
Ben Boeckel 2023-05-26 14:30:18 -04:00
parent e060666531
commit 8451a3f0b5
5 changed files with 38 additions and 35 deletions

View File

@ -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) {

View File

@ -2076,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>
@ -2103,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)
@ -2114,13 +2117,13 @@ int cmGlobalGenerator::Build(
* Run an executable command and put the stdout in output.
*/
cmWorkingDirectory workdir(bindir);
output += cmStrCat("Change Dir: '", bindir, "'\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 += cmStrCat(err, '\n');
ostr << err << std::endl;
return 1;
}
std::string realConfig = config;
@ -2149,8 +2152,8 @@ int cmGlobalGenerator::Build(
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
{ "clean" }, realConfig, jobs, verbose,
buildOptions);
output += cmStrCat(
"\nRun Clean Command: ", cleanCommand.front().QuotedPrintable(), '\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 "
@ -2163,18 +2166,21 @@ int cmGlobalGenerator::Build(
nullptr, outputflag, timeout)) {
cmSystemTools::SetRunCommandHideConsole(hideconsole);
cmSystemTools::Error("Generator: execution of make clean failed.");
output +=
cmStrCat(*outputPtr, "\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;
std::string outputMakeCommandStr;
output += "\nRun Build Command(s): ";
bool isWatcomWMake = this->CMakeInstance->GetState()->UseWatcomWMake();
bool needBuildOutput = isWatcomWMake;
std::string buildOutput;
ostr << "\nRun Build Command(s): ";
retVal = 0;
for (auto command = makeCommand.begin();
@ -2186,7 +2192,7 @@ int cmGlobalGenerator::Build(
outputMakeCommandStr += " && ";
}
output += outputMakeCommandStr;
ostr << outputMakeCommandStr << std::endl;
if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr,
outputPtr, &retVal, nullptr,
outputflag, timeout)) {
@ -2194,22 +2200,24 @@ int cmGlobalGenerator::Build(
cmSystemTools::Error(
"Generator: execution of make failed. Make command was: " +
makeCommandStr);
output +=
cmStrCat(*outputPtr,
"\nGenerator: execution of make failed. Make command was: ",
outputMakeCommandStr, '\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;
}

View File

@ -234,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,

View File

@ -3625,7 +3625,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");
@ -3699,18 +3698,16 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
}
this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs);
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, output, "", config, buildOptions,
jobs, "", dir, projName, targets, verbose_ostr, "", config, buildOptions,
verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH,
nativeOptions);
if (verbose) {
// `cmGlobalGenerator::Build` logs metadata about what directory and
// commands are being executed to the `output` parameter. If CMake is
// verbose, print this out.
std::cout << output;
}
return buildresult;
}

View File

@ -1 +1 @@
^ninja: no work to do
ninja: no work to do