instrumentation: Move target data into content files

Create a single place to store target data to prevent duplication.
This moves `targetType` and `targetLabels` out of the snippet files
and into a target map in the `cmakeContent` file referenced by each
snippet.

Fixes: #27244
This commit is contained in:
Martin Duffy
2025-09-25 15:37:02 -04:00
parent bef873755b
commit 97adbc91fa
20 changed files with 216 additions and 193 deletions

View File

@@ -37,15 +37,14 @@ Whenever ``cmake_instrumentation`` is invoked, a query file is generated in
``<build>/.cmake/instrumentation/v1/query/generated`` to enable instrumentation
with the provided arguments.
.. _`cmake_instrumentation Configure Content`:
.. _`cmake_instrumentation CUSTOM_CONTENT`:
Custom Configure Content
^^^^^^^^^^^^^^^^^^^^^^^^
Custom CMake Content
^^^^^^^^^^^^^^^^^^^^
The ``CUSTOM_CONTENT`` argument specifies certain data from configure time to
include in each :ref:`cmake-instrumentation v1 Snippet File` that
corresponds to the configure step associated with the command. This may be used
to associate instrumentation data with certain information about its
include in each :ref:`cmake-instrumentation v1 CMake Content File`. This
may be used to associate instrumentation data with certain information about its
configuration, such as the optimization level or whether it is part of a
coverage build.
@@ -102,12 +101,12 @@ equivalent JSON query file.
]
}
This will also result in a configure content JSON being reported in each
:ref:`cmake-instrumentation v1 Snippet File` with the following contents:
This will also result in the following content included in each
:ref:`cmake-instrumentation v1 CMake Content File`:
.. code-block:: json
{
"custom": {
"myString": "string",
"myList": [
"item1", "item2"

View File

@@ -127,6 +127,10 @@ by setting :envvar:`CTEST_USE_VERBOSE_INSTRUMENTATION` to 1.
Alternatively, you can use the `v1 Query Files`_ to enable instrumentation for
CDash using the ``cdashSubmit`` and ``cdashVerbose`` options.
In order for the submitted ``Build.xml`` file to group the snippet files
correctly, all configure and build commands should be executed with CTest in
Dashboard Client mode.
.. _`cmake-instrumentation API v1`:
API v1
@@ -164,7 +168,7 @@ subdirectories:
``data/content/``
A subset of the collected data, containing any
:ref:`cmake_instrumentation Configure Content` files.
`v1 CMake Content Files <v1 CMake Content File_>`_.
``data/trace/``
A subset of the collected data, containing the `Google Trace File`_ created
@@ -302,9 +306,9 @@ Data version specifies the contents of the output files generated by the CMake
instrumentation API as part of the `Data Collection`_ and `Indexing`_. A new
version number will be created whenever previously included data is removed or
reformatted such that scripts written to parse this data may become
incompatible with the new format. There are three types of data files generated:
the `v1 Snippet File`_, the `v1 Index File`_, and the `Google Trace File`_.
When using the `API v1`_, these files live in
incompatible with the new format. There are four types of data files generated:
the `v1 Snippet File`_, `v1 Index File`_, `v1 CMake Content File`_, and the
`Google Trace File`_. When using the `API v1`_, these files live in
``<build>/.cmake/instrumentation/v1/data/`` under the project build tree.
.. _`cmake-instrumentation v1 Snippet File`:
@@ -359,17 +363,9 @@ and contain the following data:
* ``test``: a single test executed by CTest
``target``
The CMake target associated with the command. Included when ``role`` is
``compile``, or ``link``, and when ``role`` is ``custom`` and the custom
command is attached to a target with :ref:`add_custom_command(TARGET)`.
``targetType``
The :prop_tgt:`TYPE` of the target. Only included when ``role`` is
``link``.
``targetLabels``
The :prop_tgt:`LABELS` of the target. Only included when ``role`` is
``link``.
The CMake target associated with the command. Only included when ``role`` is
``compile`` or ``link``. In conjunction with ``cmakeContent``, this can
be used to look up the target type and labels.
``timeStart``
Time at which the command started, expressed as the number of milliseconds
@@ -422,10 +418,10 @@ and contain the following data:
The Average CPU Load at ``timeStart + duration``, or ``null`` if it cannot
be determined.
``configureContent``
The path to a :ref:`cmake_instrumentation Configure Content` file located
under ``data``, which may contain information about the CMake configure
step corresponding to this data.
``cmakeContent``
The path to a `v1 CMake Content` file located under ``data``, which
contains information about the CMake configure and generate steps
responsible for generating the ``command`` in this snippet.
Example:
@@ -451,7 +447,7 @@ Example:
},
"timeStart" : 1737053448177,
"duration" : 31,
"configureContent" : "content/configure-2025-07-11T12-46-32-0572.json"
"cmakeContent" : "content/cmake-2025-07-11T12-46-32-0572.json"
}
v1 Index File
@@ -534,6 +530,33 @@ Example:
"trace": "trace/trace-<timestamp>.json"
}
.. _`cmake-instrumentation v1 CMake Content File`:
v1 CMake Content File
---------------------
CMake content files contain information about the CMake configure and generate
steps. Each `v1 Snippet File`_ provides the path to one of these files
corresponding to the CMake invocation responsible for generating its command.
Each CMake content file contains the following:
``custom``
An object containing arbitrary JSON data specified by the user with the
:ref:`cmake_instrumentation CUSTOM_CONTENT` functionality of the
:command:`cmake_instrumentation` command.
``targets``
An object containing CMake targets, indexed by name, that have corresponding
instrumentation data. Each target contains the following:
``type``
The target type. One of ``EXECUTABLE``, ``STATIC_LIBRARY``,
``SHARED_LIBRARY`` or ``OBJECT_LIBRARY``.
``labels``
The :prop_tgt:`LABELS` property of the target.
Google Trace File
-----------------

