mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-26 09:48:16 +00:00
instrumentation: Add compileTrace option
Adds support for optionally saving and reporting trace files generated by Clang's `-ftime-trace` option.
This commit is contained in:
@@ -76,7 +76,7 @@ equivalent JSON query file.
|
||||
API_VERSION 1
|
||||
DATA_VERSION 1.0
|
||||
HOOKS postGenerate preCMakeBuild postCMakeBuild
|
||||
OPTIONS staticSystemInformation dynamicSystemInformation trace
|
||||
OPTIONS staticSystemInformation dynamicSystemInformation compileTrace trace
|
||||
CALLBACK ${CMAKE_COMMAND} -P /path/to/handle_data.cmake
|
||||
CALLBACK ${CMAKE_COMMAND} -P /path/to/handle_data_2.cmake
|
||||
CUSTOM_CONTENT myString STRING string
|
||||
@@ -92,7 +92,7 @@ equivalent JSON query file.
|
||||
"postGenerate", "preCMakeBuild", "postCMakeBuild"
|
||||
],
|
||||
"options": [
|
||||
"staticSystemInformation", "dynamicSystemInformation", "trace"
|
||||
"staticSystemInformation", "dynamicSystemInformation", "compileTrace", "trace"
|
||||
],
|
||||
"callbacks": [
|
||||
"/path/to/cmake -P /path/to/handle_data.cmake",
|
||||
|
||||
@@ -211,6 +211,11 @@ subdirectories:
|
||||
trace file remains even after `Indexing`_ occurs and all `Callbacks`_ are
|
||||
executed, until the next time `Indexing`_ occurs.
|
||||
|
||||
``data/compile-trace/``
|
||||
A subset of the collected data, containing any trace files generated by
|
||||
the compiler, when the ``compileTrace`` `option <v1 Query Files_>`_ is
|
||||
enabled.
|
||||
|
||||
``cdash/``
|
||||
Holds temporary files used internally to generate XML content to be submitted
|
||||
to CDash.
|
||||
@@ -308,6 +313,16 @@ key is required, but all other fields are optional.
|
||||
|
||||
Only available as of data version ``1.1``.
|
||||
|
||||
``compileTrace``
|
||||
.. versionadded:: 4.4
|
||||
|
||||
Enables collection of JSON files generated by Clang's
|
||||
``-ftime-trace`` option. When such files are created for an
|
||||
instrumented compile command, they are copied into the instrumentation
|
||||
``data`` directory and referenced from the compile snippet.
|
||||
|
||||
Only available as of data version ``1.1``.
|
||||
|
||||
``cdashSubmit``
|
||||
Enables including instrumentation data in CDash. This is
|
||||
equivalent to having the :envvar:`CTEST_USE_INSTRUMENTATION` environment
|
||||
@@ -508,6 +523,16 @@ Snippet files have a filename with the syntax
|
||||
or ``Debug``. Only included when ``role`` is one of: ``compile``, ``link``,
|
||||
``custom``, ``install``, ``test``.
|
||||
|
||||
``traceFile``
|
||||
.. versionadded:: 4.4
|
||||
|
||||
A path, relative to the instrumentation ``data`` directory, referencing a
|
||||
copied JSON file generated by Clang's ``-ftime-trace`` option. Only
|
||||
included when the ``compileTrace`` `option
|
||||
<v1 Query Files_>`_ is enabled and ``role`` is
|
||||
``compile``. If no JSON file was produced by the compile command, this value
|
||||
is ``null``.
|
||||
|
||||
``dynamicSystemInformation``
|
||||
Specifies the dynamic information collected about the host machine
|
||||
CMake is being run from. Data is collected for every snippet file
|
||||
@@ -558,6 +583,7 @@ Example:
|
||||
"language" : "C++",
|
||||
"outputs" : [ "CMakeFiles/main.dir/main.cxx.o" ],
|
||||
"outputSizes" : [ 0 ],
|
||||
"traceFile" : "compile-trace/main.cxx-<hash>.json",
|
||||
"source" : "<src>/main.cxx",
|
||||
"config" : "Debug",
|
||||
"dynamicSystemInformation" :
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
"enum": [
|
||||
"staticSystemInformation",
|
||||
"dynamicSystemInformation",
|
||||
"compileTrace",
|
||||
"cdashSubmit",
|
||||
"cdashVerbose",
|
||||
"trace",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <cm/memory>
|
||||
#include <cm/optional>
|
||||
#include <cm/string_view>
|
||||
#include <cmext/algorithm>
|
||||
|
||||
#include <cm3p/json/reader.h>
|
||||
@@ -434,6 +435,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
|
||||
|
||||
// Delete old content and trace files
|
||||
this->RemoveOldFiles("content");
|
||||
this->RemoveOldFiles("compile-trace");
|
||||
this->RemoveOldFiles("trace");
|
||||
|
||||
this->indexLock.Release();
|
||||
@@ -651,6 +653,49 @@ int cmInstrumentation::InstrumentCommand(
|
||||
if (!command_str.empty()) {
|
||||
root["command"] = command_str;
|
||||
}
|
||||
root["role"] = command_type;
|
||||
root["workingDir"] = cmSystemTools::GetLogicalWorkingDirectory();
|
||||
|
||||
if (data.has_value()) {
|
||||
for (auto const& item : data.value()) {
|
||||
if (item.first == "role" && !item.second.empty()) {
|
||||
command_type = item.second;
|
||||
root["role"] = command_type;
|
||||
} else if (item.first == "showOnly") {
|
||||
root[item.first] = item.second == "1" ? true : false;
|
||||
} else if (!item.second.empty()) {
|
||||
root[item.first] = item.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arrayData.has_value()) {
|
||||
for (auto const& item : arrayData.value()) {
|
||||
root[item.first] = Json::arrayValue;
|
||||
std::stringstream ss(item.second);
|
||||
std::string element;
|
||||
while (getline(ss, element, ',')) {
|
||||
root[item.first].append(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create empty config entry if config not found
|
||||
if (!root.isMember("config") &&
|
||||
(command_type == "compile" || command_type == "link" ||
|
||||
command_type == "custom" || command_type == "install")) {
|
||||
root["config"] = "";
|
||||
}
|
||||
|
||||
// Check existing compile trace json to check for modifications
|
||||
std::string compileTraceFile;
|
||||
if (this->HasOption(cmInstrumentationQuery::Option::CompileTrace) &&
|
||||
command_type == "compile") {
|
||||
compileTraceFile = this->GetCompileTraceFile(
|
||||
command, root["outputs"], root["workingDir"].asString());
|
||||
}
|
||||
long int oldCompileTraceTimestamp = !compileTraceFile.empty() &&
|
||||
cmSystemTools::FileExists(compileTraceFile, true)
|
||||
? cmSystemTools::ModifiedTime(compileTraceFile)
|
||||
: -1;
|
||||
|
||||
// Pre-Command
|
||||
auto steady_start = std::chrono::steady_clock::now();
|
||||
@@ -699,52 +744,18 @@ int cmInstrumentation::InstrumentCommand(
|
||||
this->InsertDynamicSystemInformation(root, "after");
|
||||
}
|
||||
|
||||
// Gather additional data
|
||||
if (data.has_value()) {
|
||||
for (auto const& item : data.value()) {
|
||||
if (item.first == "role" && !item.second.empty()) {
|
||||
command_type = item.second;
|
||||
} else if (item.first == "showOnly") {
|
||||
root[item.first] = item.second == "1" ? true : false;
|
||||
} else if (!item.second.empty()) {
|
||||
root[item.first] = item.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See SpawnBuildDaemon(); this data is currently meaningless for build.
|
||||
root["result"] = command_type == "build" ? Json::nullValue : ret;
|
||||
|
||||
// Create empty config entry if config not found
|
||||
if (!root.isMember("config") &&
|
||||
(command_type == "compile" || command_type == "link" ||
|
||||
command_type == "custom" || command_type == "install")) {
|
||||
root["config"] = "";
|
||||
}
|
||||
|
||||
if (arrayData.has_value()) {
|
||||
for (auto const& item : arrayData.value()) {
|
||||
if (item.first == "targetLabels" && command_type != "link") {
|
||||
continue;
|
||||
}
|
||||
root[item.first] = Json::arrayValue;
|
||||
std::stringstream ss(item.second);
|
||||
std::string element;
|
||||
while (getline(ss, element, ',')) {
|
||||
root[item.first].append(element);
|
||||
}
|
||||
if (item.first == "outputs") {
|
||||
root["outputSizes"] = Json::arrayValue;
|
||||
for (auto const& output : root["outputs"]) {
|
||||
root["outputSizes"].append(
|
||||
static_cast<Json::Value::UInt64>(cmSystemTools::FileLength(
|
||||
cmStrCat(this->binaryDir, '/', output.asCString()))));
|
||||
}
|
||||
}
|
||||
// Output Sizes
|
||||
if (root.isMember("outputs")) {
|
||||
root["outputSizes"] = Json::arrayValue;
|
||||
for (auto const& output : root["outputs"]) {
|
||||
root["outputSizes"].append(
|
||||
static_cast<Json::Value::UInt64>(cmSystemTools::FileLength(
|
||||
cmStrCat(this->binaryDir, '/', output.asCString()))));
|
||||
}
|
||||
}
|
||||
root["role"] = command_type;
|
||||
root["workingDir"] = cmSystemTools::GetLogicalWorkingDirectory();
|
||||
|
||||
auto addCMakeContent = [this](Json::Value& root_) -> void {
|
||||
std::string contentFile =
|
||||
@@ -758,14 +769,25 @@ int cmInstrumentation::InstrumentCommand(
|
||||
addCMakeContent(root);
|
||||
}
|
||||
|
||||
// Write Json
|
||||
cmsys::SystemInformation& info = this->GetSystemInformation();
|
||||
// Compute file name properties
|
||||
std::chrono::system_clock::time_point endTime =
|
||||
system_start + std::chrono::milliseconds(root["duration"].asUInt64());
|
||||
std::string const& file_name = cmStrCat(
|
||||
command_type, '-',
|
||||
this->ComputeSuffixHash(cmStrCat(command_str, info.GetProcessId())), '-',
|
||||
this->ComputeSuffixTime(endTime), ".json");
|
||||
cmsys::SystemInformation& info = this->GetSystemInformation();
|
||||
std::string const commandHash =
|
||||
this->ComputeSuffixHash(cmStrCat(command_str, info.GetProcessId()));
|
||||
std::string const suffixTime = this->ComputeSuffixTime(endTime);
|
||||
|
||||
// Compile Trace
|
||||
if (this->HasOption(cmInstrumentationQuery::Option::CompileTrace) &&
|
||||
command_type == "compile") {
|
||||
this->CollectCompileTraceFile(root, compileTraceFile,
|
||||
oldCompileTraceTimestamp, commandHash,
|
||||
suffixTime);
|
||||
}
|
||||
|
||||
// Write JSON
|
||||
std::string const& file_name =
|
||||
cmStrCat(command_type, '-', commandHash, '-', suffixTime, ".json");
|
||||
|
||||
// Don't write configure snippet until generate time
|
||||
if (command_type == "configure") {
|
||||
@@ -1048,14 +1070,72 @@ void cmInstrumentation::PrepareDataForCDash(std::string const& data_dir,
|
||||
}
|
||||
|
||||
std::string dst = cmStrCat(dst_dir, '/', snippet_str);
|
||||
cmsys::Status copied = cmSystemTools::CopyFileAlways(snippet_path, dst);
|
||||
if (!copied) {
|
||||
if (!cmSystemTools::CopyFileAlways(snippet_path, dst)) {
|
||||
error_msg = cmStrCat("Failed to copy ", snippet_path, " to ", dst);
|
||||
cmSystemTools::Error(error_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmInstrumentation::GetCompileTraceFile(
|
||||
std::vector<std::string> const& command, Json::Value const& outputs,
|
||||
std::string const& workingDir)
|
||||
{
|
||||
cm::string_view const prefix = "-ftime-trace=";
|
||||
std::string traceFile;
|
||||
for (auto it = command.rbegin(); it != command.rend(); ++it) {
|
||||
std::string const& arg = *it;
|
||||
if (cmHasPrefix(arg, prefix)) {
|
||||
traceFile = arg.substr(prefix.size());
|
||||
}
|
||||
}
|
||||
if (traceFile.empty() && !outputs.empty()) {
|
||||
std::string outputPath = outputs[0].asString();
|
||||
cm::string_view ext =
|
||||
cmSystemTools::GetFilenameLastExtensionView(outputPath);
|
||||
if (!outputPath.empty() && !ext.empty()) {
|
||||
traceFile = cmStrCat(
|
||||
outputPath.substr(0, outputPath.size() - ext.size()), ".json");
|
||||
}
|
||||
}
|
||||
if (!cmSystemTools::FileIsFullPath(traceFile)) {
|
||||
traceFile = cmStrCat(workingDir, '/', traceFile);
|
||||
}
|
||||
|
||||
return traceFile;
|
||||
}
|
||||
|
||||
void cmInstrumentation::CollectCompileTraceFile(Json::Value& root,
|
||||
std::string traceFile,
|
||||
long int oldTimestamp,
|
||||
std::string const& commandHash,
|
||||
std::string const& suffixTime)
|
||||
{
|
||||
if (traceFile.empty()) {
|
||||
root["traceFile"] = Json::nullValue;
|
||||
return;
|
||||
}
|
||||
if (!cmSystemTools::FileExists(traceFile, true) ||
|
||||
cmSystemTools::ModifiedTime(traceFile) == oldTimestamp) {
|
||||
root["traceFile"] = Json::nullValue;
|
||||
return;
|
||||
}
|
||||
cm::string_view ext = cmSystemTools::GetFilenameLastExtensionView(traceFile);
|
||||
std::string candidateName = cmSystemTools::GetFilenameName(traceFile);
|
||||
std::string copiedName =
|
||||
cmStrCat(candidateName.substr(0, candidateName.size() - ext.size()), '-',
|
||||
commandHash, '-', suffixTime, ext);
|
||||
std::string const copiedFile = cmStrCat("compile-trace/", copiedName);
|
||||
std::string const destination = cmStrCat(this->dataDir, '/', copiedFile);
|
||||
cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(destination));
|
||||
if (!cmSystemTools::CopyFileAlways(traceFile, destination)) {
|
||||
cmSystemTools::Error(cmStrCat("Failed to copy compile trace file ",
|
||||
traceFile, " to ", destination));
|
||||
return;
|
||||
}
|
||||
root["traceFile"] = copiedFile;
|
||||
}
|
||||
|
||||
void cmInstrumentation::WriteTraceFile(Json::Value const& index,
|
||||
std::string const& trace_name)
|
||||
{
|
||||
|
||||
@@ -119,6 +119,14 @@ private:
|
||||
static bool IsInstrumentableTargetType(cmStateEnums::TargetType type);
|
||||
void PrepareDataForCDash(std::string const& data_dir,
|
||||
std::string const& index_path);
|
||||
static std::string GetCompileTraceFile(
|
||||
std::vector<std::string> const& command, Json::Value const& outputs,
|
||||
std::string const& workingDir);
|
||||
void CollectCompileTraceFile(Json::Value& root, std::string traceFile,
|
||||
long int oldTimestamp,
|
||||
std::string const& commandHash,
|
||||
std::string const& suffixTime);
|
||||
void RemoveCompileTraceFile(Json::Value const& snippetData);
|
||||
void RemoveOldFiles(std::string const& dataSubdir);
|
||||
void WriteTraceFile(Json::Value const& index, std::string const& trace_name);
|
||||
Json::Value BuildTraceEvent(std::vector<uint64_t>& workers,
|
||||
|
||||
@@ -18,6 +18,7 @@ std::vector<std::string> const cmInstrumentationQuery::OptionString{
|
||||
"staticSystemInformation",
|
||||
"dynamicSystemInformation",
|
||||
"captureOutput",
|
||||
"compileTrace",
|
||||
"cdashSubmit",
|
||||
"cdashVerbose",
|
||||
"trace"
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
StaticSystemInformation,
|
||||
DynamicSystemInformation,
|
||||
CaptureOutput,
|
||||
CompileTrace,
|
||||
CDashSubmit,
|
||||
CDashVerbose,
|
||||
Trace
|
||||
|
||||
@@ -440,6 +440,9 @@ add_RunCMake_test(FileAPI -DPython_EXECUTABLE=${Python_EXECUTABLE}
|
||||
-DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA})
|
||||
if(CMAKE_GENERATOR MATCHES "Make|Ninja|FASTBuild")
|
||||
add_RunCMake_test(Instrumentation -DPython_EXECUTABLE=${Python_EXECUTABLE}
|
||||
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}
|
||||
-DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA})
|
||||
endif()
|
||||
add_RunCMake_test(ConfigDir)
|
||||
|
||||
@@ -17,6 +17,8 @@ function(instrument test)
|
||||
"STATIC_QUERY"
|
||||
"DYNAMIC_QUERY"
|
||||
"CAPTURE_OUTPUT_QUERY"
|
||||
"COMPILE_TRACE_QUERY"
|
||||
"COMPILE_TRACE_QUERY_NULL"
|
||||
"TRACE_QUERY"
|
||||
"MANUAL_HOOK"
|
||||
"PRESERVE_DATA"
|
||||
@@ -25,7 +27,7 @@ function(instrument test)
|
||||
"FAIL"
|
||||
"BAD_QUERY"
|
||||
)
|
||||
cmake_parse_arguments(ARGS "${OPTIONS}" "CHECK_SCRIPT;CONFIGURE_ARG" "" ${ARGN})
|
||||
cmake_parse_arguments(ARGS "${OPTIONS}" "CHECK_SCRIPT" "CONFIGURE_ARGS" ${ARGN})
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test})
|
||||
set(v1 ${RunCMake_TEST_BINARY_DIR}/.cmake/instrumentation/v1)
|
||||
set(v1 ${v1} PARENT_SCOPE)
|
||||
@@ -56,6 +58,8 @@ function(instrument test)
|
||||
if (ARGS_TRACE_QUERY)
|
||||
set(trace_query_hook_arg 1)
|
||||
endif()
|
||||
set(ARGS_COMPILE_TRACE_QUERY ${ARGS_COMPILE_TRACE_QUERY} PARENT_SCOPE)
|
||||
set(ARGS_COMPILE_TRACE_QUERY_NULL ${ARGS_COMPILE_TRACE_QUERY_NULL} PARENT_SCOPE)
|
||||
set(GET_HOOK
|
||||
"\\\"${CMAKE_COMMAND}\\\""
|
||||
"-DSTATIC_QUERY=${static_query_hook_arg}"
|
||||
@@ -86,7 +90,7 @@ function(instrument test)
|
||||
set(cmake_file "${query_dir}/default.cmake")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND ARGS_CONFIGURE_ARG "-DINSTRUMENT_COMMAND_FILE=${cmake_file}")
|
||||
list(APPEND ARGS_CONFIGURE_ARGS "-DINSTRUMENT_COMMAND_FILE=${cmake_file}")
|
||||
endif()
|
||||
|
||||
set(copy_loc ${RunCMake_TEST_BINARY_DIR}/query)
|
||||
@@ -112,10 +116,10 @@ function(instrument test)
|
||||
# Configure Test Case
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
if (ARGS_FAIL)
|
||||
list(APPEND ARGS_CONFIGURE_ARG "-DFAIL=ON")
|
||||
list(APPEND ARGS_CONFIGURE_ARGS "-DFAIL=ON")
|
||||
endif()
|
||||
if (ARGS_DISABLE_TEST)
|
||||
list(APPEND ARGS_CONFIGURE_ARG "-DDISABLE_TEST=ON")
|
||||
list(APPEND ARGS_CONFIGURE_ARGS "-DDISABLE_TEST=ON")
|
||||
endif()
|
||||
set(RunCMake_TEST_SOURCE_DIR ${RunCMake_SOURCE_DIR}/project)
|
||||
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
@@ -141,7 +145,7 @@ function(instrument test)
|
||||
unset(RunCMake_QUIET_ERROR)
|
||||
endif()
|
||||
if (NOT ARGS_NO_CONFIGURE)
|
||||
run_cmake_with_options(${test} ${ARGS_CONFIGURE_ARG} ${maybe_CMAKE_BUILD_TYPE})
|
||||
run_cmake_with_options(${test} ${ARGS_CONFIGURE_ARGS} ${maybe_CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
# Follow-up Commands
|
||||
@@ -275,7 +279,7 @@ instrument(cmake-command-parallel-install
|
||||
BUILD INSTALL TEST INSTALL_PARALLEL DYNAMIC_QUERY
|
||||
CHECK_SCRIPT check-data-dir.cmake)
|
||||
instrument(cmake-command-initial-cache
|
||||
CONFIGURE_ARG "-C ${RunCMake_BINARY_DIR}/initial.cmake"
|
||||
CONFIGURE_ARGS "-C ${RunCMake_BINARY_DIR}/initial.cmake"
|
||||
)
|
||||
instrument(cmake-command-resets-generated
|
||||
COPY_QUERIES_GENERATED
|
||||
@@ -303,11 +307,11 @@ instrument(cmake-command-workflow
|
||||
# Test CUSTOM_CONTENT
|
||||
instrument(cmake-command-custom-content
|
||||
BUILD
|
||||
CONFIGURE_ARG "-DN=1"
|
||||
CONFIGURE_ARGS "-DN=1"
|
||||
)
|
||||
instrument(cmake-command-custom-content
|
||||
BUILD PRESERVE_DATA
|
||||
CONFIGURE_ARG "-DN=2"
|
||||
CONFIGURE_ARGS "-DN=2"
|
||||
CHECK_SCRIPT check-custom-content.cmake
|
||||
)
|
||||
set(indexDir ${v1}/data/index)
|
||||
@@ -352,6 +356,53 @@ instrument(cmake-command-capture-output
|
||||
CHECK_SCRIPT check-data-dir.cmake
|
||||
)
|
||||
|
||||
# Test compile trace collection
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||
if (CMAKE_C_COMPILER_VERSION VERSION_LESS 11.1)
|
||||
set(Skip_COMPILE_TRACE_QUERY_Case 1)
|
||||
elseif (CMAKE_C_COMPILER_VERSION VERSION_LESS 15)
|
||||
set(Skip_COMPILE_TRACE_QUERY_ARG_Case 1)
|
||||
endif()
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
if (CMAKE_C_COMPILER_VERSION VERSION_LESS 9)
|
||||
set(Skip_COMPILE_TRACE_QUERY_Case 1)
|
||||
elseif (CMAKE_C_COMPILER_VERSION VERSION_LESS 16)
|
||||
set(Skip_COMPILE_TRACE_QUERY_ARG_Case 1)
|
||||
endif()
|
||||
else()
|
||||
set(Skip_COMPILE_TRACE_QUERY_Case 1)
|
||||
endif()
|
||||
if("$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
|
||||
# `-ftime-trace` with multiple `-arch` puts the trace file in TMPDIR.
|
||||
set(Skip_COMPILE_TRACE_QUERY_Case 1)
|
||||
endif()
|
||||
if(RunCMake_GENERATOR MATCHES "NMake")
|
||||
# `-ftime-trace=` is hidden by `@<< ... <<` response file syntax.
|
||||
set(Skip_COMPILE_TRACE_QUERY_ARG_Case 1)
|
||||
endif()
|
||||
if (NOT Skip_COMPILE_TRACE_QUERY_Case)
|
||||
instrument(cmake-command-compile-trace
|
||||
BUILD COMPILE_TRACE_QUERY
|
||||
CONFIGURE_ARGS
|
||||
"-DINSTRUMENT_COMPILE_TRACE=DEFAULT"
|
||||
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
|
||||
CHECK_SCRIPT check-data-dir.cmake
|
||||
)
|
||||
instrument(cmake-command-compile-trace-null
|
||||
BUILD COMPILE_TRACE_QUERY_NULL
|
||||
CHECK_SCRIPT check-data-dir.cmake
|
||||
)
|
||||
if (NOT Skip_COMPILE_TRACE_QUERY_ARG_Case)
|
||||
instrument(cmake-command-compile-trace-explicit
|
||||
BUILD COMPILE_TRACE_QUERY
|
||||
CONFIGURE_ARGS
|
||||
"-DINSTRUMENT_COMPILE_TRACE=EXPLICIT"
|
||||
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
|
||||
CHECK_SCRIPT check-data-dir.cmake
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Test make/ninja hooks
|
||||
if(RunCMake_GENERATOR STREQUAL "FASTBuild")
|
||||
# FIXME(#27184): This does not work for FASTBuild.
|
||||
|
||||
@@ -73,6 +73,20 @@ foreach(snippet IN LISTS snippets)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
if (ARGS_COMPILE_TRACE_QUERY)
|
||||
json_has_key("${snippet}" "${contents}" traceFile)
|
||||
string(JSON jsonFile GET "${contents}" traceFile)
|
||||
if (NOT EXISTS "${v1}/data/${jsonFile}" OR IS_DIRECTORY "${v1}/data/${jsonFile}")
|
||||
json_error("${snippet}" "Missing copied compile JSON file: ${jsonFile}")
|
||||
else()
|
||||
read_json("${v1}/data/${jsonFile}" trace_contents)
|
||||
json_has_key("${v1}/data/${jsonFile}" "${trace_contents}" traceEvents)
|
||||
endif()
|
||||
elseif (ARGS_COMPILE_TRACE_QUERY_NULL)
|
||||
json_assert_key("${snippet}" "${contents}" traceFile null)
|
||||
else()
|
||||
json_missing_key("${snippet}" "${contents}" traceFile)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Verify contents of link-* Snippets
|
||||
|
||||
@@ -8,6 +8,15 @@ endif()
|
||||
add_executable(main main.c)
|
||||
add_library(lib lib.c)
|
||||
target_link_libraries(main lib)
|
||||
|
||||
if (INSTRUMENT_COMPILE_TRACE STREQUAL "DEFAULT")
|
||||
target_compile_options(main PRIVATE "-ftime-trace")
|
||||
target_compile_options(lib PRIVATE "-ftime-trace")
|
||||
elseif (INSTRUMENT_COMPILE_TRACE STREQUAL "EXPLICIT")
|
||||
target_compile_options(main PRIVATE "-ftime-trace=main.json")
|
||||
target_compile_options(lib PRIVATE "-ftime-trace=lib.json")
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET main POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E true
|
||||
)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_instrumentation(
|
||||
API_VERSION 1
|
||||
DATA_VERSION 1
|
||||
OPTIONS compileTrace
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_instrumentation(
|
||||
API_VERSION 1
|
||||
DATA_VERSION 1
|
||||
OPTIONS compileTrace
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_instrumentation(
|
||||
API_VERSION 1
|
||||
DATA_VERSION 1
|
||||
OPTIONS compileTrace
|
||||
)
|
||||
Reference in New Issue
Block a user