Explorar el Código

Fix transitive usage requirements through same-name imported targets

If two imported targets in different directories have the same name we
should still be able to propagate transitive usage requirements from
both.  Fix the DAG checker to work with target pointers instead of
target names since the pointers will not be duplicated even if the names
are.

Fixes: #18345
Brad King hace 7 años
padre
commit
f35be59961

+ 1 - 1
Source/cmExportBuildAndroidMKGenerator.cxx

@@ -108,7 +108,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
         // build type of the makefile
         // build type of the makefile
         cmGeneratorExpression ge;
         cmGeneratorExpression ge;
         cmGeneratorExpressionDAGChecker dagChecker(
         cmGeneratorExpressionDAGChecker dagChecker(
-          target->GetName(), "INTERFACE_LINK_LIBRARIES", nullptr, nullptr);
+          target, "INTERFACE_LINK_LIBRARIES", nullptr, nullptr);
         std::unique_ptr<cmCompiledGeneratorExpression> cge =
         std::unique_ptr<cmCompiledGeneratorExpression> cge =
           ge.Parse(property.second);
           ge.Parse(property.second);
         std::string evaluated = cge->Evaluate(
         std::string evaluated = cge->Evaluate(

+ 1 - 2
Source/cmExportTryCompileFileGenerator.cxx

@@ -65,8 +65,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
 
 
   cmGeneratorExpression ge;
   cmGeneratorExpression ge;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(tgt->GetName(), propName, nullptr,
-                                             nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
 
 
   std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
   std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
 
 

+ 1 - 2
Source/cmGeneratorExpression.cxx

@@ -13,7 +13,6 @@
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionLexer.h"
 #include "cmGeneratorExpressionLexer.h"
 #include "cmGeneratorExpressionParser.h"
 #include "cmGeneratorExpressionParser.h"
-#include "cmGeneratorTarget.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 
 
 cmGeneratorExpression::cmGeneratorExpression(
 cmGeneratorExpression::cmGeneratorExpression(
@@ -395,7 +394,7 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
 
 
   // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
   // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
   cmGeneratorExpressionDAGChecker dagChecker(
   cmGeneratorExpressionDAGChecker dagChecker(
-    this->HeadTarget->GetName(),
+    this->HeadTarget,
     property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
     property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
     nullptr);
     nullptr);
 
 

+ 7 - 6
Source/cmGeneratorExpressionDAGChecker.cxx

@@ -14,7 +14,7 @@
 #include <utility>
 #include <utility>
 
 
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
-  const cmListFileBacktrace& backtrace, const std::string& target,
+  const cmListFileBacktrace& backtrace, cmGeneratorTarget const* target,
   const std::string& property, const GeneratorExpressionContent* content,
   const std::string& property, const GeneratorExpressionContent* content,
   cmGeneratorExpressionDAGChecker* parent)
   cmGeneratorExpressionDAGChecker* parent)
   : Parent(parent)
   : Parent(parent)
@@ -28,7 +28,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
 }
 }
 
 
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
-  const std::string& target, const std::string& property,
+  cmGeneratorTarget const* target, const std::string& property,
   const GeneratorExpressionContent* content,
   const GeneratorExpressionContent* content,
   cmGeneratorExpressionDAGChecker* parent)
   cmGeneratorExpressionDAGChecker* parent)
   : Parent(parent)
   : Parent(parent)
