瀏覽代碼

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 <[email protected]>
Acked-by: buildbot <[email protected]>
Acked-by: Roscoe A. Bartlett <[email protected]>
Merge-request: !10185
Brad King 9 月之前
父節點
當前提交
c2838829f2

+ 6 - 2
Help/manual/cmake-instrumentation.7.rst

@@ -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

+ 7 - 0
Source/CTest/cmCTestLaunch.cxx

@@ -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 {

+ 1 - 0
Source/CTest/cmCTestLaunchReporter.h

@@ -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;

+ 9 - 0
Source/cmGeneratorTarget.cxx

@@ -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(

+ 4 - 0
Source/cmGeneratorTarget.h

@@ -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
   {

+ 3 - 0
Source/cmInstrumentation.cxx

@@ -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;

+ 1 - 0
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -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) {

+ 2 - 0
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -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();

+ 2 - 0
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -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();

+ 2 - 1
Source/cmMakefileTargetGenerator.cxx

@@ -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();

+ 6 - 0
Source/cmNinjaNormalTargetGenerator.cxx

@@ -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();

+ 3 - 0
Source/cmNinjaTargetGenerator.cxx

@@ -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";

+ 7 - 0
Source/cmRulePlaceholderExpander.cxx

@@ -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;

+ 1 - 0
Source/cmRulePlaceholderExpander.h

@@ -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;

+ 4 - 3
Source/cmake.cxx

@@ -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,

+ 36 - 14
Tests/RunCMake/Instrumentation/check-data-dir.cmake

@@ -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()

+ 3 - 3
Tests/RunCMake/Instrumentation/hook.cmake

@@ -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()

+ 16 - 14
Tests/RunCMake/Instrumentation/verify-snippet.cmake

@@ -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)