From fdda4095a32dcbb9cc0e9b38067652c025447822 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 12 Dec 2022 10:16:54 -0500 Subject: cmCoreTryCompile: Return more semantic information from compile step Update the `TryCompileCode` signature to allow callers to distinguish between administrative failures and a compilation failure. Return results in a structure to which more information can be added later. --- Source/cmCoreTryCompile.cxx | 55 ++++++++++++++++++++++++--------------------- Source/cmCoreTryCompile.h | 9 ++++++-- Source/cmTryRunCommand.cxx | 5 +++-- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index b44111d..e7351b2 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -285,8 +285,8 @@ Arguments cmCoreTryCompile::ParseArgs( return arguments; } -bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, - cmStateEnums::TargetType targetType) +cm::optional cmCoreTryCompile::TryCompileCode( + Arguments& arguments, cmStateEnums::TargetType targetType) { this->OutputFile.clear(); // which signature were we called with ? @@ -302,7 +302,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, arguments.SourceDirectoryOrFile->empty()) { this->Makefile->IssueMessage(MessageType::FATAL_ERROR, "No specified."); - return false; + return cm::nullopt; } sourceDirectory = *arguments.SourceDirectoryOrFile; projectName = *arguments.ProjectName; @@ -322,7 +322,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, if (!arguments.BinaryDirectory || arguments.BinaryDirectory->empty()) { this->Makefile->IssueMessage(MessageType::FATAL_ERROR, "No specified."); - return false; + return cm::nullopt; } if (*arguments.BinaryDirectory == unique_binary_directory) { // leave empty until we're ready to create it, so we don't try to remove @@ -335,7 +335,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, MessageType::FATAL_ERROR, cmStrCat(" is not an absolute path:\n '", *arguments.BinaryDirectory, "'")); - return false; + return cm::nullopt; } this->BinaryDirectory = *arguments.BinaryDirectory; // compute the binary dir when TRY_COMPILE is called with a src file @@ -367,7 +367,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, "IMPORTED LINK_LIBRARIES. Got ", tgt->GetName(), " of type ", cmState::GetTargetTypeName(tgt->GetType()), ".")); - return false; + return cm::nullopt; } if (tgt->IsImported()) { targets.emplace_back(i); @@ -379,28 +379,28 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, if (arguments.CopyFileTo && arguments.CopyFileTo->empty()) { this->Makefile->IssueMessage(MessageType::FATAL_ERROR, "COPY_FILE must be followed by a file path"); - return false; + return cm::nullopt; } if (arguments.CopyFileError && arguments.CopyFileError->empty()) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "COPY_FILE_ERROR must be followed by a variable name"); - return false; + return cm::nullopt; } if (arguments.CopyFileError && !arguments.CopyFileTo) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "COPY_FILE_ERROR may be used only with COPY_FILE"); - return false; + return cm::nullopt; } if (arguments.Sources && arguments.Sources->empty()) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "SOURCES must be followed by at least one source file"); - return false; + return cm::nullopt; } if (this->SrcFileSignature) { @@ -409,19 +409,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "SOURCE_FROM_CONTENT requires exactly two arguments"); - return false; + return cm::nullopt; } if (arguments.SourceFromVar && arguments.SourceFromVar->size() % 2) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "SOURCE_FROM_VAR requires exactly two arguments"); - return false; + return cm::nullopt; } if (arguments.SourceFromFile && arguments.SourceFromFile->size() % 2) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "SOURCE_FROM_FILE requires exactly two arguments"); - return false; + return cm::nullopt; } } else { // only valid for srcfile signatures @@ -430,19 +430,19 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, MessageType::FATAL_ERROR, cmStrCat(arguments.LangProps.begin()->first, " allowed only in source file signature")); - return false; + return cm::nullopt; } if (!arguments.CompileDefs.empty()) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "COMPILE_DEFINITIONS allowed only in source file signature"); - return false; + return cm::nullopt; } if (arguments.CopyFileTo) { this->Makefile->IssueMessage( MessageType::FATAL_ERROR, "COPY_FILE allowed only in source file signature"); - return false; + return cm::nullopt; } } @@ -462,7 +462,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, e << "Attempt at a recursive or nested TRY_COMPILE in directory\n" << " " << this->BinaryDirectory << "\n"; this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return false; + return cm::nullopt; } std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt"; @@ -486,7 +486,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, const auto& content = (*arguments.SourceFromContent)[i + 1]; auto out = this->WriteSource(name, content, "SOURCE_FROM_CONTENT"); if (out.empty()) { - return false; + return cm::nullopt; } sources.emplace_back(std::move(out)); } @@ -499,7 +499,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, const auto& content = this->Makefile->GetDefinition(var); auto out = this->WriteSource(name, content, "SOURCE_FROM_VAR"); if (out.empty()) { - return false; + return cm::nullopt; } sources.emplace_back(std::move(out)); } @@ -514,7 +514,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, const auto& msg = cmStrCat("SOURCE_FROM_FILE given invalid filename \"", dst, "\""); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg); - return false; + return cm::nullopt; } auto dstPath = cmStrCat(this->BinaryDirectory, "/", dst); @@ -523,7 +523,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, const auto& msg = cmStrCat("SOURCE_FROM_FILE failed to copy \"", src, "\": ", result.GetString()); this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg); - return false; + return cm::nullopt; } sources.emplace_back(std::move(dstPath)); @@ -550,7 +550,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, err << cmJoin(langs, " "); err << "\nSee project() command to enable other languages."; this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err.str()); - return false; + return cm::nullopt; } } @@ -577,7 +577,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, << cmSystemTools::GetLastSystemError(); /* clang-format on */ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); - return false; + return cm::nullopt; } cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH"); @@ -778,7 +778,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, this->Makefile->IssueMessage(MessageType::FATAL_ERROR, "could not write export file."); fclose(fout); - return false; + return cm::nullopt; } fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n", fname.c_str()); @@ -1111,7 +1111,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, } if (!arguments.CopyFileError) { this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str()); - return false; + return cm::nullopt; } copyFileErrorMessage = emsg.str(); } @@ -1122,7 +1122,10 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments, this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage); } } - return res == 0; + + cmTryCompileResult result; + result.ExitCode = res; + return result; } bool cmCoreTryCompile::IsTemporary(std::string const& path) diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h index 3e1e12c..d9649b9 100644 --- a/Source/cmCoreTryCompile.h +++ b/Source/cmCoreTryCompile.h @@ -18,6 +18,11 @@ class cmMakefile; template class cmRange; +struct cmTryCompileResult +{ + int ExitCode = 1; +}; + /** \class cmCoreTryCompile * \brief Base class for cmTryCompileCommand and cmTryRunCommand * @@ -80,8 +85,8 @@ public: * This function requires at least two \p arguments and will crash if given * fewer. */ - bool TryCompileCode(Arguments& arguments, - cmStateEnums::TargetType targetType); + cm::optional TryCompileCode( + Arguments& arguments, cmStateEnums::TargetType targetType); /** * Returns \c true if \p path resides within a CMake temporary directory, diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 1e81195..1b545d5 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -109,10 +109,11 @@ bool TryRunCommandImpl::TryRunCode(std::vector const& argv) } // do the try compile - bool compiled = this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE); + cm::optional compileResult = + this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE); // now try running the command if it compiled - if (compiled) { + if (compileResult && compileResult->ExitCode == 0) { if (this->OutputFile.empty()) { cmSystemTools::Error(this->FindErrorMessage); } else { -- cgit v0.12 From 8d29a0bda616c4c344def2b1db7aaa94b7f27dbb Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 12 Dec 2022 13:05:53 -0500 Subject: cmTryRunCommand: Factor out stdout/stderr capture conditions --- Source/cmTryRunCommand.cxx | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 1b545d5..bbefcd9 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -96,14 +96,16 @@ bool TryRunCommandImpl::TryRunCode(std::vector const& argv) } bool captureRunOutput = false; - bool captureRunOutputStdOutErr = 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) { - captureRunOutputStdOutErr = true; + captureRunOutputStdOut = arguments.RunOutputStdOutVariable.has_value(); + captureRunOutputStdErr = arguments.RunOutputStdErrVariable.has_value(); } else if (arguments.RunOutputVariable) { captureRunOutput = true; } @@ -132,22 +134,14 @@ bool TryRunCommandImpl::TryRunCode(std::vector const& argv) runArgs, *arguments.SourceDirectoryOrFile, *arguments.CompileResultVariable, captureRunOutput ? &runOutputContents : nullptr, - captureRunOutputStdOutErr && arguments.RunOutputStdOutVariable - ? &runOutputStdOutContents - : nullptr, - captureRunOutputStdOutErr && arguments.RunOutputStdErrVariable - ? &runOutputStdErrContents - : nullptr); + captureRunOutputStdOut ? &runOutputStdOutContents : nullptr, + captureRunOutputStdErr ? &runOutputStdErrContents : nullptr); } else { this->RunExecutable( runArgs, arguments.RunWorkingDirectory, captureRunOutput ? &runOutputContents : nullptr, - captureRunOutputStdOutErr && arguments.RunOutputStdOutVariable - ? &runOutputStdOutContents - : nullptr, - captureRunOutputStdOutErr && arguments.RunOutputStdErrVariable - ? &runOutputStdErrContents - : nullptr); + captureRunOutputStdOut ? &runOutputStdOutContents : nullptr, + captureRunOutputStdErr ? &runOutputStdErrContents : nullptr); } // now put the output into the variables -- cgit v0.12 From e8b8d82cbf60e517ad4b9026ba24de1c59165af4 Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Wed, 9 Nov 2022 15:07:45 -0500 Subject: Tests: Generalize RunCMake expectation component names Do not assume all the component names start in "std". Co-authored-by: Brad King --- Tests/RunCMake/RunCMake.cmake | 58 ++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index cc754e8..670beb9 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -33,18 +33,18 @@ function(run_cmake test) set(platform_name msys) endif() - foreach(o IN ITEMS out err) - if(RunCMake-std${o}-file AND EXISTS ${top_src}/${RunCMake-std${o}-file}) - file(READ ${top_src}/${RunCMake-std${o}-file} expect_std${o}) - string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") - elseif(EXISTS ${top_src}/${test}-std${o}-${platform_name}.txt) - file(READ ${top_src}/${test}-std${o}-${platform_name}.txt expect_std${o}) - string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") - elseif(EXISTS ${top_src}/${test}-std${o}.txt) - file(READ ${top_src}/${test}-std${o}.txt expect_std${o}) - string(REGEX REPLACE "\n+$" "" expect_std${o} "${expect_std${o}}") + foreach(o IN ITEMS stdout stderr) + if(RunCMake-${o}-file AND EXISTS ${top_src}/${RunCMake-${o}-file}) + file(READ ${top_src}/${RunCMake-${o}-file} expect_${o}) + string(REGEX REPLACE "\n+$" "" expect_${o} "${expect_${o}}") + elseif(EXISTS ${top_src}/${test}-${o}-${platform_name}.txt) + file(READ ${top_src}/${test}-${o}-${platform_name}.txt expect_${o}) + string(REGEX REPLACE "\n+$" "" expect_${o} "${expect_${o}}") + elseif(EXISTS ${top_src}/${test}-${o}.txt) + file(READ ${top_src}/${test}-${o}.txt expect_${o}) + string(REGEX REPLACE "\n+$" "" expect_${o} "${expect_${o}}") else() - unset(expect_std${o}) + unset(expect_${o}) endif() endforeach() if (NOT expect_stderr) @@ -180,17 +180,13 @@ function(run_cmake test) "|[^\n]*Bullseye Testing Technology" ")[^\n]*\n)+" ) - foreach(o IN ITEMS out err) - string(REGEX REPLACE "\r\n" "\n" actual_std${o} "${actual_std${o}}") - string(REGEX REPLACE "${ignore_line_regex}" "\\1" actual_std${o} "${actual_std${o}}") - string(REGEX REPLACE "\n+$" "" actual_std${o} "${actual_std${o}}") - set(expect_${o} "") - if(DEFINED expect_std${o}) - if(NOT "${actual_std${o}}" MATCHES "${expect_std${o}}") - string(REGEX REPLACE "\n" "\n expect-${o}> " expect_${o} - " expect-${o}> ${expect_std${o}}") - set(expect_${o} "Expected std${o} to match:\n${expect_${o}}\n") - string(APPEND msg "std${o} does not match that expected.\n") + foreach(o IN ITEMS stdout stderr) + string(REGEX REPLACE "\r\n" "\n" actual_${o} "${actual_${o}}") + string(REGEX REPLACE "${ignore_line_regex}" "\\1" actual_${o} "${actual_${o}}") + string(REGEX REPLACE "\n+$" "" actual_${o} "${actual_${o}}") + if(DEFINED expect_${o}) + if(NOT "${actual_${o}}" MATCHES "${expect_${o}}") + string(APPEND msg "${o} does not match that expected.\n") endif() endif() endforeach() @@ -215,15 +211,15 @@ function(run_cmake test) string(APPEND msg "Command was:\n command> ${command}\n") endif() if(msg) - string(REGEX REPLACE "\n" "\n actual-out> " actual_out " actual-out> ${actual_stdout}") - string(REGEX REPLACE "\n" "\n actual-err> " actual_err " actual-err> ${actual_stderr}") - message(SEND_ERROR "${test}${RunCMake_TEST_VARIANT_DESCRIPTION} - FAILED:\n" - "${msg}" - "${expect_out}" - "Actual stdout:\n${actual_out}\n" - "${expect_err}" - "Actual stderr:\n${actual_err}\n" - ) + foreach(o IN ITEMS stdout stderr) + if(DEFINED expect_${o}) + string(REGEX REPLACE "\n" "\n expect-${o}> " expect_${o} " expect-${o}> ${expect_${o}}") + string(APPEND msg "Expected ${o} to match:\n${expect_${o}}\n") + endif() + string(REGEX REPLACE "\n" "\n actual-${o}> " actual_${o} " actual-${o}> ${actual_${o}}") + string(APPEND msg "Actual ${o}:\n${actual_${o}}\n") + endforeach() + message(SEND_ERROR "${test}${RunCMake_TEST_VARIANT_DESCRIPTION} - FAILED:\n${msg}") else() message(STATUS "${test}${RunCMake_TEST_VARIANT_DESCRIPTION} - PASSED") endif() -- cgit v0.12 From 746c776caf1207049922edb3ea63586b94fca4c6 Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Wed, 23 Nov 2022 17:02:22 -0500 Subject: ConfigureLog: Add infrastructure for structured configure event logging Add infrastructure for a "configure log". Use YAML for a balance of machine- and human-readability to records details of configure-time events in a structured format. Teach the RunCMake test framework to support matching the configure log. Issue: #23200 --- Help/index.rst | 1 + Help/manual/cmake-configure-log.7.rst | 102 +++++++++++++++ Help/release/dev/configure-log.rst | 5 + Source/CMakeLists.txt | 2 + Source/cmConfigureLog.cxx | 238 ++++++++++++++++++++++++++++++++++ Source/cmConfigureLog.h | 61 +++++++++ Source/cmake.cxx | 12 ++ Source/cmake.h | 8 ++ Tests/RunCMake/RunCMake.cmake | 18 ++- 9 files changed, 442 insertions(+), 5 deletions(-) create mode 100644 Help/manual/cmake-configure-log.7.rst create mode 100644 Help/release/dev/configure-log.rst create mode 100644 Source/cmConfigureLog.cxx create mode 100644 Source/cmConfigureLog.h diff --git a/Help/index.rst b/Help/index.rst index fdbf847..16c8f25 100644 --- a/Help/index.rst +++ b/Help/index.rst @@ -57,6 +57,7 @@ Reference Manuals /manual/cmake-buildsystem.7 /manual/cmake-commands.7 /manual/cmake-compile-features.7 + /manual/cmake-configure-log.7 /manual/cmake-developer.7 /manual/cmake-env-variables.7 /manual/cmake-file-api.7 diff --git a/Help/manual/cmake-configure-log.7.rst b/Help/manual/cmake-configure-log.7.rst new file mode 100644 index 0000000..3ae7dca --- /dev/null +++ b/Help/manual/cmake-configure-log.7.rst @@ -0,0 +1,102 @@ +.. cmake-manual-description: CMake Configure Log + +cmake-configure-log(7) +********************** + +.. versionadded:: 3.26 + +.. only:: html + + .. contents:: + +Introduction +============ + +CMake writes a running log, known as the configure log, +of certain events that occur during the "configure" step. +The log file is located at:: + + ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeConfigureLog.yaml + +The configure log does *not* contain a log of all output, errors, +or messages printed while configuring a project. It is a log of +detailed information about specific events, such as toolchain inspection +by :command:`try_compile`, meant for use in debugging the configuration +of a build tree. + +Log Structure +============= + +The configure log is designed to be both machine- and human-readable. + +The log file is a YAML document stream containing zero or more YAML +documents separated by document markers. Each document begins +with a ``---`` document marker line, contains a single YAML mapping +that logs events from one CMake "configure" step, and, if the configure +step finished normally, ends with a ``...`` document marker line: + +.. code-block:: yaml + + --- + version: + major: 1 + minor: 0 + events: + - + kind: "..." + # (other fields omitted) + - + kind: "..." + # (other fields omitted) + ... + +A new document is appended to the log every time CMake configures +the build tree and logs new events. + +The keys of the each document root mapping are: + +``version`` + A YAML mapping that describes the schema version of the log document. + It has keys ``major`` and ``minor`` holding non-negative integer values. + +``events`` + A YAML block sequence of nodes corresponding to events logged during + one CMake "configure" step. Each event is a YAML node containing one + of the `Event Kinds`_ documented below. + +Text Block Encoding +------------------- + +In order to make the log human-readable, text blocks are always +represented using YAML literal block scalars (``|``). +Since literal block scalars do not support escaping, backslashes +and non-printable characters are encoded at the application layer: + +* ``\\`` encodes a backslash. +* ``\xXX`` encodes a byte using two hexadecimal digits, ``XX``. + +.. _`configure-log event kinds`: + +Event Kinds +=========== + +Every event kind is represented by a YAML mapping of the form: + +.. code-block:: yaml + + kind: "" + backtrace: + - ": ()" + #...event-specific keys... + +The keys common to all events are: + +``kind`` + A string identifying the event kind. + +``backtrace`` + A YAML block sequence reporting the call stack of CMake source + locations at which the event occurred. Each node is a string + specifying one location formatted as ``: ()``. + +Additional mapping keys are specific to each event kind. diff --git a/Help/release/dev/configure-log.rst b/Help/release/dev/configure-log.rst new file mode 100644 index 0000000..8518b21 --- /dev/null +++ b/Help/release/dev/configure-log.rst @@ -0,0 +1,5 @@ +Configure Log +------------- + +* CMake now writes a YAML log of configure-time checks. + See the :manual:`cmake-configure-log(7)` manual. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 41a901a..db928fc 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -160,6 +160,8 @@ add_library( cmComputeLinkInformation.h cmComputeTargetDepends.h cmComputeTargetDepends.cxx + cmConfigureLog.h + cmConfigureLog.cxx cmConsoleBuf.h cmConsoleBuf.cxx cmConstStack.h diff --git a/Source/cmConfigureLog.cxx b/Source/cmConfigureLog.cxx new file mode 100644 index 0000000..7489edc --- /dev/null +++ b/Source/cmConfigureLog.cxx @@ -0,0 +1,238 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmConfigureLog.h" + +#include +#include +#include +#include +#include + +#include + +#include + +#include "cm_utf8.h" + +#include "cmListFileCache.h" +#include "cmMakefile.h" +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" +#include "cmake.h" + +cmConfigureLog::cmConfigureLog(std::string logDir) + : LogDir(std::move(logDir)) +{ + Json::StreamWriterBuilder builder; + this->Encoder.reset(builder.newStreamWriter()); +} + +cmConfigureLog::~cmConfigureLog() +{ + if (this->Opened) { + this->EndObject(); + this->Stream << "...\n"; + } +} + +void cmConfigureLog::WriteBacktrace(cmMakefile const& mf) +{ + std::vector backtrace; + auto root = mf.GetCMakeInstance()->GetHomeDirectory(); + for (auto bt = mf.GetBacktrace(); !bt.Empty(); bt = bt.Pop()) { + auto t = bt.Top(); + if (!t.Name.empty() || t.Line == cmListFileContext::DeferPlaceholderLine) { + t.FilePath = cmSystemTools::RelativeIfUnder(root, t.FilePath); + std::ostringstream s; + s << t; + backtrace.emplace_back(s.str()); + } + } + this->WriteValue("backtrace"_s, backtrace); +} + +void cmConfigureLog::EnsureInit() +{ + if (this->Opened) { + return; + } + assert(!this->Stream.is_open()); + + std::string name = cmStrCat(this->LogDir, "/CMakeConfigureLog.yaml"); + this->Stream.open(name.c_str(), std::ios::out | std::ios::app); + + this->Opened = true; + + this->Stream << "\n---\n"; + this->BeginObject("version"_s); + this->WriteValue("major"_s, 1); + this->WriteValue("minor"_s, 0); + this->EndObject(); + this->BeginObject("events"_s); +} + +cmsys::ofstream& cmConfigureLog::BeginLine() +{ + for (unsigned i = 0; i < this->Indent; ++i) { + this->Stream << " "; + } + return this->Stream; +} + +void cmConfigureLog::EndLine() +{ + this->Stream << std::endl; +} + +void cmConfigureLog::BeginObject(cm::string_view key) +{ + this->BeginLine() << key << ':'; + this->EndLine(); + ++this->Indent; +} + +void cmConfigureLog::EndObject() +{ + assert(this->Indent); + --this->Indent; +} + +void cmConfigureLog::BeginEvent(std::string const& kind) +{ + this->EnsureInit(); + + this->BeginLine() << '-'; + this->EndLine(); + + ++this->Indent; + + this->WriteValue("kind"_s, kind); +} + +void cmConfigureLog::EndEvent() +{ + assert(this->Indent); + --this->Indent; +} + +void cmConfigureLog::WriteValue(cm::string_view key, std::nullptr_t) +{ + this->BeginLine() << key << ": null"; + this->EndLine(); +} + +void cmConfigureLog::WriteValue(cm::string_view key, bool value) +{ + this->BeginLine() << key << ": " << (value ? "true" : "false"); + this->EndLine(); +} + +void cmConfigureLog::WriteValue(cm::string_view key, int value) +{ + this->BeginLine() << key << ": " << value; + this->EndLine(); +} + +void cmConfigureLog::WriteValue(cm::string_view key, std::string const& value) +{ + this->BeginLine() << key << ": "; + this->Encoder->write(value, &this->Stream); + this->EndLine(); +} + +void cmConfigureLog::WriteValue(cm::string_view key, + std::vector const& list) +{ + this->BeginObject(key); + for (auto const& value : list) { + this->BeginLine() << "- "; + this->Encoder->write(value, &this->Stream); + this->EndLine(); + } + this->EndObject(); +} + +void cmConfigureLog::WriteLiteralTextBlock(cm::string_view key, + cm::string_view text) +{ + this->BeginLine() << key << ": |"; + this->EndLine(); + + auto const l = text.length(); + if (l) { + ++this->Indent; + this->BeginLine(); + + auto i = decltype(l){ 0 }; + while (i < l) { + // YAML allows ' ', '\t' and "printable characters", but NOT other + // ASCII whitespace; those must be escaped, as must the upper UNICODE + // control characters (U+0080 - U+009F) + static constexpr unsigned int C1_LAST = 0x9F; + auto const c = static_cast(text[i]); + switch (c) { + case '\r': + // Print a carriage return only if it is not followed by a line feed. + ++i; + if (i == l || text[i] != '\n') { + this->WriteEscape(c); + } + break; + case '\n': + // Print any line feeds except the very last one + if (i + 1 < l) { + this->EndLine(); + this->BeginLine(); + } + ++i; + break; + case '\t': + // Print horizontal tab verbatim + this->Stream.put('\t'); + ++i; + break; + case '\\': + // Escape backslash for disambiguation + this->Stream << "\\\\"; + ++i; + break; + default: + if (c >= 32 && c < 127) { + // Print ascii byte. + this->Stream.put(text[i]); + ++i; + break; + } else if (c > 127) { + // Decode a UTF-8 sequence. + unsigned int c32; + auto const* const s = text.data() + i; + auto const* const e = text.data() + l; + auto const* const n = cm_utf8_decode_character(s, e, &c32); + if (n > s && c32 > C1_LAST) { + auto const k = std::distance(s, n); + this->Stream.write(s, static_cast(k)); + i += static_cast(k); + break; + } + } + + // Escape non-printable byte. + this->WriteEscape(c); + ++i; + break; + } + } + + this->EndLine(); + --this->Indent; + } +} + +void cmConfigureLog::WriteEscape(unsigned char c) +{ + char buffer[6]; + int n = snprintf(buffer, sizeof(buffer), "\\x%02x", c); + if (n > 0) { + this->Stream.write(buffer, n); + } +} diff --git a/Source/cmConfigureLog.h b/Source/cmConfigureLog.h new file mode 100644 index 0000000..a71fd0c --- /dev/null +++ b/Source/cmConfigureLog.h @@ -0,0 +1,61 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include +#include +#include + +#include + +#include "cmsys/FStream.hxx" + +namespace Json { +class StreamWriter; +} + +class cmMakefile; + +class cmConfigureLog +{ +public: + cmConfigureLog(std::string logDir); + ~cmConfigureLog(); + + void WriteBacktrace(cmMakefile const& mf); + + void EnsureInit(); + + void BeginEvent(std::string const& kind); + void EndEvent(); + + void BeginObject(cm::string_view key); + void EndObject(); + + // TODO other value types + void WriteValue(cm::string_view key, std::nullptr_t); + void WriteValue(cm::string_view key, bool value); + void WriteValue(cm::string_view key, int value); + void WriteValue(cm::string_view key, std::string const& value); + void WriteValue(cm::string_view key, std::vector const& list); + + void WriteTextBlock(cm::string_view key, cm::string_view text); + void WriteLiteralTextBlock(cm::string_view key, cm::string_view text); + + void WriteLiteralTextBlock(cm::string_view key, std::string const& text) + { + this->WriteLiteralTextBlock(key, cm::string_view{ text }); + } + +private: + std::string LogDir; + cmsys::ofstream Stream; + unsigned Indent = 0; + bool Opened = false; + + std::unique_ptr Encoder; + + cmsys::ofstream& BeginLine(); + void EndLine(); + void WriteEscape(unsigned char c); +}; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index befcb55..17027bc 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -70,6 +70,7 @@ # include # include +# include "cmConfigureLog.h" # include "cmFileAPI.h" # include "cmGraphVizWriter.h" # include "cmVariableWatch.h" @@ -2423,10 +2424,21 @@ int cmake::ActualConfigure() #if !defined(CMAKE_BOOTSTRAP) this->FileAPI = cm::make_unique(this); this->FileAPI->ReadQueries(); + + if (!this->GetIsInTryCompile()) { + this->TruncateOutputLog("CMakeConfigureLog.yaml"); + this->ConfigureLog = cm::make_unique( + cmStrCat(this->GetHomeOutputDirectory(), "/CMakeFiles"_s)); + } #endif // actually do the configure this->GlobalGenerator->Configure(); + +#if !defined(CMAKE_BOOTSTRAP) + this->ConfigureLog.reset(); +#endif + // Before saving the cache // if the project did not define one of the entries below, add them now // so users can edit the values in the cache: diff --git a/Source/cmake.h b/Source/cmake.h index 325c0c5..10db87d 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -37,6 +37,7 @@ # include "cmMakefileProfilingData.h" #endif +class cmConfigureLog; class cmExternalMakefileProjectGeneratorFactory; class cmFileAPI; class cmFileTimeCache; @@ -521,6 +522,10 @@ public: void SetTraceFile(std::string const& file); void PrintTraceFormatVersion(); +#ifndef CMAKE_BOOTSTRAP + cmConfigureLog* GetConfigureLog() const { return this->ConfigureLog.get(); } +#endif + //! Use trace from another ::cmake instance. void SetTraceRedirect(cmake* other); @@ -714,6 +719,9 @@ private: TraceFormat TraceFormatVar = TRACE_HUMAN; cmGeneratedFileStream TraceFile; cmake* TraceRedirect = nullptr; +#ifndef CMAKE_BOOTSTRAP + std::unique_ptr ConfigureLog; +#endif bool WarnUninitialized = false; bool WarnUnusedCli = true; bool CheckSystemVars = false; diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 670beb9..54d7eb5 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -33,7 +33,7 @@ function(run_cmake test) set(platform_name msys) endif() - foreach(o IN ITEMS stdout stderr) + foreach(o IN ITEMS stdout stderr config) if(RunCMake-${o}-file AND EXISTS ${top_src}/${RunCMake-${o}-file}) file(READ ${top_src}/${RunCMake-${o}-file} expect_${o}) string(REGEX REPLACE "\n+$" "" expect_${o} "${expect_${o}}") @@ -144,6 +144,12 @@ function(run_cmake test) if(NOT "${actual_result}" MATCHES "${expect_result}") string(APPEND msg "Result is [${actual_result}], not [${expect_result}].\n") endif() + set(config_file "${RunCMake_TEST_COMMAND_WORKING_DIRECTORY}/CMakeFiles/CMakeConfigureLog.yaml") + if(EXISTS "${config_file}") + file(READ "${config_file}" actual_config) + else() + set(actual_config "") + endif() # Special case: remove ninja no-op line from stderr, but not stdout. # Test cases that look for it should use RunCMake_TEST_OUTPUT_MERGE. @@ -180,7 +186,7 @@ function(run_cmake test) "|[^\n]*Bullseye Testing Technology" ")[^\n]*\n)+" ) - foreach(o IN ITEMS stdout stderr) + foreach(o IN ITEMS stdout stderr config) string(REGEX REPLACE "\r\n" "\n" actual_${o} "${actual_${o}}") string(REGEX REPLACE "${ignore_line_regex}" "\\1" actual_${o} "${actual_${o}}") string(REGEX REPLACE "\n+$" "" actual_${o} "${actual_${o}}") @@ -211,13 +217,15 @@ function(run_cmake test) string(APPEND msg "Command was:\n command> ${command}\n") endif() if(msg) - foreach(o IN ITEMS stdout stderr) + foreach(o IN ITEMS stdout stderr config) if(DEFINED expect_${o}) string(REGEX REPLACE "\n" "\n expect-${o}> " expect_${o} " expect-${o}> ${expect_${o}}") string(APPEND msg "Expected ${o} to match:\n${expect_${o}}\n") endif() - string(REGEX REPLACE "\n" "\n actual-${o}> " actual_${o} " actual-${o}> ${actual_${o}}") - string(APPEND msg "Actual ${o}:\n${actual_${o}}\n") + if(NOT o STREQUAL "config" OR DEFINED expect_${o}) + string(REGEX REPLACE "\n" "\n actual-${o}> " actual_${o} " actual-${o}> ${actual_${o}}") + string(APPEND msg "Actual ${o}:\n${actual_${o}}\n") + endif() endforeach() message(SEND_ERROR "${test}${RunCMake_TEST_VARIANT_DESCRIPTION} - FAILED:\n${msg}") else() -- cgit v0.12 From 048a02d5bb842c783fad03105bb60e44227765ad Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Wed, 23 Nov 2022 17:02:22 -0500 Subject: ConfigureLog: Log try_compile and try_run checks Add configure log events for `try_compile` and `try_run` results. Issue: #23200 --- Help/manual/cmake-configure-log.7.rst | 137 ++++++++++++++++++++- Source/cmCoreTryCompile.cxx | 23 ++++ Source/cmCoreTryCompile.h | 11 ++ Source/cmTryCompileCommand.cxx | 26 +++- Source/cmTryRunCommand.cxx | 93 ++++++++++++-- Tests/RunCMake/try_compile/Inspect-config.txt | 37 ++++++ .../try_compile/SourceFromBadName-config.txt | 1 + Tests/RunCMake/try_run/ConfigureLog-bad.c | 1 + Tests/RunCMake/try_run/ConfigureLog-config.txt | 99 +++++++++++++++ Tests/RunCMake/try_run/ConfigureLog-test.c | 9 ++ Tests/RunCMake/try_run/ConfigureLog.cmake | 18 +++ Tests/RunCMake/try_run/RunCMakeTest.cmake | 1 + 12 files changed, 441 insertions(+), 15 deletions(-) create mode 100644 Tests/RunCMake/try_compile/Inspect-config.txt create mode 100644 Tests/RunCMake/try_compile/SourceFromBadName-config.txt create mode 100644 Tests/RunCMake/try_run/ConfigureLog-bad.c create mode 100644 Tests/RunCMake/try_run/ConfigureLog-config.txt create mode 100644 Tests/RunCMake/try_run/ConfigureLog-test.c create mode 100644 Tests/RunCMake/try_run/ConfigureLog.cmake diff --git a/Help/manual/cmake-configure-log.7.rst b/Help/manual/cmake-configure-log.7.rst index 3ae7dca..02e7bb7 100644 --- a/Help/manual/cmake-configure-log.7.rst +++ b/Help/manual/cmake-configure-log.7.rst @@ -43,10 +43,10 @@ step finished normally, ends with a ``...`` document marker line: minor: 0 events: - - kind: "..." + kind: "try_compile" # (other fields omitted) - - kind: "..." + kind: "try_compile" # (other fields omitted) ... @@ -99,4 +99,135 @@ The keys common to all events are: locations at which the event occurred. Each node is a string specifying one location formatted as ``: ()``. -Additional mapping keys are specific to each event kind. +Additional mapping keys are specific to each event kind, +described below. + +.. _`try_compile event`: + +Event Kind ``try_compile`` +-------------------------- + +The :command:`try_compile` command logs ``try_compile`` events. + +A ``try_compile`` event is a YAML mapping: + +.. code-block:: yaml + + kind: "try_compile" + backtrace: + - "CMakeLists.txt:123 (try_compile)" + directories: + source: "/path/to/.../TryCompile-01234" + binary: "/path/to/.../TryCompile-01234" + buildResult: + variable: "COMPILE_RESULT" + cached: true + stdout: | + # ... + exitCode: 0 + +The keys specific to ``try_compile`` mappings are: + +``directories`` + A mapping describing the directories associated with the + compilation attempt. It has the following keys: + + ``source`` + String specifying the source directory of the + :command:`try_compile` project. + + ``binary`` + String specifying the binary directory of the + :command:`try_compile` project. + For non-project invocations, this is often the same as + the source directory. + +``buildResult`` + A mapping describing the result of compiling the test code. + It has the following keys: + + ``variable`` + A string specifying the name of the CMake variable + storing the result of trying to build the test project. + + ``cached`` + A boolean indicating whether the above result ``variable`` + is stored in the CMake cache. + + ``stdout`` + A YAML literal block scalar containing the output from building + the test project, represented using our `Text Block Encoding`_. + This contains build output from both stdout and stderr. + + ``exitCode`` + An integer specifying the build tool exit code from trying + to build the test project. + +Event Kind ``try_run`` +---------------------- + +The :command:`try_run` command logs ``try_run`` events. + +A ``try_run`` event is a YAML mapping: + +.. code-block:: yaml + + kind: "try_run" + backtrace: + - "CMakeLists.txt:456 (try_run)" + directories: + source: "/path/to/.../TryCompile-56789" + binary: "/path/to/.../TryCompile-56789" + buildResult: + variable: "COMPILE_RESULT" + cached: true + stdout: | + # ... + exitCode: 0 + runResult: + variable: "RUN_RESULT" + cached: true + stdout: | + # ... + stderr: | + # ... + exitCode: 0 + +The keys specific to ``try_run`` mappings include those +documented by the `try_compile event`_, plus: + +``runResult`` + A mapping describing the result of running the test code. + It has the following keys: + + ``variable`` + A string specifying the name of the CMake variable + storing the result of trying to run the test executable. + + ``cached`` + A boolean indicating whether the above result ``variable`` + is stored in the CMake cache. + + ``stdout`` + An optional key that is present when the test project built successfully. + Its value is a YAML literal block scalar containing output from running + the test executable, represented using our `Text Block Encoding`_. + + If ``RUN_OUTPUT_VARIABLE`` was used, stdout and stderr are captured + together, so this will contain both. Otherwise, this will contain + only the stdout output. + + ``stderr`` + An optional key that is present when the test project built successfully + and the ``RUN_OUTPUT_VARIABLE`` option was not used. + Its value is a YAML literal block scalar containing output from running + the test executable, represented using our `Text Block Encoding`_. + + If ``RUN_OUTPUT_VARIABLE`` was used, stdout and stderr are captured + together in the ``stdout`` key, and this key will not be present. + Otherwise, this will contain the stderr output. + + ``exitCode`` + An optional key that is present when the test project built successfully. + Its value is an integer specifying the exit code, or a string containing + an error message, from trying to run the test executable. diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index e7351b2..25a0e2d 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -16,6 +16,7 @@ #include "cmsys/FStream.hxx" #include "cmArgumentParser.h" +#include "cmConfigureLog.h" #include "cmExportTryCompileFileGenerator.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" @@ -1124,6 +1125,11 @@ cm::optional cmCoreTryCompile::TryCompileCode( } cmTryCompileResult result; + result.SourceDirectory = sourceDirectory; + result.BinaryDirectory = this->BinaryDirectory; + result.Variable = *arguments.CompileResultVariable; + result.VariableCached = !arguments.NoCache; + result.Output = std::move(output); result.ExitCode = res; return result; } @@ -1266,3 +1272,20 @@ std::string cmCoreTryCompile::WriteSource(std::string const& filename, file.close(); return filepath; } + +void cmCoreTryCompile::WriteTryCompileEventFields( + cmConfigureLog& log, cmTryCompileResult const& compileResult) +{ +#ifndef CMAKE_BOOTSTRAP + log.BeginObject("directories"_s); + log.WriteValue("source"_s, compileResult.SourceDirectory); + log.WriteValue("binary"_s, compileResult.BinaryDirectory); + log.EndObject(); + log.BeginObject("buildResult"_s); + log.WriteValue("variable"_s, compileResult.Variable); + log.WriteValue("cached"_s, compileResult.VariableCached); + log.WriteLiteralTextBlock("stdout"_s, compileResult.Output); + log.WriteValue("exitCode"_s, compileResult.ExitCode); + log.EndObject(); +#endif +} diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h index d9649b9..6d29586 100644 --- a/Source/cmCoreTryCompile.h +++ b/Source/cmCoreTryCompile.h @@ -14,12 +14,20 @@ #include "cmArgumentParserTypes.h" #include "cmStateTypes.h" +class cmConfigureLog; class cmMakefile; template class cmRange; struct cmTryCompileResult { + std::string SourceDirectory; + std::string BinaryDirectory; + + bool VariableCached = true; + std::string Variable; + + std::string Output; int ExitCode = 1; }; @@ -108,6 +116,9 @@ public: */ void FindOutputFile(const std::string& targetName); + static void WriteTryCompileEventFields( + cmConfigureLog& log, cmTryCompileResult const& compileResult); + std::string BinaryDirectory; std::string OutputFile; std::string FindErrorMessage; diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx index a2c4ce1..74d240f 100644 --- a/Source/cmTryCompileCommand.cxx +++ b/Source/cmTryCompileCommand.cxx @@ -2,6 +2,9 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTryCompileCommand.h" +#include + +#include "cmConfigureLog.h" #include "cmCoreTryCompile.h" #include "cmExecutionStatus.h" #include "cmMakefile.h" @@ -13,6 +16,19 @@ #include "cmValue.h" #include "cmake.h" +namespace { +#ifndef CMAKE_BOOTSTRAP +void WriteTryCompileEvent(cmConfigureLog& log, cmMakefile const& mf, + cmTryCompileResult const& compileResult) +{ + log.BeginEvent("try_compile"); + log.WriteBacktrace(mf); + cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult); + log.EndEvent(); +} +#endif +} + bool cmTryCompileCommand(std::vector const& args, cmExecutionStatus& status) { @@ -59,7 +75,15 @@ bool cmTryCompileCommand(std::vector const& args, if (!arguments) { return true; } - tc.TryCompileCode(arguments, targetType); + + if (cm::optional compileResult = + tc.TryCompileCode(arguments, targetType)) { +#ifndef CMAKE_BOOTSTRAP + if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) { + WriteTryCompileEvent(*log, mf, *compileResult); + } +#endif + } // if They specified clean then we clean up what we can if (tc.SrcFileSignature) { diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index bbefcd9..794f2c6 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -3,12 +3,15 @@ #include "cmTryRunCommand.h" #include +#include #include +#include #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 Stdout; + cm::optional Stderr; + cm::optional 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 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 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 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 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); diff --git a/Tests/RunCMake/try_compile/Inspect-config.txt b/Tests/RunCMake/try_compile/Inspect-config.txt new file mode 100644 index 0000000..fad24d7 --- /dev/null +++ b/Tests/RunCMake/try_compile/Inspect-config.txt @@ -0,0 +1,37 @@ +^ +--- +version: + major: 1 + minor: 0 +events: + - + kind: "try_compile" + backtrace: + - "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)" + - "[^"]*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)" + - "Inspect.cmake:[0-9]+ \(enable_language\)" + - "CMakeLists.txt:[0-9]+ \(include\)" + directories: + source: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "CMAKE_C_ABI_COMPILED" + cached: true + stdout: \|.* + exitCode: 0 + - + kind: "try_compile" + backtrace: + - "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)" + - "[^"]*/Modules/CMakeTestCXXCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)" + - "Inspect.cmake:[0-9]+ \(enable_language\)" + - "CMakeLists.txt:[0-9]+ \(include\)" + directories: + source: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_compile/Inspect-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "CMAKE_CXX_ABI_COMPILED" + cached: true + stdout: \|.* + exitCode: 0 +\.\.\.$ diff --git a/Tests/RunCMake/try_compile/SourceFromBadName-config.txt b/Tests/RunCMake/try_compile/SourceFromBadName-config.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/try_compile/SourceFromBadName-config.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/try_run/ConfigureLog-bad.c b/Tests/RunCMake/try_run/ConfigureLog-bad.c new file mode 100644 index 0000000..6508ead --- /dev/null +++ b/Tests/RunCMake/try_run/ConfigureLog-bad.c @@ -0,0 +1 @@ +#error "This does not compile!" diff --git a/Tests/RunCMake/try_run/ConfigureLog-config.txt b/Tests/RunCMake/try_run/ConfigureLog-config.txt new file mode 100644 index 0000000..5078793 --- /dev/null +++ b/Tests/RunCMake/try_run/ConfigureLog-config.txt @@ -0,0 +1,99 @@ +^ +--- +version: + major: 1 + minor: 0 +events: + - + kind: "try_compile" + backtrace: + - "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)" + - "[^"]*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)" + - "CMakeLists.txt:[0-9]+ \(project\)" + directories: + source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "CMAKE_C_ABI_COMPILED" + cached: true + stdout: \|.* + exitCode: 0 + - + kind: "try_run" + backtrace: + - "ConfigureLog.cmake:[0-9]+ \(try_run\)" + - "CMakeLists.txt:[0-9]+ \(include\)" + directories: + source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "COMPILE_RESULT" + cached: true + stdout: \|.* + exitCode: [1-9][0-9]* + runResult: + variable: "RUN_RESULT" + cached: true + - + kind: "try_run" + backtrace: + - "ConfigureLog.cmake:[0-9]+ \(try_run\)" + - "CMakeLists.txt:[0-9]+ \(include\)" + directories: + source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "COMPILE_RESULT" + cached: true + stdout: \|.* + exitCode: 0 + runResult: + variable: "RUN_RESULT" + cached: true + stdout: \| + Output on stdout! + stderr: \| + Output, with backslash '\\\\', on stderr! + exitCode: 12 + - + kind: "try_run" + backtrace: + - "ConfigureLog.cmake:[0-9]+ \(try_run\)" + - "CMakeLists.txt:[0-9]+ \(include\)" + directories: + source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "COMPILE_RESULT" + cached: true + stdout: \|.* + exitCode: 0 + runResult: + variable: "RUN_RESULT" + cached: true + stdout: \| + Output, with backslash '\\\\', on stderr! + Output on stdout! + exitCode: 12 + - + kind: "try_run" + backtrace: + - "ConfigureLog.cmake:[0-9]+ \(try_run\)" + - "CMakeLists.txt:[0-9]+ \(include\)" + directories: + source: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + binary: "[^"]*/Tests/RunCMake/try_run/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/]+" + buildResult: + variable: "COMPILE_RESULT" + cached: true + stdout: \|.* + exitCode: 0 + runResult: + variable: "RUN_RESULT" + cached: true + stdout: \| + Output on stdout! + stderr: \| + Output, with backslash '\\\\', on stderr! + exitCode: 12 +\.\.\.$ diff --git a/Tests/RunCMake/try_run/ConfigureLog-test.c b/Tests/RunCMake/try_run/ConfigureLog-test.c new file mode 100644 index 0000000..6a8f125 --- /dev/null +++ b/Tests/RunCMake/try_run/ConfigureLog-test.c @@ -0,0 +1,9 @@ +#include + +int main() +{ + fprintf(stderr, "Output, with backslash '\\', on stderr!\n"); + fflush(stderr); /* make output deterministic even if stderr is buffered */ + fprintf(stdout, "Output on stdout!\n"); + return 12; +} diff --git a/Tests/RunCMake/try_run/ConfigureLog.cmake b/Tests/RunCMake/try_run/ConfigureLog.cmake new file mode 100644 index 0000000..4b5c7cb --- /dev/null +++ b/Tests/RunCMake/try_run/ConfigureLog.cmake @@ -0,0 +1,18 @@ +try_run(RUN_RESULT COMPILE_RESULT + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureLog-bad.c + ) + +try_run(RUN_RESULT COMPILE_RESULT + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureLog-test.c + ) + +try_run(RUN_RESULT COMPILE_RESULT + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureLog-test.c + RUN_OUTPUT_VARIABLE RUN_OUTPUT + ) + +try_run(RUN_RESULT COMPILE_RESULT + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/ConfigureLog-test.c + RUN_OUTPUT_STDOUT_VARIABLE RUN_STDOUT + RUN_OUTPUT_STDERR_VARIABLE RUN_STDERR + ) diff --git a/Tests/RunCMake/try_run/RunCMakeTest.cmake b/Tests/RunCMake/try_run/RunCMakeTest.cmake index dbea089..62e3caf 100644 --- a/Tests/RunCMake/try_run/RunCMakeTest.cmake +++ b/Tests/RunCMake/try_run/RunCMakeTest.cmake @@ -3,6 +3,7 @@ include(RunCMake) run_cmake(BinDirEmpty) run_cmake(BinDirRelative) run_cmake(NoOutputVariable) +run_cmake(ConfigureLog) set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=old_signature.cmake) include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake) -- cgit v0.12 From 6c40e0b25ec8475d73779ffbaa63a4230aa5e28d Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 8 Dec 2022 12:16:08 -0500 Subject: ConfigureLog: Version individual events instead of the whole log In order to support multiple log versions without buffering the entire log, move versioning to the level of individual events. Multiple versions of an event may then be logged consecutively. Issue: #23200 --- Help/manual/cmake-configure-log.7.rst | 63 +++++++++++++++++--------- Source/cmConfigureLog.cxx | 33 ++++++++++++-- Source/cmConfigureLog.h | 9 +++- Source/cmTryCompileCommand.cxx | 12 +++-- Source/cmTryRunCommand.cxx | 44 ++++++++++-------- Source/cmake.cxx | 3 +- Tests/RunCMake/try_compile/Inspect-config.txt | 7 +-- Tests/RunCMake/try_run/ConfigureLog-config.txt | 13 ++---- 8 files changed, 119 insertions(+), 65 deletions(-) diff --git a/Help/manual/cmake-configure-log.7.rst b/Help/manual/cmake-configure-log.7.rst index 02e7bb7..7f395f5 100644 --- a/Help/manual/cmake-configure-log.7.rst +++ b/Help/manual/cmake-configure-log.7.rst @@ -38,15 +38,12 @@ step finished normally, ends with a ``...`` document marker line: .. code-block:: yaml --- - version: - major: 1 - minor: 0 events: - - kind: "try_compile" + kind: "try_compile-v1" # (other fields omitted) - - kind: "try_compile" + kind: "try_compile-v1" # (other fields omitted) ... @@ -55,15 +52,27 @@ the build tree and logs new events. The keys of the each document root mapping are: -``version`` - A YAML mapping that describes the schema version of the log document. - It has keys ``major`` and ``minor`` holding non-negative integer values. - ``events`` A YAML block sequence of nodes corresponding to events logged during one CMake "configure" step. Each event is a YAML node containing one of the `Event Kinds`_ documented below. +Log Versioning +-------------- + +Each of the `Event Kinds`_ is versioned independently. The set of +keys an event's log entry provides is specific to its major version. +When an event is logged, the latest version of its event kind that is +known to the running version of CMake is always written to the log. + +Tools reading the configure log must ignore event kinds and versions +they do not understand: + +* A future version of CMake may introduce a new event kind or version. + +* If an existing build tree is re-configured with a different version of + CMake, the log may contain different versions of the same event kind. + Text Block Encoding ------------------- @@ -84,7 +93,7 @@ Every event kind is represented by a YAML mapping of the form: .. code-block:: yaml - kind: "" + kind: "-v" backtrace: - ": ()" #...event-specific keys... @@ -92,28 +101,33 @@ Every event kind is represented by a YAML mapping of the form: The keys common to all events are: ``kind`` - A string identifying the event kind. + A string identifying the event kind and major version. ``backtrace`` A YAML block sequence reporting the call stack of CMake source locations at which the event occurred. Each node is a string specifying one location formatted as ``: ()``. -Additional mapping keys are specific to each event kind, +Additional mapping keys are specific to each (versioned) event kind, described below. -.. _`try_compile event`: - Event Kind ``try_compile`` -------------------------- The :command:`try_compile` command logs ``try_compile`` events. -A ``try_compile`` event is a YAML mapping: +There is only one ``try_compile`` event major version, version 1. + +.. _`try_compile-v1 event`: + +``try_compile-v1`` Event +^^^^^^^^^^^^^^^^^^^^^^^^ + +A ``try_compile-v1`` event is a YAML mapping: .. code-block:: yaml - kind: "try_compile" + kind: "try_compile-v1" backtrace: - "CMakeLists.txt:123 (try_compile)" directories: @@ -126,7 +140,7 @@ A ``try_compile`` event is a YAML mapping: # ... exitCode: 0 -The keys specific to ``try_compile`` mappings are: +The keys specific to ``try_compile-v1`` mappings are: ``directories`` A mapping describing the directories associated with the @@ -168,11 +182,18 @@ Event Kind ``try_run`` The :command:`try_run` command logs ``try_run`` events. -A ``try_run`` event is a YAML mapping: +There is only one ``try_run`` event major version, version 1. + +.. _`try_run-v1 event`: + +``try_run-v1`` Event +^^^^^^^^^^^^^^^^^^^^ + +A ``try_run-v1`` event is a YAML mapping: .. code-block:: yaml - kind: "try_run" + kind: "try_run-v1" backtrace: - "CMakeLists.txt:456 (try_run)" directories: @@ -193,8 +214,8 @@ A ``try_run`` event is a YAML mapping: # ... exitCode: 0 -The keys specific to ``try_run`` mappings include those -documented by the `try_compile event`_, plus: +The keys specific to ``try_run-v1`` mappings include those +documented by the `try_compile-v1 event`_, plus: ``runResult`` A mapping describing the result of running the test code. diff --git a/Source/cmConfigureLog.cxx b/Source/cmConfigureLog.cxx index 7489edc..c2a5b5e 100644 --- a/Source/cmConfigureLog.cxx +++ b/Source/cmConfigureLog.cxx @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -20,9 +21,17 @@ #include "cmSystemTools.h" #include "cmake.h" -cmConfigureLog::cmConfigureLog(std::string logDir) +cmConfigureLog::cmConfigureLog(std::string logDir, + std::vector logVersions) : LogDir(std::move(logDir)) + , LogVersions(std::move(logVersions)) { + // Always emit events for the latest log version. + static const unsigned long LatestLogVersion = 1; + if (!cm::contains(this->LogVersions, LatestLogVersion)) { + this->LogVersions.emplace_back(LatestLogVersion); + } + Json::StreamWriterBuilder builder; this->Encoder.reset(builder.newStreamWriter()); } @@ -35,6 +44,24 @@ cmConfigureLog::~cmConfigureLog() } } +bool cmConfigureLog::IsAnyLogVersionEnabled( + std::vector const& v) const +{ + // Both input lists are sorted. Look for a matching element. + auto i1 = v.cbegin(); + auto i2 = this->LogVersions.cbegin(); + while (i1 != v.cend() && i2 != this->LogVersions.cend()) { + if (*i1 < *i2) { + ++i1; + } else if (*i2 < *i1) { + ++i2; + } else { + return true; + } + } + return false; +} + void cmConfigureLog::WriteBacktrace(cmMakefile const& mf) { std::vector backtrace; @@ -64,10 +91,6 @@ void cmConfigureLog::EnsureInit() this->Opened = true; this->Stream << "\n---\n"; - this->BeginObject("version"_s); - this->WriteValue("major"_s, 1); - this->WriteValue("minor"_s, 0); - this->EndObject(); this->BeginObject("events"_s); } diff --git a/Source/cmConfigureLog.h b/Source/cmConfigureLog.h index a71fd0c..9caac66 100644 --- a/Source/cmConfigureLog.h +++ b/Source/cmConfigureLog.h @@ -19,9 +19,15 @@ class cmMakefile; class cmConfigureLog { public: - cmConfigureLog(std::string logDir); + /** Construct with the log directory and a sorted list of enabled log + versions. The latest log version will be enabled regardless. */ + cmConfigureLog(std::string logDir, std::vector logVersions); ~cmConfigureLog(); + /** Return true if at least one of the log versions in the given sorted + list is enabled. */ + bool IsAnyLogVersionEnabled(std::vector const& v) const; + void WriteBacktrace(cmMakefile const& mf); void EnsureInit(); @@ -49,6 +55,7 @@ public: private: std::string LogDir; + std::vector LogVersions; cmsys::ofstream Stream; unsigned Indent = 0; bool Opened = false; diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx index 74d240f..eff21cc 100644 --- a/Source/cmTryCompileCommand.cxx +++ b/Source/cmTryCompileCommand.cxx @@ -21,10 +21,14 @@ namespace { void WriteTryCompileEvent(cmConfigureLog& log, cmMakefile const& mf, cmTryCompileResult const& compileResult) { - log.BeginEvent("try_compile"); - log.WriteBacktrace(mf); - cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult); - log.EndEvent(); + static const std::vector LogVersionsWithTryCompileV1{ 1 }; + + if (log.IsAnyLogVersionEnabled(LogVersionsWithTryCompileV1)) { + log.BeginEvent("try_compile-v1"); + log.WriteBacktrace(mf); + cmCoreTryCompile::WriteTryCompileEventFields(log, compileResult); + log.EndEvent(); + } } #endif } diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx index 794f2c6..63e4478 100644 --- a/Source/cmTryRunCommand.cxx +++ b/Source/cmTryRunCommand.cxx @@ -40,28 +40,32 @@ 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); + static const std::vector LogVersionsWithTryRunV1{ 1 }; + + if (log.IsAnyLogVersionEnabled(LogVersionsWithTryRunV1)) { + log.BeginEvent("try_run-v1"); + 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(); } - log.EndObject(); - log.EndEvent(); } #endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 17027bc..ee63909 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2428,7 +2428,8 @@ int cmake::ActualConfigure() if (!this->GetIsInTryCompile()) { this->TruncateOutputLog("CMakeConfigureLog.yaml"); this->ConfigureLog = cm::make_unique( - cmStrCat(this->GetHomeOutputDirectory(), "/CMakeFiles"_s)); + cmStrCat(this->GetHomeOutputDirectory(), "/CMakeFiles"_s), + std::vector()); } #endif diff --git a/Tests/RunCMake/try_compile/Inspect-config.txt b/Tests/RunCMake/try_compile/Inspect-config.txt index fad24d7..47169cf 100644 --- a/Tests/RunCMake/try_compile/Inspect-config.txt +++ b/Tests/RunCMake/try_compile/Inspect-config.txt @@ -1,11 +1,8 @@ ^ --- -version: - major: 1 - minor: 0 events: - - kind: "try_compile" + kind: "try_compile-v1" backtrace: - "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)" - "[^"]*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)" @@ -20,7 +17,7 @@ events: stdout: \|.* exitCode: 0 - - kind: "try_compile" + kind: "try_compile-v1" backtrace: - "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)" - "[^"]*/Modules/CMakeTestCXXCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)" diff --git a/Tests/RunCMake/try_run/ConfigureLog-config.txt b/Tests/RunCMake/try_run/ConfigureLog-config.txt index 5078793..602437e 100644 --- a/Tests/RunCMake/try_run/ConfigureLog-config.txt +++ b/Tests/RunCMake/try_run/ConfigureLog-config.txt @@ -1,11 +1,8 @@ ^ --- -version: - major: 1 - minor: 0 events: - - kind: "try_compile" + kind: "try_compile-v1" backtrace: - "[^"]*/Modules/CMakeDetermineCompilerABI.cmake:[0-9]+ \(try_compile\)" - "[^"]*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_ABI\)" @@ -19,7 +16,7 @@ events: stdout: \|.* exitCode: 0 - - kind: "try_run" + kind: "try_run-v1" backtrace: - "ConfigureLog.cmake:[0-9]+ \(try_run\)" - "CMakeLists.txt:[0-9]+ \(include\)" @@ -35,7 +32,7 @@ events: variable: "RUN_RESULT" cached: true - - kind: "try_run" + kind: "try_run-v1" backtrace: - "ConfigureLog.cmake:[0-9]+ \(try_run\)" - "CMakeLists.txt:[0-9]+ \(include\)" @@ -56,7 +53,7 @@ events: Output, with backslash '\\\\', on stderr! exitCode: 12 - - kind: "try_run" + kind: "try_run-v1" backtrace: - "ConfigureLog.cmake:[0-9]+ \(try_run\)" - "CMakeLists.txt:[0-9]+ \(include\)" @@ -76,7 +73,7 @@ events: Output on stdout! exitCode: 12 - - kind: "try_run" + kind: "try_run-v1" backtrace: - "ConfigureLog.cmake:[0-9]+ \(try_run\)" - "CMakeLists.txt:[0-9]+ \(include\)" -- cgit v0.12