@@ -58,8 +58,8 @@ void cmGeneratorExpressionDAGChecker::Initialize()
         TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(clang-tidy)
         TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(clang-tidy)
 #undef TEST_TRANSITIVE_PROPERTY_METHOD
 #undef TEST_TRANSITIVE_PROPERTY_METHOD
   {
   {
-    std::map<std::string, std::set<std::string>>::const_iterator it =
-      top->Seen.find(this->Target);
+    std::map<cmGeneratorTarget const*, std::set<std::string>>::const_iterator
+      it = top->Seen.find(this->Target);
     if (it != top->Seen.end()) {
     if (it != top->Seen.end()) {
       const std::set<std::string>& propSet = it->second;
       const std::set<std::string>& propSet = it->second;
       if (propSet.find(this->Property) != propSet.end()) {
       if (propSet.find(this->Property) != propSet.end()) {
@@ -166,7 +166,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
   return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL";
   return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL";
 }
 }
 
 
-bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt)
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
+  cmGeneratorTarget const* tgt)
 {
 {
   const cmGeneratorExpressionDAGChecker* top = this;
   const cmGeneratorExpressionDAGChecker* top = this;
   const cmGeneratorExpressionDAGChecker* parent = this->Parent;
   const cmGeneratorExpressionDAGChecker* parent = this->Parent;
@@ -189,7 +190,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt)
     strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
     strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
 }
 }
 
 
-std::string cmGeneratorExpressionDAGChecker::TopTarget() const
+cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
 {
 {
   const cmGeneratorExpressionDAGChecker* top = this;
   const cmGeneratorExpressionDAGChecker* top = this;
   const cmGeneratorExpressionDAGChecker* parent = this->Parent;
   const cmGeneratorExpressionDAGChecker* parent = this->Parent;

+ 7 - 6
Source/cmGeneratorExpressionDAGChecker.h

@@ -13,6 +13,7 @@
 
 
 struct GeneratorExpressionContent;
 struct GeneratorExpressionContent;
 struct cmGeneratorExpressionContext;
 struct cmGeneratorExpressionContext;
+class cmGeneratorTarget;
 
 
 #define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
 #define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
 #define CM_SELECT_FIRST(F, A1, A2) F(A1)
 #define CM_SELECT_FIRST(F, A1, A2) F(A1)
@@ -41,11 +42,11 @@ struct cmGeneratorExpressionContext;
 struct cmGeneratorExpressionDAGChecker
 struct cmGeneratorExpressionDAGChecker
 {
 {
   cmGeneratorExpressionDAGChecker(const cmListFileBacktrace& backtrace,
   cmGeneratorExpressionDAGChecker(const cmListFileBacktrace& backtrace,
-                                  const std::string& target,
+                                  cmGeneratorTarget const* target,
                                   const std::string& property,
                                   const std::string& property,
                                   const GeneratorExpressionContent* content,
                                   const GeneratorExpressionContent* content,
                                   cmGeneratorExpressionDAGChecker* parent);
                                   cmGeneratorExpressionDAGChecker* parent);
-  cmGeneratorExpressionDAGChecker(const std::string& target,
+  cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
                                   const std::string& property,
                                   const std::string& property,
                                   const GeneratorExpressionContent* content,
                                   const GeneratorExpressionContent* content,
                                   cmGeneratorExpressionDAGChecker* parent);
                                   cmGeneratorExpressionDAGChecker* parent);
@@ -64,7 +65,7 @@ struct cmGeneratorExpressionDAGChecker
                    const std::string& expr);
                    const std::string& expr);
 
 
   bool EvaluatingGenexExpression();
   bool EvaluatingGenexExpression();
-  bool EvaluatingLinkLibraries(const char* tgt = nullptr);
+  bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
 
 
 #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
 #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
 
 
@@ -75,7 +76,7 @@ struct cmGeneratorExpressionDAGChecker
   bool GetTransitivePropertiesOnly();
   bool GetTransitivePropertiesOnly();
   void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
   void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
 
 
-  std::string TopTarget() const;
+  cmGeneratorTarget const* TopTarget() const;
 
 
 private:
 private:
   Result CheckGraph() const;
   Result CheckGraph() const;
@@ -83,9 +84,9 @@ private:
 
 
 private:
 private:
   const cmGeneratorExpressionDAGChecker* const Parent;
   const cmGeneratorExpressionDAGChecker* const Parent;
-  const std::string Target;
+  cmGeneratorTarget const* Target;
   const std::string Property;
   const std::string Property;
-  std::map<std::string, std::set<std::string>> Seen;
+  std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
   const GeneratorExpressionContent* const Content;
   const GeneratorExpressionContent* const Content;
   const cmListFileBacktrace Backtrace;
   const cmListFileBacktrace Backtrace;
   Result CheckResult;
   Result CheckResult;

+ 6 - 7
Source/cmGeneratorExpressionNode.cxx

@@ -378,8 +378,8 @@ protected:
   {
   {
     if (context->HeadTarget) {
     if (context->HeadTarget) {
       cmGeneratorExpressionDAGChecker dagChecker(
       cmGeneratorExpressionDAGChecker dagChecker(
-        context->Backtrace, context->HeadTarget->GetName(), genexOperator,
-        content, dagCheckerParent);
+        context->Backtrace, context->HeadTarget, genexOperator, content,
+        dagCheckerParent);
       switch (dagChecker.Check()) {
       switch (dagChecker.Check()) {
         case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
         case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
         case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
         case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
@@ -1196,9 +1196,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
       return target->GetLinkerLanguage(context->Config);
       return target->GetLinkerLanguage(context->Config);
     }
     }
 
 
-    cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
-                                               target->GetName(), propertyName,
-                                               content, dagCheckerParent);
+    cmGeneratorExpressionDAGChecker dagChecker(
+      context->Backtrace, target, propertyName, content, dagCheckerParent);
 
 
     switch (dagChecker.Check()) {
     switch (dagChecker.Check()) {
       case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
       case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
@@ -1911,9 +1910,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
       return std::string();
       return std::string();
     }
     }
     if (dagChecker &&
     if (dagChecker &&
-        (dagChecker->EvaluatingLinkLibraries(name.c_str()) ||
+        (dagChecker->EvaluatingLinkLibraries(target) ||
          (dagChecker->EvaluatingSources() &&
          (dagChecker->EvaluatingSources() &&
-          name == dagChecker->TopTarget()))) {
+          target == dagChecker->TopTarget()))) {
       ::reportError(context, content->GetOriginalExpression(),
       ::reportError(context, content->GetOriginalExpression(),
                     "Expressions which require the linker language may not "
                     "Expressions which require the linker language may not "
                     "be used while evaluating link libraries");
                     "be used while evaluating link libraries");

+ 22 - 23
Source/cmGeneratorTarget.cxx

@@ -773,7 +773,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
 
 
   if (iter == this->SystemIncludesCache.end()) {
   if (iter == this->SystemIncludesCache.end()) {
     cmGeneratorExpressionDAGChecker dagChecker(
     cmGeneratorExpressionDAGChecker dagChecker(
-      this->GetName(), "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
+      this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
 
 
     bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
     bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
 
 
@@ -964,8 +964,8 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files,
     this->DebugSourcesDone = true;
     this->DebugSourcesDone = true;
   }
   }
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "SOURCES",
-                                             nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
+                                             nullptr);
 
 
   std::unordered_set<std::string> uniqueSrcs;
   std::unordered_set<std::string> uniqueSrcs;
   bool contextDependentDirectSources =
   bool contextDependentDirectSources =
@@ -2078,8 +2078,8 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
   }
   }
   cmGeneratorExpression ge;
   cmGeneratorExpression ge;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "AUTOUIC_OPTIONS", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr,
+                                             nullptr);
   cmSystemTools::ExpandListArgument(
   cmSystemTools::ExpandListArgument(
     ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this,
     ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this,
                              &dagChecker),
                              &dagChecker),
@@ -2588,8 +2588,8 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
   std::vector<std::string> includes;
   std::vector<std::string> includes;
   std::unordered_set<std::string> uniqueIncludes;
   std::unordered_set<std::string> uniqueIncludes;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "INCLUDE_DIRECTORIES", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
+                                             nullptr, nullptr);
 
 
   std::vector<std::string> debugProperties;
   std::vector<std::string> debugProperties;
   const char* debugProp =
   const char* debugProp =
@@ -2710,8 +2710,8 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
 {
 {
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "COMPILE_OPTIONS", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr,
+                                             nullptr);
 
 
   std::vector<std::string> debugProperties;
   std::vector<std::string> debugProperties;
   const char* debugProp =
   const char* debugProp =
@@ -2763,8 +2763,8 @@ void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
 {
 {
   std::unordered_set<std::string> uniqueFeatures;
   std::unordered_set<std::string> uniqueFeatures;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "COMPILE_FEATURES", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr,
+                                             nullptr);
 
 
   std::vector<std::string> debugProperties;
   std::vector<std::string> debugProperties;
   const char* debugProp =
   const char* debugProp =
@@ -2814,8 +2814,8 @@ void cmGeneratorTarget::GetCompileDefinitions(
 {
 {
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "COMPILE_DEFINITIONS", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
+                                             nullptr, nullptr);
 
 
   std::vector<std::string> debugProperties;
   std::vector<std::string> debugProperties;
   const char* debugProp =
   const char* debugProp =
@@ -2895,8 +2895,8 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
 {
 {
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_OPTIONS",
-                                             nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr,
+                                             nullptr);
 
 
   std::vector<std::string> debugProperties;
   std::vector<std::string> debugProperties;
   const char* debugProp =
   const char* debugProp =
@@ -3043,8 +3043,8 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions(
   std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
   std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "STATIC_LIBRARY_OPTIONS", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
+                                             nullptr, nullptr);
 
 
   if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
   if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
     std::vector<std::string> options;
     std::vector<std::string> options;
@@ -3083,8 +3083,8 @@ void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
 {
 {
   std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
   std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_DEPENDS",
-                                             nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
+                                             nullptr);
 
 
   if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
   if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
     std::vector<std::string> depends;
     std::vector<std::string> depends;
@@ -4509,8 +4509,7 @@ void cmGeneratorTarget::ExpandLinkItems(
   std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
   std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
 {
 {
   cmGeneratorExpression ge;
   cmGeneratorExpression ge;
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, nullptr,
-                                             nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
   // The $<LINK_ONLY> expression may be in a link interface to specify private
   // The $<LINK_ONLY> expression may be in a link interface to specify private
   // link dependencies that are otherwise excluded from usage requirements.
   // link dependencies that are otherwise excluded from usage requirements.
   if (usage_requirements_only) {
   if (usage_requirements_only) {
@@ -5561,8 +5560,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
                                      end = entryRange.end();
                                      end = entryRange.end();
        le != end; ++le, ++btIt) {
        le != end; ++le, ++btIt) {
     std::vector<std::string> llibs;
     std::vector<std::string> llibs;
-    cmGeneratorExpressionDAGChecker dagChecker(
-      this->GetName(), "LINK_LIBRARIES", nullptr, nullptr);
+    cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
+                                               nullptr);
     cmGeneratorExpression ge(*btIt);
     cmGeneratorExpression ge(*btIt);
     std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
     std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
     std::string const& evaluated =
     std::string const& evaluated =

+ 1 - 0
Tests/ImportedSameName/A/CMakeLists.txt

@@ -1,4 +1,5 @@
 add_library(a STATIC a.c)
 add_library(a STATIC a.c)
+target_compile_definitions(a INTERFACE DEF_A)
 
 
 add_library(sameName INTERFACE IMPORTED)
 add_library(sameName INTERFACE IMPORTED)
 target_link_libraries(sameName INTERFACE a)
 target_link_libraries(sameName INTERFACE a)

+ 1 - 0
Tests/ImportedSameName/B/CMakeLists.txt

@@ -1,4 +1,5 @@
 add_library(b STATIC b.c)
 add_library(b STATIC b.c)
+target_compile_definitions(b INTERFACE DEF_B)
 
 
 add_library(sameName INTERFACE IMPORTED)
 add_library(sameName INTERFACE IMPORTED)
 target_link_libraries(sameName INTERFACE b)
 target_link_libraries(sameName INTERFACE b)

+ 7 - 0
Tests/ImportedSameName/main.c

@@ -1,3 +1,10 @@
+#ifndef DEF_A
+#  error "DEF_A not defined"
+#endif
+#ifndef DEF_B
+#  error "DEF_B not defined"
+#endif
+
 extern void a(void);
 extern void a(void);
 extern void b(void);
 extern void b(void);