|
|
@@ -3,12 +3,15 @@
|
|
|
#include "cmTryRunCommand.h"
|
|
|
|
|
|
#include <cstdio>
|
|
|
+#include <stdexcept>
|
|
|
|
|
|
#include <cm/optional>
|
|
|
+#include <cmext/string_view>
|
|
|
|
|
|
#include "cmsys/FStream.hxx"
|
|
|
|
|
|
#include "cmArgumentParserTypes.h"
|
|
|
+#include "cmConfigureLog.h"
|
|
|
#include "cmCoreTryCompile.h"
|
|
|
#include "cmDuration.h"
|
|
|
#include "cmExecutionStatus.h"
|
|
|
@@ -23,6 +26,44 @@
|
|
|
#include "cmake.h"
|
|
|
|
|
|
namespace {
|
|
|
+struct cmTryRunResult
|
|
|
+{
|
|
|
+ bool VariableCached = true;
|
|
|
+ std::string Variable;
|
|
|
+ cm::optional<std::string> Stdout;
|
|
|
+ cm::optional<std::string> Stderr;
|
|
|
+ cm::optional<std::string> ExitCode;
|
|
|
+};
|
|
|
+
|
|
|
+#ifndef CMAKE_BOOTSTRAP
|
|
|
+void WriteTryRunEvent(cmConfigureLog& log, cmMakefile const& mf,
|
|
|
+ cmTryCompileResult const& compileResult,
|
|
|
+ cmTryRunResult const& runResult)
|
|
|
+{
|
|
|
+ log.BeginEvent("try_run");
|
|
|
+ log.WriteBacktrace(mf);
|
|
|
+ cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult);
|
|
|
+
|
|
|
+ log.BeginObject("runResult"_s);
|
|
|
+ log.WriteValue("variable"_s, runResult.Variable);
|
|
|
+ log.WriteValue("cached"_s, runResult.VariableCached);
|
|
|
+ if (runResult.Stdout) {
|
|
|
+ log.WriteLiteralTextBlock("stdout"_s, *runResult.Stdout);
|
|
|
+ }
|
|
|
+ if (runResult.Stderr) {
|
|
|
+ log.WriteLiteralTextBlock("stderr"_s, *runResult.Stderr);
|
|
|
+ }
|
|
|
+ if (runResult.ExitCode) {
|
|
|
+ try {
|
|
|
+ log.WriteValue("exitCode"_s, std::stoi(*runResult.ExitCode));
|
|
|
+ } catch (std::invalid_argument const&) {
|
|
|
+ log.WriteValue("exitCode"_s, *runResult.ExitCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log.EndObject();
|
|
|
+ log.EndEvent();
|
|
|
+}
|
|
|
+#endif
|
|
|
|
|
|
class TryRunCommandImpl : public cmCoreTryCompile
|
|
|
{
|
|
|
@@ -96,24 +137,33 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
|
|
|
}
|
|
|
|
|
|
bool captureRunOutput = false;
|
|
|
- bool captureRunOutputStdOut = false;
|
|
|
- bool captureRunOutputStdErr = false;
|
|
|
if (arguments.OutputVariable) {
|
|
|
captureRunOutput = true;
|
|
|
} else if (arguments.CompileOutputVariable) {
|
|
|
arguments.OutputVariable = arguments.CompileOutputVariable;
|
|
|
}
|
|
|
- if (arguments.RunOutputStdOutVariable || arguments.RunOutputStdErrVariable) {
|
|
|
- captureRunOutputStdOut = arguments.RunOutputStdOutVariable.has_value();
|
|
|
- captureRunOutputStdErr = arguments.RunOutputStdErrVariable.has_value();
|
|
|
- } else if (arguments.RunOutputVariable) {
|
|
|
- captureRunOutput = true;
|
|
|
+
|
|
|
+ // Capture the split output for the configure log unless the caller
|
|
|
+ // requests combined output to be captured by a variable.
|
|
|
+ bool captureRunOutputStdOutErr = true;
|
|
|
+ if (!arguments.RunOutputStdOutVariable &&
|
|
|
+ !arguments.RunOutputStdErrVariable) {
|
|
|
+ if (arguments.RunOutputVariable) {
|
|
|
+ captureRunOutput = true;
|
|
|
+ captureRunOutputStdOutErr = false;
|
|
|
+ } else if (arguments.OutputVariable) {
|
|
|
+ captureRunOutputStdOutErr = false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// do the try compile
|
|
|
cm::optional<cmTryCompileResult> compileResult =
|
|
|
this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE);
|
|
|
|
|
|
+ cmTryRunResult runResult;
|
|
|
+ runResult.Variable = this->RunResultVariable;
|
|
|
+ runResult.VariableCached = !arguments.NoCache;
|
|
|
+
|
|
|
// now try running the command if it compiled
|
|
|
if (compileResult && compileResult->ExitCode == 0) {
|
|
|
if (this->OutputFile.empty()) {
|
|
|
@@ -134,14 +184,26 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
|
|
|
runArgs, *arguments.SourceDirectoryOrFile,
|
|
|
*arguments.CompileResultVariable,
|
|
|
captureRunOutput ? &runOutputContents : nullptr,
|
|
|
- captureRunOutputStdOut ? &runOutputStdOutContents : nullptr,
|
|
|
- captureRunOutputStdErr ? &runOutputStdErrContents : nullptr);
|
|
|
+ captureRunOutputStdOutErr ? &runOutputStdOutContents : nullptr,
|
|
|
+ captureRunOutputStdOutErr ? &runOutputStdErrContents : nullptr);
|
|
|
} else {
|
|
|
this->RunExecutable(
|
|
|
runArgs, arguments.RunWorkingDirectory,
|
|
|
captureRunOutput ? &runOutputContents : nullptr,
|
|
|
- captureRunOutputStdOut ? &runOutputStdOutContents : nullptr,
|
|
|
- captureRunOutputStdErr ? &runOutputStdErrContents : nullptr);
|
|
|
+ captureRunOutputStdOutErr ? &runOutputStdOutContents : nullptr,
|
|
|
+ captureRunOutputStdOutErr ? &runOutputStdErrContents : nullptr);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (captureRunOutputStdOutErr) {
|
|
|
+ runResult.Stdout = runOutputStdOutContents;
|
|
|
+ runResult.Stderr = runOutputStdErrContents;
|
|
|
+ } else {
|
|
|
+ runResult.Stdout = runOutputContents;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cmValue ec =
|
|
|
+ this->Makefile->GetDefinition(this->RunResultVariable)) {
|
|
|
+ runResult.ExitCode = *ec;
|
|
|
}
|
|
|
|
|
|
// now put the output into the variables
|
|
|
@@ -172,6 +234,15 @@ bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#ifndef CMAKE_BOOTSTRAP
|
|
|
+ if (compileResult) {
|
|
|
+ cmMakefile const& mf = *(this->Makefile);
|
|
|
+ if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) {
|
|
|
+ WriteTryRunEvent(*log, mf, *compileResult, runResult);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
// if we created a directory etc, then cleanup after ourselves
|
|
|
if (!this->Makefile->GetCMakeInstance()->GetDebugTryCompile()) {
|
|
|
this->CleanupFiles(this->BinaryDirectory);
|