summaryrefslogtreecommitdiffstats
path: root/Source/cmake.cxx
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2019-11-30 11:48:26 (GMT)
committerDaniel Mensinger <daniel@mensinger-ka.de>2019-12-23 13:05:36 (GMT)
commit482497e0debc3de9f125c8c849a40872971a4a7e (patch)
tree2ae4aefba1e626668e411c53399cc241662e18d7 /Source/cmake.cxx
parent10fea25139cc302ef0f0a41aa68b44cda72a4fd2 (diff)
downloadCMake-482497e0debc3de9f125c8c849a40872971a4a7e.zip
CMake-482497e0debc3de9f125c8c849a40872971a4a7e.tar.gz
CMake-482497e0debc3de9f125c8c849a40872971a4a7e.tar.bz2
trace: Add JSON output format
Add a new `--trace-format=` flag, to enable the new JSON trace output format. This new format is easier to parse by machines than the existing format. This new format also removes the ambiguity of the whitespace in the "old" format (e.g. is that whitespace part of a file path, or does it seperate arguments)
Diffstat (limited to 'Source/cmake.cxx')
-rw-r--r--Source/cmake.cxx73
1 files changed, 73 insertions, 0 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index fdb3687..b1300c9 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -755,6 +755,15 @@ void cmake::SetArgs(const std::vector<std::string>& args)
std::cout << "Running with expanded trace output on.\n";
this->SetTrace(true);
this->SetTraceExpand(true);
+ } else if (arg.find("--trace-format=", 0) == 0) {
+ this->SetTrace(true);
+ const auto traceFormat =
+ StringToTraceFormat(arg.substr(strlen("--trace-format=")));
+ if (traceFormat == TraceFormat::TRACE_UNDEFINED) {
+ cmSystemTools::Error("Invalid format specified for --trace-format");
+ return;
+ }
+ this->SetTraceFormat(traceFormat);
} else if (arg.find("--trace-source=", 0) == 0) {
std::string file = arg.substr(strlen("--trace-source="));
cmSystemTools::ConvertToUnixSlashes(file);
@@ -895,6 +904,23 @@ cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr)
return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED;
}
+cmake::TraceFormat cmake::StringToTraceFormat(const std::string& traceStr)
+{
+ using TracePair = std::pair<std::string, TraceFormat>;
+ static const std::vector<TracePair> levels = {
+ { "human", TraceFormat::TRACE_HUMAN },
+ { "json-v1", TraceFormat::TRACE_JSON_V1 },
+ };
+
+ const auto traceStrLowCase = cmSystemTools::LowerCase(traceStr);
+
+ const auto it = std::find_if(levels.cbegin(), levels.cend(),
+ [&traceStrLowCase](const TracePair& p) {
+ return p.first == traceStrLowCase;
+ });
+ return (it != levels.cend()) ? it->second : TraceFormat::TRACE_UNDEFINED;
+}
+
void cmake::SetTraceFile(const std::string& file)
{
this->TraceFile.close();
@@ -909,6 +935,48 @@ void cmake::SetTraceFile(const std::string& file)
std::cout << "Trace will be written to " << file << "\n";
}
+void cmake::PrintTraceFormatVersion()
+{
+ if (!this->GetTrace()) {
+ return;
+ }
+
+ std::string msg;
+
+ switch (this->GetTraceFormat()) {
+ case TraceFormat::TRACE_JSON_V1: {
+#ifndef CMAKE_BOOTSTRAP
+ Json::Value val;
+ Json::Value version;
+ Json::StreamWriterBuilder builder;
+ builder["indentation"] = "";
+ version["major"] = 1;
+ version["minor"] = 0;
+ val["version"] = version;
+ msg = Json::writeString(builder, val);
+#endif
+ break;
+ }
+ case TraceFormat::TRACE_HUMAN:
+ msg = "";
+ break;
+ case TraceFormat::TRACE_UNDEFINED:
+ msg = "INTERNAL ERROR: Trace format is TRACE_UNDEFINED";
+ break;
+ }
+
+ if (msg.empty()) {
+ return;
+ }
+
+ auto& f = this->GetTraceFile();
+ if (f) {
+ f << msg << '\n';
+ } else {
+ cmSystemTools::Message(msg);
+ }
+}
+
void cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -1701,6 +1769,11 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
return -1;
}
+ // Log the trace format version to the desired output
+ if (this->GetTrace()) {
+ this->PrintTraceFormatVersion();
+ }
+
// If we are given a stamp list file check if it is really out of date.
if (!this->CheckStampList.empty() &&
cmakeCheckStampList(this->CheckStampList)) {