/* 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 #include #include #include #include #include "cmsys/FStream.hxx" #include "cmsys/SystemInformation.hxx" #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(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.Lower; v["cat"] = "cmake"; v["ts"] = Json::Value::UInt64( std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()) .count()); v["pid"] = static_cast(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"] = Json::Value::UInt64( std::chrono::duration_cast( std::chrono::steady_clock::now().time_since_epoch()) .count()); v["pid"] = static_cast(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!"); } }