瀏覽代碼

Merge topic 'trace-redirect'

3c94069660 Add --trace-redirect parameter to redirect trace output to a file

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3645
Brad King 6 年之前
父節點
當前提交
a0c8405d68

+ 3 - 0
Help/manual/cmake.1.rst

@@ -238,6 +238,9 @@ Options
 
  Multiple options are allowed.
 
+``--trace-redirect=<file>``
+ Put cmake in trace mode and redirect trace output to a file instead of stderr.
+
 ``--warn-uninitialized``
  Warn about uninitialized values.
 

+ 6 - 0
Help/release/dev/trace-redirect.rst

@@ -0,0 +1,6 @@
+trace-redirect
+--------------
+
+* :manual:`cmake(1)` gained a ``--trace-redirect=<file>`` command line option
+  that can be used to redirect ``--trace`` output to a file instead
+  of ``stderr``.

+ 8 - 1
Source/cmMakefile.cxx

@@ -23,6 +23,7 @@
 #include "cmExpandedCommandArgument.h" // IWYU pragma: keep
 #include "cmFileLockPool.h"
 #include "cmFunctionBlocker.h"
+#include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionEvaluationFile.h"
 #include "cmGlobalGenerator.h"
@@ -321,7 +322,13 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
     msg << " ";
   }
   msg << ")";
-  cmSystemTools::Message(msg.str());
+
+  auto& f = this->GetCMakeInstance()->GetTraceFile();
+  if (f) {
+    f << msg.str() << '\n';
+  } else {
+    cmSystemTools::Message(msg.str());
+  }
 }
 
 // Helper class to make sure the call stack is valid.

+ 20 - 0
Source/cmake.cxx

@@ -140,6 +140,7 @@ cmake::cmake(Role role, cmState::Mode mode)
   , State(cm::make_unique<cmState>())
   , Messenger(cm::make_unique<cmMessenger>())
 {
+  this->TraceFile.close();
   this->State->SetMode(mode);
   this->CurrentSnapshot = this->State->CreateBaseSnapshot();
 
@@ -740,6 +741,11 @@ void cmake::SetArgs(const std::vector<std::string>& args)
       cmSystemTools::ConvertToUnixSlashes(file);
       this->AddTraceSource(file);
       this->SetTrace(true);
+    } else if (arg.find("--trace-redirect=", 0) == 0) {
+      std::string file = arg.substr(strlen("--trace-redirect="));
+      cmSystemTools::ConvertToUnixSlashes(file);
+      this->SetTraceFile(file);
+      this->SetTrace(true);
     } else if (arg.find("--trace", 0) == 0) {
       std::cout << "Running with trace output on.\n";
       this->SetTrace(true);
@@ -870,6 +876,20 @@ cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr)
   return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED;
 }
 
+void cmake::SetTraceFile(const std::string& file)
+{
+  this->TraceFile.close();
+  this->TraceFile.open(file.c_str());
+  if (!this->TraceFile) {
+    std::stringstream ss;
+    ss << "Error opening trace file " << file << ": "
+       << cmSystemTools::GetLastSystemError();
+    cmSystemTools::Error(ss.str());
+    return;
+  }
+  std::cout << "Trace will be written to " << file << "\n";
+}
+
 void cmake::SetDirectoriesFromFile(const std::string& arg)
 {
   // Check if the argument refers to a CMakeCache.txt or

+ 5 - 0
Source/cmake.h

@@ -13,6 +13,7 @@
 #include <unordered_set>
 #include <vector>
 
+#include "cmGeneratedFileStream.h"
 #include "cmInstalledFile.h"
 #include "cmListFileCache.h"
 #include "cmMessageType.h"
@@ -401,6 +402,9 @@ public:
   {
     return this->TraceOnlyThisSources;
   }
+  cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
+  void SetTraceFile(std::string const& file);
+
   bool GetWarnUninitialized() { return this->WarnUninitialized; }
   void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
   bool GetWarnUnused() { return this->WarnUnused; }
@@ -547,6 +551,7 @@ private:
   bool DebugOutput = false;
   bool Trace = false;
   bool TraceExpand = false;
+  cmGeneratedFileStream TraceFile;
   bool WarnUninitialized = false;
   bool WarnUnused = false;
   bool WarnUnusedCli = true;

+ 2 - 0
Source/cmakemain.cxx

@@ -80,6 +80,8 @@ const char* cmDocumentationOptions[][2] = {
   { "--trace-expand", "Put cmake in trace mode with variable expansion." },
   { "--trace-source=<file>",
     "Trace only this CMake file/module. Multiple options allowed." },
+  { "--trace-redirect=<file>",
+    "Redirect trace output to a file instead of stderr." },
   { "--warn-uninitialized", "Warn about uninitialized values." },
   { "--warn-unused-vars", "Warn about unused variables." },
   { "--no-warn-unused-cli", "Don't warn about command line options." },

+ 8 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -484,6 +484,14 @@ set(RunCMake_TEST_OPTIONS --trace-expand --warn-uninitialized)
 run_cmake(trace-expand-warn-uninitialized)
 unset(RunCMake_TEST_OPTIONS)
 
+set(RunCMake_TEST_OPTIONS --trace-redirect=${RunCMake_BINARY_DIR}/redirected.trace)
+run_cmake(trace-redirect)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --trace-redirect=/no/such/file.txt)
+run_cmake(trace-redirect-nofile)
+unset(RunCMake_TEST_OPTIONS)
+
 set(RunCMake_TEST_OPTIONS -Wno-deprecated --warn-uninitialized)
 run_cmake(warn-uninitialized)
 unset(RunCMake_TEST_OPTIONS)

+ 13 - 0
Tests/RunCMake/CommandLine/trace-redirect-check.cmake

@@ -0,0 +1,13 @@
+file(READ ${RunCMake_SOURCE_DIR}/trace-stderr.txt expected_content)
+string(REGEX REPLACE "\n+$" "" expected_content "${expected_content}")
+
+file(READ ${RunCMake_BINARY_DIR}/redirected.trace actual_content)
+string(REGEX REPLACE "\r\n" "\n" actual_content "${actual_content}")
+string(REGEX REPLACE "\n+$" "" actual_content "${actual_content}")
+if(NOT "${actual_content}" MATCHES "${expected_content}")
+    set(RunCMake_TEST_FAILED
+        "Trace file content does not match that expected."
+        "Expected to match:\n${expected_content}\n"
+        "Actual content:\n${actual_content}\n"
+        )
+endif()

+ 1 - 0
Tests/RunCMake/CommandLine/trace-redirect-nofile-result.txt

@@ -0,0 +1 @@
+1

+ 1 - 0
Tests/RunCMake/CommandLine/trace-redirect-nofile-stderr.txt

@@ -0,0 +1 @@
+^CMake Error: Error opening trace file /no/such/file.txt: .+$

+ 0 - 0
Tests/RunCMake/CommandLine/trace-redirect-nofile.cmake


+ 1 - 0
Tests/RunCMake/CommandLine/trace-redirect-stdout.txt

@@ -0,0 +1 @@
+^.*Trace will be written to .+redirected.trace.*$

+ 0 - 0
Tests/RunCMake/CommandLine/trace-redirect.cmake