View File

@@ -626,48 +626,38 @@ void cmCTestBuildHandler::GenerateInstrumentationXML(cmXMLWriter& xml)
xml.StartElement("Target");
xml.Attribute("name", target_name);
// Check if we have a link snippet for this target.
cmsys::Directory target_dir;
if (!target_dir.Load(targets_dir.GetFilePath(i))) {
cmSystemTools::Error(
cmStrCat("Error loading directory ", targets_dir.GetFilePath(i)));
}
Json::Value link_item;
for (unsigned int j = 0; j < target_dir.GetNumberOfFiles(); j++) {
std::string fname = target_dir.GetFile(j);
if (fname.rfind("link-", 0) == 0) {
std::string fpath = target_dir.GetFilePath(j);
cmJSONState parseState = cmJSONState(fpath, &link_item);
if (!parseState.errors.empty()) {
cmSystemTools::Error(parseState.GetErrorMessage(true));
break;
}
if (!link_item.isObject()) {
std::string error_msg =
cmStrCat("Expected snippet ", fpath, " to contain an object");
cmSystemTools::Error(error_msg);
break;
}
// Load latest CMake content file
Json::Value target_data;
std::string cmake_content_file =
cmStrCat(CTest->GetInstrumentation().GetDataDir(), "/content/",
this->CTest->GetInstrumentation().GetFileByTimestamp(
cmInstrumentation::LatestOrOldest::Latest, "content"));
if (!cmake_content_file.empty() &&
cmSystemTools::FileExists(cmake_content_file)) {
Json::Value cmake_content;
cmJSONState parseState =
cmJSONState(cmake_content_file, &cmake_content);
if (!parseState.errors.empty()) {
cmSystemTools::Error(parseState.GetErrorMessage(true));
break;
}
}
// If so, parse targetType and targetLabels (optional) from it.
if (link_item.isMember("targetType")) {
target_type = link_item["targetType"].asString();
}
xml.Attribute("type", target_type);
if (link_item.isMember("targetLabels") &&
!link_item["targetLabels"].empty()) {
xml.StartElement("Labels");
for (auto const& json_label_item : link_item["targetLabels"]) {
xml.Element("Label", json_label_item.asString());
if (cmake_content.isMember("targets")) {
target_data = cmake_content["targets"];
}
xml.EndElement(); // Labels
}
// Extract targetType and targetLabels
if (target_data.isObject() && target_data.isMember(target_name)) {
target_type = target_data[target_name]["type"].asString();
if (!target_data[target_name]["labels"].empty()) {
xml.StartElement("Labels");
for (auto const& json_label_item :
target_data[target_name]["labels"]) {
xml.Element("Label", json_label_item.asString());
}
xml.EndElement(); // Labels
}
}
xml.Attribute("type", target_type);
// Write instrumendation data for this target.
std::string target_subdir = cmStrCat("build/targets/", target_name);

View File

@@ -257,8 +257,6 @@ bool cmFastbuildNormalTargetGenerator::DetectBaseLinkerCommand(
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
vars.CMTargetLabels =
this->GetGeneratorTarget()->GetTargetLabelsString().c_str();
vars.Config = Config.c_str();
vars.Language = linkLanguage.c_str();
std::string const manifests =
@@ -1133,8 +1131,6 @@ cmFastbuildNormalTargetGenerator::ComputeRuleVariables() const
compileObjectVars.CMTargetName = GeneratorTarget->GetName().c_str();
compileObjectVars.CMTargetType =
cmState::GetTargetTypeName(GeneratorTarget->GetType()).c_str();
compileObjectVars.CMTargetLabels =
this->GetGeneratorTarget()->GetTargetLabelsString().c_str();
compileObjectVars.Source = FASTBUILD_1_INPUT_PLACEHOLDER;
compileObjectVars.Object = FASTBUILD_2_INPUT_PLACEHOLDER;
compileObjectVars.ObjectDir =

View File

@@ -2095,14 +2095,6 @@ std::vector<std::string> cmGeneratorTarget::GetAppleArchs(
return std::move(archList.data());
}
std::string const& cmGeneratorTarget::GetTargetLabelsString()
{
this->targetLabelsString = this->GetSafeProperty("LABELS");
std::replace(this->targetLabelsString.begin(),
this->targetLabelsString.end(), ';', ',');
return this->targetLabelsString;
}
namespace {
bool IsSupportedClassifiedFlagsLanguage(std::string const& lang)
@@ -2367,7 +2359,6 @@ cmGeneratorTarget::GetClassifiedFlagsForSource(cmSourceFile const* sf,
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetName().c_str();
vars.CMTargetType = cmState::GetTargetTypeName(this->GetType()).c_str();
vars.CMTargetLabels = this->GetTargetLabelsString().c_str();
vars.Language = lang.c_str();
auto const sfPath = this->LocalGenerator->ConvertToOutputFormat(

View File

@@ -535,8 +535,6 @@ public:
std::vector<std::string> GetAppleArchs(std::string const& config,
cm::optional<std::string> lang) const;
std::string const& GetTargetLabelsString();
// The classification of the flag.
enum class FlagClassification
{

View File

@@ -11,6 +11,7 @@
#include <cm/memory>
#include <cm/optional>
#include <cmext/algorithm>
#include <cm3p/json/reader.h>
#include <cm3p/json/version.h>
@@ -27,8 +28,13 @@
#include "cmExperimental.h"
#include "cmFileLock.h"
#include "cmFileLockResult.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmInstrumentationQuery.h"
#include "cmJSONState.h"
#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
@@ -94,6 +100,7 @@ cmInstrumentation::cmInstrumentation(std::string const& binary_dir,
this->timingDirv1 =
cmStrCat(this->binaryDir, "/.cmake/instrumentation-", uuid, "/v1");
this->cdashDir = cmStrCat(this->timingDirv1, "/cdash");
this->dataDir = cmStrCat(this->timingDirv1, "/data");
if (cm::optional<std::string> configDir =
cmSystemTools::GetCMakeConfigDirectory()) {
this->userTimingDirv1 =
@@ -221,20 +228,45 @@ void cmInstrumentation::AddCustomContent(std::string const& name,
this->customContent[name] = contents;
}
void cmInstrumentation::WriteCustomContent()
void cmInstrumentation::WriteCMakeContent(
std::unique_ptr<cmGlobalGenerator> const& gg)
{
if (!this->customContent.isNull()) {
this->WriteInstrumentationJson(
this->customContent, "data/content",
cmStrCat("configure-", this->ComputeSuffixTime(), ".json"));
Json::Value root;
root["targets"] = this->DumpTargets(gg);
root["custom"] = this->customContent;
this->WriteInstrumentationJson(
root, "data/content",
cmStrCat("cmake-", this->ComputeSuffixTime(), ".json"));
}
Json::Value cmInstrumentation::DumpTargets(
std::unique_ptr<cmGlobalGenerator> const& gg)
{
Json::Value targets = Json::objectValue;
std::vector<cmGeneratorTarget*> targetList;
for (auto const& lg : gg->GetLocalGenerators()) {
cm::append(targetList, lg->GetGeneratorTargets());
}
for (cmGeneratorTarget* gt : targetList) {
if (this->IsInstrumentableTargetType(gt->GetType())) {
Json::Value target = Json::objectValue;
auto labels = gt->GetSafeProperty("LABELS");
target["labels"] = Json::arrayValue;
for (auto const& item : cmList(labels)) {
target["labels"].append(item);
}
target["type"] = cmState::GetTargetTypeName(gt->GetType()).c_str();
targets[gt->GetName()] = target;
}
}
return targets;
}
std::string cmInstrumentation::GetFileByTimestamp(
cmInstrumentation::LatestOrOldest order, std::string const& dataSubdir,
std::string const& exclude)
{
std::string fullDir = cmStrCat(this->timingDirv1, "/data/", dataSubdir);
std::string fullDir = cmStrCat(this->dataDir, '/', dataSubdir);
std::string result;
if (cmSystemTools::FileExists(fullDir)) {
cmsys::Directory d;
@@ -255,12 +287,11 @@ std::string cmInstrumentation::GetFileByTimestamp(
void cmInstrumentation::RemoveOldFiles(std::string const& dataSubdir)
{
std::string const dataSubdirPath =
cmStrCat(this->timingDirv1, "/data/", dataSubdir);
std::string const dataSubdirPath = cmStrCat(this->dataDir, '/', dataSubdir);
std::string oldIndex =
this->GetFileByTimestamp(LatestOrOldest::Oldest, "index");
if (!oldIndex.empty()) {
oldIndex = cmStrCat(this->timingDirv1, "/data/index/", oldIndex);
oldIndex = cmStrCat(this->dataDir, "/index/", oldIndex);
}
if (cmSystemTools::FileExists(dataSubdirPath)) {
std::string latestFile =
@@ -316,10 +347,9 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
}
// Touch index file immediately to claim snippets
std::string const& directory = cmStrCat(this->timingDirv1, "/data");
std::string suffix_time = ComputeSuffixTime();
std::string const& index_name = cmStrCat("index-", suffix_time, ".json");
std::string index_path = cmStrCat(directory, "/index/", index_name);
std::string index_path = cmStrCat(this->dataDir, "/index/", index_name);
cmSystemTools::Touch(index_path, true);
// Gather Snippets
@@ -328,7 +358,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
cmsys::Directory d;
std::string last_index_name =
this->GetFileByTimestamp(LatestOrOldest::Latest, "index", index_name);
if (d.Load(directory)) {
if (d.Load(this->dataDir)) {
for (unsigned int i = 0; i < d.GetNumberOfFiles(); i++) {
std::string fpath = d.GetFilePath(i);
std::string fname = d.GetFile(i);
@@ -343,7 +373,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
Json::Value index(Json::objectValue);
index["snippets"] = Json::arrayValue;
index["hook"] = cmInstrumentationQuery::HookString[hook];
index["dataDir"] = directory;
index["dataDir"] = this->dataDir;
index["buildDir"] = this->binaryDir;
index["version"] = 1;
if (this->HasOption(
@@ -356,7 +386,7 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
} else {
int compare;
std::string last_index_path =
cmStrCat(directory, "/index/", last_index_name);
cmStrCat(this->dataDir, "/index/", last_index_name);
cmSystemTools::FileTimeCompare(file.second, last_index_path, &compare);
if (compare == 1) {
index["snippets"].append(file.first);
@@ -383,12 +413,12 @@ int cmInstrumentation::CollectTimingData(cmInstrumentationQuery::Hook hook)
// Special case for CDash collation
if (this->HasOption(cmInstrumentationQuery::Option::CDashSubmit)) {
this->PrepareDataForCDash(directory, index_path);
this->PrepareDataForCDash(this->dataDir, index_path);
}
// Delete files
for (auto const& f : index["snippets"]) {
cmSystemTools::RemoveFile(cmStrCat(directory, '/', f.asString()));
cmSystemTools::RemoveFile(cmStrCat(this->dataDir, '/', f.asString()));
}
cmSystemTools::RemoveFile(index_path);
@@ -605,11 +635,6 @@ int cmInstrumentation::InstrumentCommand(
int ret = callback();
root["result"] = ret;
// Write configure content if command was configure
if (command_type == "configure") {
this->WriteCustomContent();
}
// Exit early if configure didn't generate a query
if (reloadQueriesAfterCommand == LoadQueriesAfter::Yes) {
this->LoadQueries();
@@ -675,11 +700,16 @@ int cmInstrumentation::InstrumentCommand(
root["role"] = command_type;
root["workingDir"] = cmSystemTools::GetLogicalWorkingDirectory();
// Add custom configure content
std::string contentFile =
this->GetFileByTimestamp(LatestOrOldest::Latest, "content");
if (!contentFile.empty()) {
root["configureContent"] = cmStrCat("content/", contentFile);
auto addCMakeContent = [this](Json::Value& root_) -> void {
std::string contentFile =
this->GetFileByTimestamp(LatestOrOldest::Latest, "content");
if (!contentFile.empty()) {
root_["cmakeContent"] = cmStrCat("content/", contentFile);
}
};
// Don't insert path to CMake content until generate time
if (command_type != "configure") {
addCMakeContent(root);
}
// Write Json
@@ -690,7 +720,21 @@ int cmInstrumentation::InstrumentCommand(
command_type, '-',
this->ComputeSuffixHash(cmStrCat(command_str, info.GetProcessId())), '-',
this->ComputeSuffixTime(endTime), ".json");
this->WriteInstrumentationJson(root, "data", file_name);
// Don't write configure snippet until generate time
if (command_type == "configure") {
this->configureSnippetData = root;
this->configureSnippetName = file_name;
} else {
// Add reference to CMake content and write out configure snippet after
// generate
if (command_type == "generate") {
addCMakeContent(this->configureSnippetData);
this->WriteInstrumentationJson(this->configureSnippetData, "data",
this->configureSnippetName);
}
this->WriteInstrumentationJson(root, "data", file_name);
}
return ret;
}
@@ -736,6 +780,15 @@ std::string cmInstrumentation::ComputeSuffixTime(
return ss.str();
}
bool cmInstrumentation::IsInstrumentableTargetType(
cmStateEnums::TargetType type)
{
return type == cmStateEnums::TargetType::EXECUTABLE ||
type == cmStateEnums::TargetType::SHARED_LIBRARY ||
type == cmStateEnums::TargetType::STATIC_LIBRARY ||
type == cmStateEnums::TargetType::OBJECT_LIBRARY;
}
/*
* Called by ctest --start-instrumentation.
*
@@ -818,11 +871,16 @@ void cmInstrumentation::AddOption(cmInstrumentationQuery::Option option)
this->options.insert(option);
}
std::string const& cmInstrumentation::GetCDashDir()
std::string const& cmInstrumentation::GetCDashDir() const
{
return this->cdashDir;
}
std::string const& cmInstrumentation::GetDataDir() const
{
return this->dataDir;
}
/** Copy the snippets referred to by an index file to a separate
* directory where they will be parsed for submission to CDash.
**/

View File

@@ -17,13 +17,16 @@
#include <cm3p/json/value.h>
#include <stddef.h>
#include "cmFileLock.h"
#ifndef CMAKE_BOOTSTRAP
# include <cmsys/SystemInformation.hxx>
#endif
#include <stdint.h>
#include "cmFileLock.h"
#include "cmInstrumentationQuery.h"
#include "cmStateTypes.h"
class cmGlobalGenerator;
class cmInstrumentation
{
@@ -61,7 +64,8 @@ public:
std::set<cmInstrumentationQuery::Hook> const& hooks,
std::vector<std::vector<std::string>> const& callback);
void AddCustomContent(std::string const& name, Json::Value const& contents);
void WriteCustomContent();
void WriteCMakeContent(std::unique_ptr<cmGlobalGenerator> const& gg);
Json::Value DumpTargets(std::unique_ptr<cmGlobalGenerator> const& gg);
void ClearGeneratedQueries();
int CollectTimingData(cmInstrumentationQuery::Hook hook);
int SpawnBuildDaemon();
@@ -70,7 +74,16 @@ public:
void AddHook(cmInstrumentationQuery::Hook hook);
void AddOption(cmInstrumentationQuery::Option option);
bool HasErrors() const;
std::string const& GetCDashDir();
std::string const& GetCDashDir() const;
std::string const& GetDataDir() const;
enum LatestOrOldest
{
Latest,
Oldest
};
std::string GetFileByTimestamp(LatestOrOldest latestOrOldest,
std::string const& dataSubdir,
std::string const& exclude = "");
private:
Json::Value ReadJsonSnippet(std::string const& file_name);
@@ -89,6 +102,7 @@ private:
static std::string ComputeSuffixHash(std::string const& command_str);
static std::string ComputeSuffixTime(
cm::optional<std::chrono::system_clock::time_point> time = cm::nullopt);
static bool IsInstrumentableTargetType(cmStateEnums::TargetType type);
void PrepareDataForCDash(std::string const& data_dir,
std::string const& index_path);
void RemoveOldFiles(std::string const& dataSubdir);
@@ -97,18 +111,11 @@ private:
Json::Value const& snippetData);
size_t AssignTargetToTraceThread(std::vector<uint64_t>& workers,
uint64_t timeStart, uint64_t duration);
enum LatestOrOldest
{
Latest,
Oldest
};
std::string GetFileByTimestamp(LatestOrOldest latestOrOldest,
std::string const& dataSubdir,
std::string const& exclude = "");
std::string binaryDir;
std::string timingDirv1;
std::string userTimingDirv1;
std::string cdashDir;
std::string dataDir;
std::set<cmInstrumentationQuery::Option> options;
std::set<cmInstrumentationQuery::Hook> hooks;
std::vector<std::string> callbacks;
@@ -120,6 +127,8 @@ private:
bool ranSystemChecks = false;
bool ranOSCheck = false;
Json::Value customContent;
Json::Value configureSnippetData;
std::string configureSnippetName;
#ifndef CMAKE_BOOTSTRAP
std::unique_ptr<cmsys::SystemInformation> systemInformation;
cmsys::SystemInformation& GetSystemInformation();

View File

@@ -1055,7 +1055,6 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
vars.CMTargetName = target->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(target->GetType()).c_str();
vars.CMTargetLabels = target->GetTargetLabelsString().c_str();
std::string output;
std::vector<std::string> const& outputs = ccg.GetOutputs();
for (size_t i = 0; i < outputs.size(); ++i) {

View File

@@ -545,8 +545,6 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.CMTargetLabels =
this->GeneratorTarget->GetTargetLabelsString().c_str();
vars.Language = linkLanguage.c_str();
vars.Linker = linker.c_str();
vars.AIXExports = aixExports.c_str();

View File

@@ -792,8 +792,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.CMTargetLabels =
this->GeneratorTarget->GetTargetLabelsString().c_str();
vars.Language = linkLanguage.c_str();
vars.Linker = linker.c_str();
vars.AIXExports = aixExports.c_str();

View File

@@ -932,7 +932,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.CMTargetLabels = this->GeneratorTarget->GetTargetLabelsString().c_str();
vars.Language = lang.c_str();
vars.Target = targetOutPathReal.c_str();
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -1713,7 +1712,6 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str();
vars.CMTargetLabels = this->GeneratorTarget->GetTargetLabelsString().c_str();
vars.Language = "CUDA";
vars.Object = output.c_str();
vars.Fatbinary = fatbinaryOutput.c_str();

View File

@@ -294,9 +294,6 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
vars.CMTargetType =
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
.c_str();
vars.CMTargetLabels =
this->GetGeneratorTarget()->GetTargetLabelsString().c_str();
vars.Language = "CUDA";
std::string linker =
this->GetGeneratorTarget()->GetLinkerTool("CUDA", config);
@@ -404,9 +401,6 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str();
vars.CMTargetLabels =
this->GetGeneratorTarget()->GetTargetLabelsString().c_str();
vars.Language = "CUDA";
vars.Object = "$out";
vars.Fatbinary = "$FATBIN";
@@ -466,9 +460,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
vars.CMTargetLabels =
this->GetGeneratorTarget()->GetTargetLabelsString().c_str();
std::string linker = this->GetGeneratorTarget()->GetLinkerTool(config);
vars.Linker = linker.c_str();
std::string lang = this->TargetLinkLanguage(config);

View File

@@ -596,7 +596,6 @@ cmNinjaRule GetScanRule(
cmRulePlaceholderExpander::RuleVariables scanVars;
scanVars.CMTargetName = vars.CMTargetName;
scanVars.CMTargetType = vars.CMTargetType;
scanVars.CMTargetLabels = vars.CMTargetLabels;
scanVars.Language = vars.Language;
scanVars.Object = "$OBJ_FILE";
scanVars.PreprocessedSource = ppFileName.c_str();
@@ -656,8 +655,6 @@ void cmNinjaTargetGenerator::WriteCompileRule(std::string const& lang,
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str();
vars.CMTargetLabels =
this->GetGeneratorTarget()->GetTargetLabelsString().c_str();
vars.Language = lang.c_str();
vars.Source = "$in";
vars.Object = "$out";

View File

@@ -266,13 +266,6 @@ std::string cmRulePlaceholderExpander::ExpandVariable(
return this->ReplaceValues->CMTargetType;
}
}
if (variable == "TARGET_LABELS") {
if (this->ReplaceValues->CMTargetLabels) {
return this->ReplaceValues->CMTargetLabels;
}
return "";
}
if (this->ReplaceValues->Output) {
if (variable == "OUTPUT") {
return this->ReplaceValues->Output;

View File

@@ -32,7 +32,6 @@ public:
{
char const* CMTargetName = nullptr;
char const* CMTargetType = nullptr;
char const* CMTargetLabels = nullptr;
char const* TargetPDB = nullptr;
char const* TargetCompilePDB = nullptr;
char const* TargetVersionMajor = nullptr;

View File

@@ -2761,8 +2761,7 @@ int cmake::ActualConfigure()
"RULE_LAUNCH_LINK",
cmStrCat(
launcher, "--command-type link", common_args,
"--output <TARGET> --target-type <TARGET_TYPE> "
"--language <LANGUAGE> --target-labels \"<TARGET_LABELS>\" -- "));
"--output <TARGET> --config <CONFIG> --language <LANGUAGE> -- "));
this->State->SetGlobalProperty(
"RULE_LAUNCH_CUSTOM",
cmStrCat(launcher, "--command-type custom", common_args,
@@ -3116,6 +3115,9 @@ int cmake::Generate()
return -1;
}
this->GlobalGenerator->Generate();
if (this->Instrumentation->HasQuery()) {
this->Instrumentation->WriteCMakeContent(this->GlobalGenerator);
}
return 0;
};

View File

@@ -10,25 +10,39 @@ if (NOT ${num} EQUAL 2)
add_error("Found ${num} custom content files, expected 2.")
endif()
# Check contents of configureContent files
# Check contents of cmakeContent files
set(firstFile "")
foreach(content_file IN LISTS content_files)
read_json("${content_file}" contents)
json_assert_key("${content_file}" "${contents}" myString "string")
json_assert_key("${content_file}" "${contents}" myBool "OFF")
json_assert_key("${content_file}" "${contents}" myInt "1")
json_assert_key("${content_file}" "${contents}" myFloat "2.5")
json_assert_key("${content_file}" "${contents}" myTrue "ON")
json_assert_key("${content_file}" "${contents}" myList "[ \"a\", \"b\", \"c\" ]")
json_assert_key("${content_file}" "${contents}" myObject "{.*\"key\".*:.*\"value\".*}")
# Check custom content
string(JSON custom GET "${contents}" custom)
json_assert_key("${content_file}" "${custom}" myString "string")
json_assert_key("${content_file}" "${custom}" myBool "OFF")
json_assert_key("${content_file}" "${custom}" myInt "1")
json_assert_key("${content_file}" "${custom}" myFloat "2.5")
json_assert_key("${content_file}" "${custom}" myTrue "ON")
json_assert_key("${content_file}" "${custom}" myList "\\[ \"a\", \"b\", \"c\" \\]")
json_assert_key("${content_file}" "${custom}" myObject "{.*\"key\".*:.*\"value\".*}")
if (NOT firstFile)
set(firstFile "${content_file}")
endif()
if ("${content_file}" STREQUAL "${firstFile}")
string(JSON firstN GET "${contents}" nConfigure)
string(JSON firstN GET "${custom}" nConfigure)
else()
string(JSON secondN GET "${contents}" nConfigure)
string(JSON secondN GET "${custom}" nConfigure)
endif()
# Check target content
string(JSON targets GET "${contents}" targets)
string(JSON targetData GET "${targets}" lib)
json_assert_key("${content_file}" "${targetData}" labels "\\[ \"label3\" \\]")
json_assert_key("${content_file}" "${targetData}" type "STATIC_LIBRARY")
string(JSON targetData GET "${targets}" main)
json_assert_key("${content_file}" "${targetData}" labels "\\[ \"label1\", \"label2\" \\]")
json_assert_key("${content_file}" "${targetData}" type "EXECUTABLE")
endforeach()
# Ensure provided -DN=* arguments result in differing JSON contents
@@ -40,7 +54,7 @@ endif()
# Ensure snippets reference valid files
foreach(snippet IN LISTS snippets)
read_json("${snippet}" contents)
string(JSON filename GET "${contents}" configureContent)
string(JSON filename GET "${contents}" cmakeContent)
if (NOT EXISTS "${v1}/data/${filename}")
add_error("Reference to content file that does not exist.")
endif()

View File

@@ -51,36 +51,8 @@ foreach(snippet IN LISTS snippets)
# Verify contents of link-* Snippets
if (filename MATCHES "^link-")
string(JSON target GET "${contents}" target)
string(JSON targetType GET "${contents}" targetType)
string(JSON targetLabels GET "${contents}" targetLabels)
if (target MATCHES "main")
if (NOT targetType MATCHES "EXECUTABLE")
json_error("${snippet}" "Expected EXECUTABLE, target type was ${targetType}")
endif()
string(JSON nlabels LENGTH "${targetLabels}")
if (NOT nlabels STREQUAL 2)
json_error("${snippet}" "Missing Target Labels for: ${target}")
else()
string(JSON label1 GET "${contents}" targetLabels 0)
string(JSON label2 GET "${contents}" targetLabels 1)
if (NOT label1 MATCHES "label1" OR NOT label2 MATCHES "label2")
json_error("${snippet}" "Missing Target Labels for: ${target}")
endif()
endif()
endif()
if (target MATCHES "lib")
if (NOT targetType MATCHES "STATIC_LIBRARY")
json_error("${snippet}" "Expected STATIC_LIBRARY, target type was ${targetType}")
endif()
string(JSON nlabels LENGTH "${targetLabels}")
if (NOT nlabels STREQUAL 1)
json_error("${snippet}" "Missing Target Labels for: ${target}")
else()
string(JSON label ERROR_VARIABLE noLabels GET "${contents}" targetLabels 0)
if (NOT label MATCHES "label3")
json_error("${snippet}" "Missing Target Labels for: ${target}")
endif()
endif()
if (NOT target MATCHES "main|lib")
json_error("${snippet}" "Unexpected link target: ${target}")
endif()
endif()

View File

@@ -14,8 +14,6 @@ function(snippet_has_fields snippet contents)
json_has_key("${snippet}" "${contents}" target)
json_has_key("${snippet}" "${contents}" outputs)
json_has_key("${snippet}" "${contents}" outputSizes)
json_has_key("${snippet}" "${contents}" targetType)
json_has_key("${snippet}" "${contents}" targetLabels)
json_has_key("${snippet}" "${contents}" config)
json_has_key("${snippet}" "${contents}" language)
elseif (filename MATCHES "^compile-*")