mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-30 18:29:37 -06:00
For users of CMake who want to optimize their scripts if they take a while to run, this commit adds the ability to output profiling data. To enable this output, it adds the two command line parameters to select the output path and format. This commit adds the first profiling format of type ``google-trace``, which is the output is a JSON file containing Duration events as per the Google Trace Format specification: https://docs.google.com/document/d/1CvAClvFfyA5R- PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#
114 lines
3.4 KiB
C++
114 lines
3.4 KiB
C++
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
|
#include "cmMakefileProfilingData.h"
|
|
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <stdexcept>
|
|
#include <vector>
|
|
|
|
#include "cmsys/FStream.hxx"
|
|
#include "cmsys/SystemInformation.hxx"
|
|
|
|
#include "cm_jsoncpp_value.h"
|
|
#include "cm_jsoncpp_writer.h"
|
|
|
|
#include "cmListFileCache.h"
|
|
#include "cmStringAlgorithms.h"
|
|
#include "cmSystemTools.h"
|
|
|
|
cmMakefileProfilingData::cmMakefileProfilingData(
|
|
const std::string& profileStream)
|
|
{
|
|
std::ios::openmode omode = std::ios::out | std::ios::trunc;
|
|
this->ProfileStream.open(profileStream.c_str(), omode);
|
|
Json::StreamWriterBuilder wbuilder;
|
|
this->JsonWriter =
|
|
std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
|
|
if (!this->ProfileStream.good()) {
|
|
throw std::runtime_error(std::string("Unable to open: ") + profileStream);
|
|
}
|
|
|
|
this->ProfileStream << "[";
|
|
};
|
|
|
|
cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
|
|
{
|
|
if (this->ProfileStream.good()) {
|
|
try {
|
|
this->ProfileStream << "]";
|
|
this->ProfileStream.close();
|
|
} catch (...) {
|
|
cmSystemTools::Error("Error writing profiling output!");
|
|
}
|
|
}
|
|
}
|
|
|
|
void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
|
|
cmListFileContext const& lfc)
|
|
{
|
|
/* Do not try again if we previously failed to write to output. */
|
|
if (!this->ProfileStream.good()) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
if (this->ProfileStream.tellp() > 1) {
|
|
this->ProfileStream << ",";
|
|
}
|
|
cmsys::SystemInformation info;
|
|
Json::Value v;
|
|
v["ph"] = "B";
|
|
v["name"] = lff.Name.Original;
|
|
v["cat"] = "cmake";
|
|
v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(
|
|
std::chrono::steady_clock::now().time_since_epoch())
|
|
.count());
|
|
v["pid"] = static_cast<int>(info.GetProcessId());
|
|
v["tid"] = 0;
|
|
Json::Value argsValue;
|
|
if (!lff.Arguments.empty()) {
|
|
std::string args;
|
|
for (const auto& a : lff.Arguments) {
|
|
args += (args.empty() ? "" : " ") + a.Value;
|
|
}
|
|
argsValue["functionArgs"] = args;
|
|
}
|
|
argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
|
|
v["args"] = argsValue;
|
|
|
|
this->JsonWriter->write(v, &this->ProfileStream);
|
|
} catch (std::ios_base::failure& fail) {
|
|
cmSystemTools::Error(
|
|
cmStrCat("Failed to write to profiling output: ", fail.what()));
|
|
} catch (...) {
|
|
cmSystemTools::Error("Error writing profiling output!");
|
|
}
|
|
}
|
|
|
|
void cmMakefileProfilingData::StopEntry()
|
|
{
|
|
/* Do not try again if we previously failed to write to output. */
|
|
if (!this->ProfileStream.good()) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
this->ProfileStream << ",";
|
|
cmsys::SystemInformation info;
|
|
Json::Value v;
|
|
v["ph"] = "E";
|
|
v["ts"] = uint64_t(std::chrono::duration_cast<std::chrono::microseconds>(
|
|
std::chrono::steady_clock::now().time_since_epoch())
|
|
.count());
|
|
v["pid"] = static_cast<int>(info.GetProcessId());
|
|
v["tid"] = 0;
|
|
this->JsonWriter->write(v, &this->ProfileStream);
|
|
} catch (std::ios_base::failure& fail) {
|
|
cmSystemTools::Error(
|
|
cmStrCat("Failed to write to profiling output:", fail.what()));
|
|
} catch (...) {
|
|
cmSystemTools::Error("Error writing profiling output!");
|
|
}
|
|
}
|