Browse Source

instrumentation: Add targetLabels field to link snippets

Adds a new data field `targetLabels` to link snippets which contains a list of
text labels from the LABELS target property.
Martin Duffy 9 months ago
parent
commit
9d34069ca8

+ 4 - 0
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.

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

+ 20 - 0
Tests/RunCMake/Instrumentation/check-data-dir.cmake

@@ -52,15 +52,35 @@ foreach(snippet ${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")
         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()
 

+ 1 - 0
Tests/RunCMake/Instrumentation/verify-snippet.cmake

@@ -32,6 +32,7 @@ macro(snippet_has_fields snippet contents)
     has_key(${snippet} ${contents} outputs)
     has_key(${snippet} ${contents} outputSizes)
     has_key(${snippet} ${contents} targetType)
+    has_key(${snippet} ${contents} targetLabels)
   elseif (filename MATCHES ^compile-*)
     has_key(${snippet} ${contents} target)
     has_key(${snippet} ${contents} outputs)