Merge topic 'instrumentation-target-labels'

9d34069ca8 instrumentation: Add targetLabels field to link snippets
32444714e5 instrumentation: Update tests so that snippet verification runs
11bcf2efb8 instrumentation: Correct example v1 Data snippet in manual

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Acked-by: Roscoe A. Bartlett <rabartl@sandia.gov>
Merge-request: !10185
This commit is contained in:
Brad King 2025-01-18 14:46:07 +00:00 committed by Kitware Robot
commit c2838829f2
18 changed files with 113 additions and 37 deletions

View File

@ -232,6 +232,10 @@ and contain the following data:
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``.
``timeStart``
Time at which the command started, expressed as the number of milliseconds
since the system epoch.
@ -296,8 +300,8 @@ Example:
"beforeCPULoadAverage" : 2.3500000000000001,
"beforeHostMemoryUsed" : 6635832.0
},
"timeStart" : 31997009,
"timeStop" : 31997056
"timeStart" : 1737053448177,
"duration" : 31
}
v1 Index File

View File

@ -62,6 +62,7 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
DoingOutput,
DoingSource,
DoingLanguage,
DoingTargetLabels,
DoingTargetName,
DoingTargetType,
DoingCommandType,
@ -84,6 +85,8 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
doing = DoingSource;
} else if (strcmp(arg, "--language") == 0) {
doing = DoingLanguage;
} else if (strcmp(arg, "--target-labels") == 0) {
doing = DoingTargetLabels;
} else if (strcmp(arg, "--target-name") == 0) {
doing = DoingTargetName;
} else if (strcmp(arg, "--target-type") == 0) {
@ -106,6 +109,9 @@ bool cmCTestLaunch::ParseArguments(int argc, const char* const* argv)
this->Reporter.OptionLanguage = "C++";
}
doing = DoingNone;
} else if (doing == DoingTargetLabels) {
this->Reporter.OptionTargetLabels = arg;
doing = DoingNone;
} else if (doing == DoingTargetName) {
this->Reporter.OptionTargetName = arg;
doing = DoingNone;
@ -257,6 +263,7 @@ int cmCTestLaunch::Run()
options["role"] = this->Reporter.OptionRole;
std::map<std::string, std::string> arrayOptions;
arrayOptions["outputs"] = this->Reporter.OptionOutput;
arrayOptions["targetLabels"] = this->Reporter.OptionTargetLabels;
instrumenter.InstrumentCommand(
this->Reporter.OptionCommandType, this->RealArgV,
[this]() -> int {

View File

@ -34,6 +34,7 @@ public:
std::string OptionOutput;
std::string OptionSource;
std::string OptionLanguage;
std::string OptionTargetLabels;
std::string OptionTargetName;
std::string OptionTargetType;
std::string OptionBuildDir;

View File

@ -2041,6 +2041,14 @@ std::vector<std::string> cmGeneratorTarget::GetAppleArchs(
return std::move(archList.data());
}
const std::string& 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)
@ -2305,6 +2313,7 @@ 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

@ -402,6 +402,8 @@ public:
cmLocalGenerator* LocalGenerator;
cmGlobalGenerator const* GlobalGenerator;
std::string targetLabelsString;
struct ModuleDefinitionInfo
{
std::string DefFile;
@ -514,6 +516,8 @@ public:
std::vector<std::string> GetAppleArchs(std::string const& config,
cm::optional<std::string> lang) const;
const std::string& GetTargetLabelsString();
// The classification of the flag.
enum class FlagClassification
{

View File

@ -425,6 +425,9 @@ int cmInstrumentation::InstrumentCommand(
}
if (arrayOptions.has_value()) {
for (auto const& item : arrayOptions.value()) {
if (item.first == "targetLabels" && command_type != "link") {
continue;
}
root[item.first] = Json::arrayValue;
std::stringstream ss(item.second);
std::string element;

View File

@ -994,6 +994,7 @@ 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;
const std::vector<std::string>& outputs = ccg.GetOutputs();
for (size_t i = 0; i < outputs.size(); ++i) {

View File

@ -537,6 +537,8 @@ 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

@ -781,6 +781,8 @@ 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

@ -931,6 +931,7 @@ 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();
@ -1694,7 +1695,7 @@ 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

@ -293,6 +293,8 @@ 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 =
@ -400,6 +402,8 @@ 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";
@ -451,6 +455,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
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();

View File

@ -623,6 +623,7 @@ 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();
@ -681,6 +682,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& 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

@ -261,6 +261,13 @@ 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,6 +32,7 @@ public:
{
const char* CMTargetName = nullptr;
const char* CMTargetType = nullptr;
const char* CMTargetLabels = nullptr;
const char* TargetPDB = nullptr;
const char* TargetCompilePDB = nullptr;
const char* TargetVersionMajor = nullptr;

View File

@ -2703,9 +2703,10 @@ int cmake::ActualConfigure()
"--output <OBJECT> --source <SOURCE> --language <LANGUAGE> -- "));
this->State->SetGlobalProperty(
"RULE_LAUNCH_LINK",
cmStrCat(launcher, "--command-type link", common_args,
"--output <TARGET> --target-type <TARGET_TYPE> ",
"--language <LANGUAGE> -- "));
cmStrCat(
launcher, "--command-type link", common_args,
"--output <TARGET> --target-type <TARGET_TYPE> ",
"--language <LANGUAGE> --target-labels \"<TARGET_LABELS>\" -- "));
this->State->SetGlobalProperty(
"RULE_LAUNCH_CUSTOM",
cmStrCat(launcher, "--command-type custom", common_args,

View File

@ -8,6 +8,8 @@ endif()
set(FOUND_SNIPPETS "")
foreach(snippet ${snippets})
get_filename_component(filename ${snippet} NAME)
read_json(${snippet} contents)
# Verify snippet file is valid
@ -19,7 +21,7 @@ foreach(snippet ${snippets})
endif()
# Verify target
string(JSON target ERROR_VARIABLE noTarget GET ${contents} target)
string(JSON target ERROR_VARIABLE noTarget GET "${contents}" target)
if (NOT target MATCHES NOTFOUND)
set(targets "main;lib;customTarget;TARGET_NAME")
if (NOT ${target} IN_LIST targets)
@ -28,16 +30,16 @@ foreach(snippet ${snippets})
endif()
# Verify output
string(JSON result GET ${contents} result)
string(JSON result GET "${contents}" result)
if (NOT ${result} EQUAL 0)
snippet_error(${snippet} "Compile command had non-0 result")
endif()
# Verify contents of compile-* Snippets
if (snippet MATCHES ^compile-)
string(JSON target GET ${contents} target)
string(JSON source GET ${contents} source)
string(JSON language GET ${contents} language)
if (filename MATCHES ^compile-)
string(JSON target GET "${contents}" target)
string(JSON source GET "${contents}" source)
string(JSON language GET "${contents}" language)
if (NOT language MATCHES "C\\+\\+")
snippet_error(${snippet} "Expected C++ compile language")
endif()
@ -47,33 +49,53 @@ foreach(snippet ${snippets})
endif()
# Verify contents of link-* Snippets
if (snippet MATCHES ^link-)
string(JSON target GET ${contents} target)
string(JSON targetType GET ${contents} targetType)
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")
snippet_error(${snippet} "Expected EXECUTABLE, target type was ${targetType}")
endif()
string(JSON nlabels LENGTH "${targetLabels}")
if (NOT nlabels STREQUAL 2)
snippet_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")
snippet_error(${snippet} "Missing Target Labels for: ${target}")
endif()
endif()
endif()
if (target MATCHES lib)
if (NOT targetType MATCHES "STATIC_LIBRARY")
snippet_error(${snippet} "Expected STATIC_LIBRARY, target type was ${targetType}")
endif()
string(JSON nlabels LENGTH "${targetLabels}")
if (NOT nlabels STREQUAL 1)
snippet_error(${snippet} "Missing Target Labels for: ${target}")
else()
string(JSON label ERROR_VARIABLE noLabels GET "${contents}" targetLabels 0)
if (NOT label MATCHES "label3")
snippet_error(${snippet} "Missing Target Labels for: ${target}")
endif()
endif()
endif()
endif()
# Verify contents of custom-* Snippets
if (snippet MATCHES ^custom-)
string(JSON outputs GET ${contents} outputs)
if (filename MATCHES ^custom-)
string(JSON outputs GET "${contents}" outputs)
if (NOT output1 MATCHES "output1" OR NOT output2 MATCHES "output2")
snippet_error(${snippet} "Custom command missing outputs")
endif()
endif()
# Verify contents of test-* Snippets
if (snippet MATCHES ^test-)
string(JSON testName GET ${contents} testName)
if (NOT testName EQUAL "test")
if (filename MATCHES ^test-)
string(JSON testName GET "${contents}" testName)
if (NOT testName STREQUAL "test")
snippet_error(${snippet} "Unexpected testName: ${testName}")
endif()
endif()

View File

@ -6,7 +6,7 @@ if (NOT ${CMAKE_ARGV3})
set(hasStaticInfo "UNEXPECTED")
endif()
read_json(${index} contents)
string(JSON hook GET ${contents} hook)
string(JSON hook GET "${contents}" hook)
# Output is verified by *-stdout.txt files that the HOOK is run
message(STATUS ${hook})
@ -19,7 +19,7 @@ endmacro()
macro(has_key key json)
cmake_parse_arguments(ARG "UNEXPECTED" "" "" ${ARGN})
unset(missingKey)
string(JSON ${key} ERROR_VARIABLE missingKey GET ${json} ${key})
string(JSON ${key} ERROR_VARIABLE missingKey GET "${json}" ${key})
if (NOT ARG_UNEXPECTED AND NOT "${missingKey}" MATCHES NOTFOUND)
add_error("\nKey \"${key}\" not in index:\n${json}")
elseif(ARG_UNEXPECTED AND "${missingKey}" MATCHES NOTFOUND)
@ -39,7 +39,7 @@ endif()
string(JSON length LENGTH ${snippets})
math(EXPR length ${length}-1)
foreach(i RANGE ${length})
string(JSON filename GET ${snippets} ${i})
string(JSON filename GET "${snippets}" ${i})
if (NOT EXISTS ${dataDir}/${filename})
add_error("Listed snippet: ${dataDir}/${filename} does not exist")
endif()

View File

@ -9,44 +9,46 @@ macro(snippet_error snippet error)
endmacro()
macro(has_key snippet json key)
string(JSON data ERROR_VARIABLE missingKey GET ${json} ${key})
string(JSON data ERROR_VARIABLE missingKey GET "${json}" ${key})
if (NOT ${missingKey} MATCHES NOTFOUND)
snippet_error(${snippet} "Missing ${key}")
endif()
endmacro()
macro(has_not_key snippet json key)
string(JSON data ERROR_VARIABLE missingKey GET ${json} ${key})
string(JSON data ERROR_VARIABLE missingKey GET "${json}" ${key})
if (${missingKey} MATCHES NOTFOUND)
snippet_error(${snippet} "Has unexpected ${key}")
endif()
endmacro()
macro(snippet_has_fields snippet contents)
get_filename_component(filename ${snippet} NAME)
has_key(${snippet} ${contents} command)
has_key(${snippet} ${contents} role)
has_key(${snippet} ${contents} result)
if (snippet MATCHES ^link-*)
if (filename MATCHES ^link-*)
has_key(${snippet} ${contents} target)
has_key(${snippet} ${contents} outputs)
has_key(${snippet} ${contents} outputSizes)
has_key(${snippet} ${contents} targetType)
elseif (snippet MATCHES ^compile-*)
has_key(${snippet} ${contents} targetLabels)
elseif (filename MATCHES ^compile-*)
has_key(${snippet} ${contents} target)
has_key(${snippet} ${contents} outputs)
has_key(${snippet} ${contents} outputSizes)
has_key(${snippet} ${contents} source)
has_key(${snippet} ${contents} language)
elseif (snippet MATCHES ^custom-*)
elseif (filename MATCHES ^custom-*)
has_key(${snippet} ${contents} target)
has_key(${snippet} ${contents} outputs)
has_key(${snippet} ${contents} outputSizes)
elseif (snippet MATCHES ^test-*)
elseif (filename MATCHES ^test-*)
has_key(${snippet} ${contents} testName)
endif()
if(ARGS_DYNAMIC_QUERY)
has_key(${snippet} ${contents} dynamicSystemInformation)
string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET ${contents} dynamicSystemInformation)
string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET "${contents}" dynamicSystemInformation)
if (noInfo MATCHES NOTFOUND)
has_key(${snippet} ${dynamicSystemInfo} beforeCPULoadAverage)
has_key(${snippet} ${dynamicSystemInfo} beforeHostMemoryUsed)
@ -55,7 +57,7 @@ macro(snippet_has_fields snippet contents)
endif()
else()
has_not_key(${snippet} ${contents} dynamicSystemInformation)
string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET ${contents} dynamicSystemInformation)
string(JSON dynamicSystemInfo ERROR_VARIABLE noInfo GET "${contents}" dynamicSystemInformation)
if (noInfo MATCHES NOTFOUND)
has_not_key(${snippet} ${dynamicSystemInfo} beforeCPULoadAverage)
has_not_key(${snippet} ${dynamicSystemInfo} beforeHostMemoryUsed)
@ -66,8 +68,8 @@ macro(snippet_has_fields snippet contents)
endmacro()
macro(snippet_valid_timing contents)
string(JSON start GET ${contents} timeStart)
string(JSON duration GET ${contents} duration)
string(JSON start GET "${contents}" timeStart)
string(JSON duration GET "${contents}" duration)
if (${start} LESS 0)
snippet_error(${snippet} "Negative time start: ${start}")
endif()
@ -79,18 +81,18 @@ endmacro()
macro(verify_snippet snippet contents)
snippet_has_fields(${snippet} ${contents})
snippet_valid_timing(${contents})
string(JSON version GET ${contents} version)
string(JSON version GET "${contents}" version)
if (NOT ${version} EQUAL 1)
snippet_error(${snippet} "Version must be 1, got: ${version}")
endif()
string(JSON role GET ${contents} role)
string(JSON role GET "${contents}" role)
get_filename_component(filename ${snippet} NAME)
if (NOT ${filename} MATCHES ^${role}-)
snippet_error(${snippet} "Role \"${role}\" doesn't match snippet filename")
endif()
string(JSON outputs ERROR_VARIABLE noOutputs GET ${contents} outputs)
string(JSON outputs ERROR_VARIABLE noOutputs GET "${contents}" outputs)
if (NOT outputs MATCHES NOTFOUND)
string(JSON outputSizes ERROR_VARIABLE noOutputSizes GET ${contents} outputSizes)
string(JSON outputSizes ERROR_VARIABLE noOutputSizes GET "${contents}" outputSizes)
list(LENGTH outputs outputsLen)
list(LENGTH outputSizes outputSizesLen)
if (outputSizes MATCHES NOTFOUND OR NOT outputsLen EQUAL outputSizesLen)