[Cmake-commits] CMake branch, master, updated. v3.12.2-588-gb1c8d95

Kitware Robot kwrobot at kitware.com
Tue Sep 11 08:25:06 EDT 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  b1c8d95dbe97ab2511e08518bf8eee1f5da2e941 (commit)
       via  4188b8fd6a17b7959aff8cf695ad02c291171950 (commit)
       via  dcbad14d23c8ca6673251a3f6ea9587ee0fe3d51 (commit)
       via  bb59e362cca795543a551f765fb8d39c0236df45 (commit)
       via  e0e56abe3479efddd994cc1a3ee9b8a123111903 (commit)
       via  3eda5cdd939e0bae5241e2286e7524d552ab455c (commit)
       via  e374b9f1ebae70ca4381588362d6d3418f832ea7 (commit)
       via  09f0325eaffb6b32b570e3339aa8b8332350b31d (commit)
       via  f35be599612b788125d08a7c3e61d0fad3805bdd (commit)
       via  68f2b471df7687e37ab2a5808585aad76c7c3122 (commit)
       via  1b57f49586afc9e8663d5e146732b1cd0597e7ef (commit)
       via  bea390e9bd68e1aa7d86b6aef7384f502c39068c (commit)
       via  fc7e4d1ed85370d03acbd62bc753cced3550752b (commit)
      from  c669b59095bf01ab0e254949989677496946ec08 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b1c8d95dbe97ab2511e08518bf8eee1f5da2e941
commit b1c8d95dbe97ab2511e08518bf8eee1f5da2e941
Merge: 4188b8f f35be59
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 11 12:20:44 2018 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Tue Sep 11 08:20:50 2018 -0400

    Merge topic 'imported-same-name'
    
    f35be59961 Fix transitive usage requirements through same-name imported targets
    1b57f49586 genex: Simplify cmGeneratorExpressionInterpreter
    bea390e9bd Fix dependency propagation through same-name imported targets
    fc7e4d1ed8 cmLinkItem: Convert to a "sum type" over a string and target pointer
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !2359


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4188b8fd6a17b7959aff8cf695ad02c291171950
commit 4188b8fd6a17b7959aff8cf695ad02c291171950
Merge: dcbad14 e0e56ab
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 11 08:19:44 2018 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Sep 11 08:19:44 2018 -0400

    Merge branch 'release-3.12'


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=dcbad14d23c8ca6673251a3f6ea9587ee0fe3d51
commit dcbad14d23c8ca6673251a3f6ea9587ee0fe3d51
Merge: bb59e36 e374b9f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 11 12:18:38 2018 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Tue Sep 11 08:18:55 2018 -0400

    Merge topic 'FindMPI-restore-flags-string'
    
    e374b9f1eb FindMPI: Restore MPI_<LANG>_COMPILE_FLAGS as a command-line string
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Reviewed-by: Christoph Junghans <junghans at votca.org>
    Reviewed-by: Christian Pfeiffer <cpfeiffer at live.de>
    Merge-request: !2368


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bb59e362cca795543a551f765fb8d39c0236df45
commit bb59e362cca795543a551f765fb8d39c0236df45
Merge: c669b59 09f0325
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Sep 11 12:18:01 2018 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Tue Sep 11 08:18:08 2018 -0400

    Merge topic 'fix-ctest_start-track'
    
    09f0325eaf CTest: Fix regression in ctest_start()
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !2366


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f35be599612b788125d08a7c3e61d0fad3805bdd
commit f35be599612b788125d08a7c3e61d0fad3805bdd
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 6 18:22:31 2018 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Sep 10 07:51:44 2018 -0400

    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

diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index bb370c4..3d32b84 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -108,7 +108,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
         // build type of the makefile
         cmGeneratorExpression ge;
         cmGeneratorExpressionDAGChecker dagChecker(
-          target->GetName(), "INTERFACE_LINK_LIBRARIES", nullptr, nullptr);
+          target, "INTERFACE_LINK_LIBRARIES", nullptr, nullptr);
         std::unique_ptr<cmCompiledGeneratorExpression> cge =
           ge.Parse(property.second);
         std::string evaluated = cge->Evaluate(
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 87648cb..c169032 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -65,8 +65,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
 
   cmGeneratorExpression ge;
 
-  cmGeneratorExpressionDAGChecker dagChecker(tgt->GetName(), propName, nullptr,
-                                             nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
 
   std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
 
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 6d83a3f..658e9a7 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -13,7 +13,6 @@
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionLexer.h"
 #include "cmGeneratorExpressionParser.h"
-#include "cmGeneratorTarget.h"
 #include "cmSystemTools.h"
 
 cmGeneratorExpression::cmGeneratorExpression(
@@ -395,7 +394,7 @@ const std::string& cmGeneratorExpressionInterpreter::Evaluate(
 
   // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
   cmGeneratorExpressionDAGChecker dagChecker(
-    this->HeadTarget->GetName(),
+    this->HeadTarget,
     property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
     nullptr);
 
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index face282..8d57441 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -14,7 +14,7 @@
 #include <utility>
 
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
-  const cmListFileBacktrace& backtrace, const std::string& target,
+  const cmListFileBacktrace& backtrace, cmGeneratorTarget const* target,
   const std::string& property, const GeneratorExpressionContent* content,
   cmGeneratorExpressionDAGChecker* parent)
   : Parent(parent)
@@ -28,7 +28,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
 }
 
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
-  const std::string& target, const std::string& property,
+  cmGeneratorTarget const* target, const std::string& property,
   const GeneratorExpressionContent* content,
   cmGeneratorExpressionDAGChecker* parent)
   : Parent(parent)
@@ -58,8 +58,8 @@ void cmGeneratorExpressionDAGChecker::Initialize()
         TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(clang-tidy)
 #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()) {
       const std::set<std::string>& propSet = it->second;
       if (propSet.find(this->Property) != propSet.end()) {
@@ -166,7 +166,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
   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* parent = this->Parent;
@@ -189,7 +190,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt)
     strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
 }
 
-std::string cmGeneratorExpressionDAGChecker::TopTarget() const
+cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
 {
   const cmGeneratorExpressionDAGChecker* top = this;
   const cmGeneratorExpressionDAGChecker* parent = this->Parent;
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index cd23904..8b1697b 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -13,6 +13,7 @@
 
 struct GeneratorExpressionContent;
 struct cmGeneratorExpressionContext;
+class cmGeneratorTarget;
 
 #define CM_SELECT_BOTH(F, A1, A2) F(A1, A2)
 #define CM_SELECT_FIRST(F, A1, A2) F(A1)
@@ -41,11 +42,11 @@ struct cmGeneratorExpressionContext;
 struct cmGeneratorExpressionDAGChecker
 {
   cmGeneratorExpressionDAGChecker(const cmListFileBacktrace& backtrace,
-                                  const std::string& target,
+                                  cmGeneratorTarget const* target,
                                   const std::string& property,
                                   const GeneratorExpressionContent* content,
                                   cmGeneratorExpressionDAGChecker* parent);
-  cmGeneratorExpressionDAGChecker(const std::string& target,
+  cmGeneratorExpressionDAGChecker(cmGeneratorTarget const* target,
                                   const std::string& property,
                                   const GeneratorExpressionContent* content,
                                   cmGeneratorExpressionDAGChecker* parent);
@@ -64,7 +65,7 @@ struct cmGeneratorExpressionDAGChecker
                    const std::string& expr);
 
   bool EvaluatingGenexExpression();
-  bool EvaluatingLinkLibraries(const char* tgt = nullptr);
+  bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
 
 #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
 
@@ -75,7 +76,7 @@ struct cmGeneratorExpressionDAGChecker
   bool GetTransitivePropertiesOnly();
   void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
 
-  std::string TopTarget() const;
+  cmGeneratorTarget const* TopTarget() const;
 
 private:
   Result CheckGraph() const;
@@ -83,9 +84,9 @@ private:
 
 private:
   const cmGeneratorExpressionDAGChecker* const Parent;
-  const std::string Target;
+  cmGeneratorTarget const* Target;
   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 cmListFileBacktrace Backtrace;
   Result CheckResult;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 9aa5212..1e51f09 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -378,8 +378,8 @@ protected:
   {
     if (context->HeadTarget) {
       cmGeneratorExpressionDAGChecker dagChecker(
-        context->Backtrace, context->HeadTarget->GetName(), genexOperator,
-        content, dagCheckerParent);
+        context->Backtrace, context->HeadTarget, genexOperator, content,
+        dagCheckerParent);
       switch (dagChecker.Check()) {
         case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
         case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
@@ -1196,9 +1196,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
       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()) {
       case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
@@ -1911,9 +1910,9 @@ struct TargetFilesystemArtifact : public cmGeneratorExpressionNode
       return std::string();
     }
     if (dagChecker &&
-        (dagChecker->EvaluatingLinkLibraries(name.c_str()) ||
+        (dagChecker->EvaluatingLinkLibraries(target) ||
          (dagChecker->EvaluatingSources() &&
-          name == dagChecker->TopTarget()))) {
+          target == dagChecker->TopTarget()))) {
       ::reportError(context, content->GetOriginalExpression(),
                     "Expressions which require the linker language may not "
                     "be used while evaluating link libraries");
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 080ff1c..e8e7b90 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -773,7 +773,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
 
   if (iter == this->SystemIncludesCache.end()) {
     cmGeneratorExpressionDAGChecker dagChecker(
-      this->GetName(), "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
+      this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr);
 
     bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
 
@@ -964,8 +964,8 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<std::string>& files,
     this->DebugSourcesDone = true;
   }
 
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "SOURCES",
-                                             nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
+                                             nullptr);
 
   std::unordered_set<std::string> uniqueSrcs;
   bool contextDependentDirectSources =
@@ -2078,8 +2078,8 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
   }
   cmGeneratorExpression ge;
 
-  cmGeneratorExpressionDAGChecker dagChecker(
-    this->GetName(), "AUTOUIC_OPTIONS", nullptr, nullptr);
+  cmGeneratorExpressionDAGChecker dagChecker(this, "AUTOUIC_OPTIONS", nullptr,
+                                             nullptr);
   cmSystemTools::ExpandListArgument(
     ge.Parse(prop)->Evaluate(this->LocalGenerator, config, false, this,
                              &dagChecker),
@@ -2588,8 +2588,8 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
   std::vector<std::string> includes;
   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;
   const char* debugProp =
@@ -2710,8 +2710,8 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
 {
   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;
   const char* debugProp =
@@ -2763,8 +2763,8 @@ void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
 {
   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;
   const char* debugProp =
@@ -2814,8 +2814,8 @@ void cmGeneratorTarget::GetCompileDefinitions(
 {
   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;
   const char* debugProp =
@@ -2895,8 +2895,8 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
 {
   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;
   const char* debugProp =
@@ -3043,8 +3043,8 @@ void cmGeneratorTarget::GetStaticLibraryLinkOptions(
   std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
   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")) {
     std::vector<std::string> options;
@@ -3083,8 +3083,8 @@ void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
 {
   std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
   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")) {
     std::vector<std::string> depends;
@@ -4509,8 +4509,7 @@ void cmGeneratorTarget::ExpandLinkItems(
   std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
 {
   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
   // link dependencies that are otherwise excluded from usage requirements.
   if (usage_requirements_only) {
@@ -5561,8 +5560,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
                                      end = entryRange.end();
        le != end; ++le, ++btIt) {
     std::vector<std::string> llibs;
-    cmGeneratorExpressionDAGChecker dagChecker(
-      this->GetName(), "LINK_LIBRARIES", nullptr, nullptr);
+    cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
+                                               nullptr);
     cmGeneratorExpression ge(*btIt);
     std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
     std::string const& evaluated =
diff --git a/Tests/ImportedSameName/A/CMakeLists.txt b/Tests/ImportedSameName/A/CMakeLists.txt
index 9417a2c..0a31b40 100644
--- a/Tests/ImportedSameName/A/CMakeLists.txt
+++ b/Tests/ImportedSameName/A/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_library(a STATIC a.c)
+target_compile_definitions(a INTERFACE DEF_A)
 
 add_library(sameName INTERFACE IMPORTED)
 target_link_libraries(sameName INTERFACE a)
diff --git a/Tests/ImportedSameName/B/CMakeLists.txt b/Tests/ImportedSameName/B/CMakeLists.txt
index 6947fa9..d930326 100644
--- a/Tests/ImportedSameName/B/CMakeLists.txt
+++ b/Tests/ImportedSameName/B/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_library(b STATIC b.c)
+target_compile_definitions(b INTERFACE DEF_B)
 
 add_library(sameName INTERFACE IMPORTED)
 target_link_libraries(sameName INTERFACE b)
diff --git a/Tests/ImportedSameName/main.c b/Tests/ImportedSameName/main.c
index 33196b7..a0cb27f 100644
--- a/Tests/ImportedSameName/main.c
+++ b/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 b(void);
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1b57f49586afc9e8663d5e146732b1cd0597e7ef
commit 1b57f49586afc9e8663d5e146732b1cd0597e7ef
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 6 16:49:34 2018 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Sep 7 09:23:43 2018 -0400

    genex: Simplify cmGeneratorExpressionInterpreter
    
    All callers were constructing with a non-empty target name using the
    target whose pointer was passed anyway.  Drop this argument.  Simplify
    logic accordingly.  Re-order constructor arguments to match the
    cmCompiledGeneratorExpression::Evaluate arguments.
    
    Also remove unnecessary getters.

diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 14e7927..c4cca07 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -354,8 +354,8 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
   lg->GetTargetCompileFlags(gtgt, config, language, flags);
 
   // Add source file specific flags.
-  cmGeneratorExpressionInterpreter genexInterpreter(lg, gtgt, config,
-                                                    gtgt->GetName(), language);
+  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, gtgt,
+                                                    language);
 
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
   if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
@@ -381,8 +381,8 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
   cmMakefile* makefile = lg->GetMakefile();
   const std::string& language = source->GetLanguage();
   const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  cmGeneratorExpressionInterpreter genexInterpreter(
-    lg, target, config, target->GetName(), language);
+  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
+                                                    language);
 
   // Add the export symbol definition for shared library objects.
   if (const char* exportMacro = target->GetExportMacro()) {
@@ -419,8 +419,8 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes(
   cmMakefile* makefile = lg->GetMakefile();
   const std::string& language = source->GetLanguage();
   const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
-  cmGeneratorExpressionInterpreter genexInterpreter(
-    lg, target, config, target->GetName(), language);
+  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
+                                                    language);
 
   // Add include directories for this source file
   const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 6823cd5..6d83a3f 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -13,6 +13,7 @@
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionLexer.h"
 #include "cmGeneratorExpressionParser.h"
+#include "cmGeneratorTarget.h"
 #include "cmSystemTools.h"
 
 cmGeneratorExpression::cmGeneratorExpression(
@@ -389,14 +390,16 @@ void cmCompiledGeneratorExpression::GetMaxLanguageStandard(
 const std::string& cmGeneratorExpressionInterpreter::Evaluate(
   const char* expression, const std::string& property)
 {
-  if (this->Target.empty()) {
-    return this->EvaluateExpression(expression);
-  }
+  this->CompiledGeneratorExpression =
+    this->GeneratorExpression.Parse(expression);
 
   // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
   cmGeneratorExpressionDAGChecker dagChecker(
-    this->Target, property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property,
-    nullptr, nullptr);
+    this->HeadTarget->GetName(),
+    property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property, nullptr,
+    nullptr);
 
-  return this->EvaluateExpression(expression, &dagChecker);
+  return this->CompiledGeneratorExpression->Evaluate(
+    this->LocalGenerator, this->Config, false, this->HeadTarget, &dagChecker,
+    this->Language);
 }
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 2b7df91..8176d5c 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -160,24 +160,15 @@ class cmGeneratorExpressionInterpreter
 
 public:
   cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator,
-                                   cmGeneratorTarget* generatorTarget,
-                                   const std::string& config,
-                                   const std::string& target,
-                                   const std::string& lang)
+                                   std::string const& config,
+                                   cmGeneratorTarget const* headTarget,
+                                   std::string const& lang = std::string())
     : LocalGenerator(localGenerator)
-    , GeneratorTarget(generatorTarget)
     , Config(config)
-    , Target(target)
+    , HeadTarget(headTarget)
     , Language(lang)
   {
   }
-  cmGeneratorExpressionInterpreter(cmLocalGenerator* localGenerator,
-                                   cmGeneratorTarget* generatorTarget,
-                                   const std::string& config)
-    : cmGeneratorExpressionInterpreter(localGenerator, generatorTarget, config,
-                                       std::string(), std::string())
-  {
-  }
 
   const std::string& Evaluate(const char* expression,
                               const std::string& property);
@@ -188,47 +179,11 @@ public:
   }
 
 protected:
-  cmGeneratorExpression& GetGeneratorExpression()
-  {
-    return this->GeneratorExpression;
-  }
-
-  cmCompiledGeneratorExpression& GetCompiledGeneratorExpression()
-  {
-    return *(this->CompiledGeneratorExpression);
-  }
-
-  cmLocalGenerator* GetLocalGenerator() { return this->LocalGenerator; }
-
-  cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
-
-  const std::string& GetTargetName() const { return this->Target; }
-  const std::string& GetLanguage() const { return this->Language; }
-
-  const std::string& EvaluateExpression(
-    const char* expression,
-    cmGeneratorExpressionDAGChecker* dagChecker = nullptr)
-  {
-    this->CompiledGeneratorExpression =
-      this->GeneratorExpression.Parse(expression);
-
-    if (dagChecker == nullptr) {
-      return this->CompiledGeneratorExpression->Evaluate(
-        this->LocalGenerator, this->Config, false, this->GeneratorTarget);
-    }
-
-    return this->CompiledGeneratorExpression->Evaluate(
-      this->LocalGenerator, this->Config, false, this->GeneratorTarget,
-      dagChecker, this->Language);
-  }
-
-private:
   cmGeneratorExpression GeneratorExpression;
   std::unique_ptr<cmCompiledGeneratorExpression> CompiledGeneratorExpression;
   cmLocalGenerator* LocalGenerator = nullptr;
-  cmGeneratorTarget* GeneratorTarget = nullptr;
   std::string Config;
-  std::string Target;
+  cmGeneratorTarget const* HeadTarget = nullptr;
   std::string Language;
 };
 
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 7456d3c..e353a37 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -751,11 +751,10 @@ class XCodeGeneratorExpressionInterpreter
 public:
   XCodeGeneratorExpressionInterpreter(cmSourceFile* sourceFile,
                                       cmLocalGenerator* localGenerator,
-                                      cmGeneratorTarget* generatorTarget,
+                                      cmGeneratorTarget* headTarget,
                                       const std::string& lang)
-    : cmGeneratorExpressionInterpreter(localGenerator, generatorTarget,
-                                       "NO-PER-CONFIG-SUPPORT-IN-XCODE",
-                                       generatorTarget->GetName(), lang)
+    : cmGeneratorExpressionInterpreter(
+        localGenerator, "NO-PER-CONFIG-SUPPORT-IN-XCODE", headTarget, lang)
     , SourceFile(sourceFile)
   {
   }
@@ -767,8 +766,7 @@ public:
   {
     const std::string& processed =
       this->cmGeneratorExpressionInterpreter::Evaluate(expression, property);
-    if (this->GetCompiledGeneratorExpression()
-          .GetHadContextSensitiveCondition()) {
+    if (this->CompiledGeneratorExpression->GetHadContextSensitiveCondition()) {
       std::ostringstream e;
       /* clang-format off */
       e <<
@@ -777,7 +775,7 @@ public:
           "specified for source:\n"
           "  " << this->SourceFile->GetFullPath() << "\n";
       /* clang-format on */
-      this->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, e.str());
+      this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
     }
 
     return processed;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 13bd214..c05b085 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1497,8 +1497,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
       lang = sourceLang;
     }
 
-    cmGeneratorExpressionInterpreter genexInterpreter(lg, gt, *i,
-                                                      gt->GetName(), lang);
+    cmGeneratorExpressionInterpreter genexInterpreter(lg, *i, gt, lang);
 
     bool needfc = false;
     if (!objectName.empty()) {
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index e8cf255..c8dc392 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -434,8 +434,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
   std::string config = this->LocalGenerator->GetConfigName();
   std::string configUpper = cmSystemTools::UpperCase(config);
   cmGeneratorExpressionInterpreter genexInterpreter(
-    this->LocalGenerator, this->GeneratorTarget, config,
-    this->GeneratorTarget->GetName(), lang);
+    this->LocalGenerator, config, this->GeneratorTarget, lang);
 
   // Add Fortran format flags.
   if (lang == "Fortran") {
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 1cfaac5..ebcc501 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -136,9 +136,8 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
 
   // Add source file specific flags.
   cmGeneratorExpressionInterpreter genexInterpreter(
-    this->LocalGenerator, this->GeneratorTarget,
-    this->LocalGenerator->GetConfigName(), this->GeneratorTarget->GetName(),
-    language);
+    this->LocalGenerator, this->LocalGenerator->GetConfigName(),
+    this->GeneratorTarget, language);
 
   const std::string COMPILE_FLAGS("COMPILE_FLAGS");
   if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
@@ -188,8 +187,7 @@ std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
   std::set<std::string> defines;
   const std::string config = this->LocalGenerator->GetConfigName();
   cmGeneratorExpressionInterpreter genexInterpreter(
-    this->LocalGenerator, this->GeneratorTarget, config,
-    this->GeneratorTarget->GetName(), language);
+    this->LocalGenerator, config, this->GeneratorTarget, language);
 
   const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
   if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
@@ -217,8 +215,7 @@ std::string cmNinjaTargetGenerator::ComputeIncludes(
   std::vector<std::string> includes;
   const std::string config = this->LocalGenerator->GetConfigName();
   cmGeneratorExpressionInterpreter genexInterpreter(
-    this->LocalGenerator, this->GeneratorTarget, config,
-    this->GeneratorTarget->GetName(), language);
+    this->LocalGenerator, config, this->GeneratorTarget, language);
 
   const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
   if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index af4b466..231cacb 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -722,8 +722,8 @@ static void PopulateFileGroupData(
         ? languageDataMap.at(kInterfaceSourcesLanguageDataKey)
         : languageDataMap.at(fileData.Language);
       cmLocalGenerator* lg = target->GetLocalGenerator();
-      cmGeneratorExpressionInterpreter genexInterpreter(
-        lg, target, config, target->GetName(), fileData.Language);
+      cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
+                                                        fileData.Language);
 
       std::string compileFlags = ld.Flags;
       const std::string COMPILE_FLAGS("COMPILE_FLAGS");
@@ -817,7 +817,7 @@ static Json::Value DumpSourceFilesList(
   auto targetProp = target->Target->GetProperty("INTERFACE_SOURCES");
   if (targetProp != nullptr) {
     cmGeneratorExpressionInterpreter genexInterpreter(
-      target->GetLocalGenerator(), target, config, target->GetName(), "");
+      target->GetLocalGenerator(), config, target);
 
     auto evaluatedSources = cmsys::SystemTools::SplitString(
       genexInterpreter.Evaluate(targetProp, "INTERFACE_SOURCES"), ';');
@@ -977,8 +977,7 @@ static void CreateInterfaceSourcesEntry(
   LanguageData& ld = languageDataMap[kInterfaceSourcesLanguageDataKey];
   ld.Language = "";
 
-  cmGeneratorExpressionInterpreter genexInterpreter(lg, target, config,
-                                                    target->GetName(), "");
+  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target);
   std::vector<std::string> propertyValue;
   GetTargetProperty(genexInterpreter, target, "INTERFACE_INCLUDE_DIRECTORIES",
                     propertyValue);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 9e74335..53a2a59 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2117,8 +2117,7 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
         flagtable = gg->GetCSharpFlagTable();
       }
       cmGeneratorExpressionInterpreter genexInterpreter(
-        this->LocalGenerator, this->GeneratorTarget, config,
-        this->GeneratorTarget->GetName(), lang);
+        this->LocalGenerator, config, this->GeneratorTarget, lang);
       cmVS10GeneratorOptions clOptions(
         this->LocalGenerator, cmVisualStudioGeneratorOptions::Compiler,
         flagtable, this);

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bea390e9bd68e1aa7d86b6aef7384f502c39068c
commit bea390e9bd68e1aa7d86b6aef7384f502c39068c
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 6 14:21:06 2018 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Sep 7 09:23:43 2018 -0400

    Fix dependency propagation through same-name imported targets
    
    If two imported targets in different directories have the same name we
    should still be able to propagate transitive link dependencies from
    both.  Fix the target and link dependency analyzers to de-duplicate
    targets using target pointers rather than target names since the
    pointers will not be duplicated even if the names are.
    
    Issue: #18345

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 3659a1e..aa17de6 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -279,12 +279,12 @@ cmComputeLinkDepends::Compute()
   return this->FinalLinkEntries;
 }
 
-std::map<std::string, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
-  std::string const& item)
+std::map<cmLinkItem, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
+  cmLinkItem const& item)
 {
-  std::map<std::string, int>::value_type index_entry(
+  std::map<cmLinkItem, int>::value_type index_entry(
     item, static_cast<int>(this->EntryList.size()));
-  std::map<std::string, int>::iterator lei =
+  std::map<cmLinkItem, int>::iterator lei =
     this->LinkEntryIndex.insert(index_entry).first;
   this->EntryList.emplace_back();
   this->InferredDependSets.push_back(nullptr);
@@ -295,15 +295,14 @@ std::map<std::string, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
 int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
 {
   // Check if the item entry has already been added.
-  std::map<std::string, int>::iterator lei =
-    this->LinkEntryIndex.find(item.AsStr());
+  std::map<cmLinkItem, int>::iterator lei = this->LinkEntryIndex.find(item);
   if (lei != this->LinkEntryIndex.end()) {
     // Yes.  We do not need to follow the item's dependencies again.
     return lei->second;
   }
 
   // Allocate a spot for the item entry.
-  lei = this->AllocateLinkEntry(item.AsStr());
+  lei = this->AllocateLinkEntry(item);
 
   // Initialize the item entry.
   int index = lei->second;
@@ -397,11 +396,11 @@ void cmComputeLinkDepends::QueueSharedDependencies(
 void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
 {
   // Check if the target already has an entry.
-  std::map<std::string, int>::iterator lei =
-    this->LinkEntryIndex.find(dep.Item.AsStr());
+  std::map<cmLinkItem, int>::iterator lei =
+    this->LinkEntryIndex.find(dep.Item);
   if (lei == this->LinkEntryIndex.end()) {
     // Allocate a spot for the item entry.
-    lei = this->AllocateLinkEntry(dep.Item.AsStr());
+    lei = this->AllocateLinkEntry(dep.Item);
 
     // Initialize the item entry.
     LinkEntry& entry = this->EntryList[lei->second];
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index fb3a02f..66fb1e6 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -72,8 +72,8 @@ private:
   std::string Config;
   EntryVector FinalLinkEntries;
 
-  std::map<std::string, int>::iterator AllocateLinkEntry(
-    std::string const& item);
+  std::map<cmLinkItem, int>::iterator AllocateLinkEntry(
+    cmLinkItem const& item);
   int AddLinkEntry(cmLinkItem const& item);
   void AddVarLinkEntries(int depender_index, const char* value);
   void AddDirectLinkEntries();
@@ -83,7 +83,7 @@ private:
 
   // One entry for each unique item.
   std::vector<LinkEntry> EntryList;
-  std::map<std::string, int> LinkEntryIndex;
+  std::map<cmLinkItem, int> LinkEntryIndex;
 
   // BFS of initial dependencies.
   struct BFSEntry
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index edda2bd..268e749 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -195,7 +195,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   // dependencies in all targets, because the generated build-systems can't
   // deal with config-specific dependencies.
   {
-    std::set<std::string> emitted;
+    std::set<cmLinkItem> emitted;
 
     std::vector<std::string> configs;
     depender->Makefile->GetConfigurations(configs);
@@ -206,30 +206,34 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
       std::vector<cmSourceFile const*> objectFiles;
       depender->GetExternalObjects(objectFiles, it);
       for (cmSourceFile const* o : objectFiles) {
-        std::string objLib = o->GetObjectLibrary();
-        if (!objLib.empty() && emitted.insert(objLib).second) {
-          if (depender->GetType() != cmStateEnums::EXECUTABLE &&
-              depender->GetType() != cmStateEnums::STATIC_LIBRARY &&
-              depender->GetType() != cmStateEnums::SHARED_LIBRARY &&
-              depender->GetType() != cmStateEnums::MODULE_LIBRARY &&
-              depender->GetType() != cmStateEnums::OBJECT_LIBRARY) {
-            this->GlobalGenerator->GetCMakeInstance()->IssueMessage(
-              cmake::FATAL_ERROR,
-              "Only executables and libraries may reference target objects.",
-              depender->GetBacktrace());
-            return;
+        std::string const& objLib = o->GetObjectLibrary();
+        if (!objLib.empty()) {
+          cmLinkItem const& objItem = depender->ResolveLinkItem(objLib);
+          if (emitted.insert(objItem).second) {
+            if (depender->GetType() != cmStateEnums::EXECUTABLE &&
+                depender->GetType() != cmStateEnums::STATIC_LIBRARY &&
+                depender->GetType() != cmStateEnums::SHARED_LIBRARY &&
+                depender->GetType() != cmStateEnums::MODULE_LIBRARY &&
+                depender->GetType() != cmStateEnums::OBJECT_LIBRARY) {
+              this->GlobalGenerator->GetCMakeInstance()->IssueMessage(
+                cmake::FATAL_ERROR,
+                "Only executables and libraries may reference target objects.",
+                depender->GetBacktrace());
+              return;
+            }
+            const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(
+              objLib);
           }
-          const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(objLib);
         }
       }
 
       cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
 
       // A target should not depend on itself.
-      emitted.insert(depender->GetName());
+      emitted.insert(cmLinkItem(depender));
       for (cmLinkImplItem const& lib : impl->Libraries) {
         // Don't emit the same library twice for this target.
-        if (emitted.insert(lib.AsStr()).second) {
+        if (emitted.insert(lib).second) {
           this->AddTargetDepend(depender_index, lib, true);
           this->AddInterfaceDepends(depender_index, lib, it, emitted);
         }
@@ -240,12 +244,12 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
   // Loop over all utility dependencies.
   {
     std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
-    std::set<std::string> emitted;
+    std::set<cmLinkItem> emitted;
     // A target should not depend on itself.
-    emitted.insert(depender->GetName());
+    emitted.insert(cmLinkItem(depender));
     for (cmLinkItem const& litem : tutils) {
       // Don't emit the same utility twice for this target.
-      if (emitted.insert(litem.AsStr()).second) {
+      if (emitted.insert(litem).second) {
         this->AddTargetDepend(depender_index, litem, false);
       }
     }
@@ -254,14 +258,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
 
 void cmComputeTargetDepends::AddInterfaceDepends(
   int depender_index, const cmGeneratorTarget* dependee,
-  const std::string& config, std::set<std::string>& emitted)
+  const std::string& config, std::set<cmLinkItem>& emitted)
 {
   cmGeneratorTarget const* depender = this->Targets[depender_index];
   if (cmLinkInterface const* iface =
         dependee->GetLinkInterface(config, depender)) {
     for (cmLinkItem const& lib : iface->Libraries) {
       // Don't emit the same library twice for this target.
-      if (emitted.insert(lib.AsStr()).second) {
+      if (emitted.insert(lib).second) {
         this->AddTargetDepend(depender_index, lib, true);
         this->AddInterfaceDepends(depender_index, lib, config, emitted);
       }
@@ -271,7 +275,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
 
 void cmComputeTargetDepends::AddInterfaceDepends(
   int depender_index, cmLinkItem const& dependee_name,
-  const std::string& config, std::set<std::string>& emitted)
+  const std::string& config, std::set<cmLinkItem>& emitted)
 {
   cmGeneratorTarget const* depender = this->Targets[depender_index];
   cmGeneratorTarget const* dependee = dependee_name.Target;
@@ -285,7 +289,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
 
   if (dependee) {
     // A target should not depend on itself.
-    emitted.insert(depender->GetName());
+    emitted.insert(cmLinkItem(depender));
     this->AddInterfaceDepends(depender_index, dependee, config, emitted);
   }
 }
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index e93e376..3046e8a 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -51,11 +51,11 @@ private:
   bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
   void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name,
                            const std::string& config,
-                           std::set<std::string>& emitted);
+                           std::set<cmLinkItem>& emitted);
   void AddInterfaceDepends(int depender_index,
                            cmGeneratorTarget const* dependee,
                            const std::string& config,
-                           std::set<std::string>& emitted);
+                           std::set<cmLinkItem>& emitted);
   cmGlobalGenerator* GlobalGenerator;
   bool DebugMode;
   bool NoCycles;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 377c008..080ff1c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4575,14 +4575,14 @@ void cmGeneratorTarget::ComputeLinkInterface(
         this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       // Shared libraries may have runtime implementation dependencies
       // on other shared libraries that are not in the interface.
-      std::unordered_set<std::string> emitted;
+      std::set<cmLinkItem> emitted;
       for (cmLinkItem const& lib : iface.Libraries) {
-        emitted.insert(lib.AsStr());
+        emitted.insert(lib);
       }
       if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
         cmLinkImplementation const* impl = this->GetLinkImplementation(config);
         for (cmLinkImplItem const& lib : impl->Libraries) {
-          if (emitted.insert(lib.AsStr()).second) {
+          if (emitted.insert(lib).second) {
             if (lib.Target) {
               // This is a runtime dependency on another shared library.
               if (lib.Target->GetType() == cmStateEnums::SHARED_LIBRARY) {
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 971d7ff..a22521b 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -396,6 +396,7 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
   ADD_TEST_MACRO(AliasTarget AliasTarget)
   ADD_TEST_MACRO(StagingPrefix StagingPrefix)
+  ADD_TEST_MACRO(ImportedSameName ImportedSameName)
   ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
   if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
     set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
diff --git a/Tests/ImportedSameName/A/CMakeLists.txt b/Tests/ImportedSameName/A/CMakeLists.txt
new file mode 100644
index 0000000..9417a2c
--- /dev/null
+++ b/Tests/ImportedSameName/A/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_library(a STATIC a.c)
+
+add_library(sameName INTERFACE IMPORTED)
+target_link_libraries(sameName INTERFACE a)
+
+add_library(ifaceA INTERFACE)
+target_link_libraries(ifaceA INTERFACE sameName)
diff --git a/Tests/ImportedSameName/A/a.c b/Tests/ImportedSameName/A/a.c
new file mode 100644
index 0000000..4ef3698
--- /dev/null
+++ b/Tests/ImportedSameName/A/a.c
@@ -0,0 +1,3 @@
+void a(void)
+{
+}
diff --git a/Tests/ImportedSameName/B/CMakeLists.txt b/Tests/ImportedSameName/B/CMakeLists.txt
new file mode 100644
index 0000000..6947fa9
--- /dev/null
+++ b/Tests/ImportedSameName/B/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_library(b STATIC b.c)
+
+add_library(sameName INTERFACE IMPORTED)
+target_link_libraries(sameName INTERFACE b)
+
+add_library(ifaceB INTERFACE)
+target_link_libraries(ifaceB INTERFACE sameName)
diff --git a/Tests/ImportedSameName/B/b.c b/Tests/ImportedSameName/B/b.c
new file mode 100644
index 0000000..c7c7df4
--- /dev/null
+++ b/Tests/ImportedSameName/B/b.c
@@ -0,0 +1,3 @@
+void b(void)
+{
+}
diff --git a/Tests/ImportedSameName/CMakeLists.txt b/Tests/ImportedSameName/CMakeLists.txt
new file mode 100644
index 0000000..4292c12
--- /dev/null
+++ b/Tests/ImportedSameName/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.12)
+project(ImportedSameName C)
+
+add_subdirectory(A)
+add_subdirectory(B)
+
+add_executable(ImportedSameName main.c)
+target_link_libraries(ImportedSameName PRIVATE ifaceA ifaceB)
diff --git a/Tests/ImportedSameName/main.c b/Tests/ImportedSameName/main.c
new file mode 100644
index 0000000..33196b7
--- /dev/null
+++ b/Tests/ImportedSameName/main.c
@@ -0,0 +1,9 @@
+extern void a(void);
+extern void b(void);
+
+int main(void)
+{
+  a();
+  b();
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fc7e4d1ed85370d03acbd62bc753cced3550752b
commit fc7e4d1ed85370d03acbd62bc753cced3550752b
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Sep 6 13:10:55 2018 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Sep 7 08:57:51 2018 -0400

    cmLinkItem: Convert to a "sum type" over a string and target pointer
    
    Avoid exposing the item name implicitly as std::string.  When the item
    is a target, avoid storing a second copy of its name.
    
    Most link item construction is paired with calls to `FindTargetToLink`
    to get the possible target pointer.  Rename these methods to
    `ResolveLinkItem` and refactor them to construct the entire item.

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 0457984..628cc6f 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -265,6 +265,7 @@ set(SRCS
   cmInstallDirectoryGenerator.h
   cmInstallDirectoryGenerator.cxx
   cmLinkedTree.h
+  cmLinkItem.cxx
   cmLinkItem.h
   cmLinkLineComputer.cxx
   cmLinkLineComputer.h
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index b1f3860..3659a1e 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -295,22 +295,24 @@ std::map<std::string, int>::iterator cmComputeLinkDepends::AllocateLinkEntry(
 int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
 {
   // Check if the item entry has already been added.
-  std::map<std::string, int>::iterator lei = this->LinkEntryIndex.find(item);
+  std::map<std::string, int>::iterator lei =
+    this->LinkEntryIndex.find(item.AsStr());
   if (lei != this->LinkEntryIndex.end()) {
     // Yes.  We do not need to follow the item's dependencies again.
     return lei->second;
   }
 
   // Allocate a spot for the item entry.
-  lei = this->AllocateLinkEntry(item);
+  lei = this->AllocateLinkEntry(item.AsStr());
 
   // Initialize the item entry.
   int index = lei->second;
   LinkEntry& entry = this->EntryList[index];
-  entry.Item = item;
+  entry.Item = item.AsStr();
   entry.Target = item.Target;
-  entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
-                  item.substr(0, 10) != "-framework");
+  entry.IsFlag =
+    (!entry.Target && entry.Item[0] == '-' && entry.Item[1] != 'l' &&
+     entry.Item.substr(0, 10) != "-framework");
 
   // If the item has dependencies queue it to follow them.
   if (entry.Target) {
@@ -396,14 +398,14 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
 {
   // Check if the target already has an entry.
   std::map<std::string, int>::iterator lei =
-    this->LinkEntryIndex.find(dep.Item);
+    this->LinkEntryIndex.find(dep.Item.AsStr());
   if (lei == this->LinkEntryIndex.end()) {
     // Allocate a spot for the item entry.
-    lei = this->AllocateLinkEntry(dep.Item);
+    lei = this->AllocateLinkEntry(dep.Item.AsStr());
 
     // Initialize the item entry.
     LinkEntry& entry = this->EntryList[lei->second];
-    entry.Item = dep.Item;
+    entry.Item = dep.Item.AsStr();
     entry.Target = dep.Item.Target;
 
     // This item was added specifically because it is a dependent
@@ -473,9 +475,9 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
 
       // If the library is meant for this link type then use it.
       if (llt == GENERAL_LibraryType || llt == this->LinkType) {
-        actual_libs.emplace_back(d, this->FindTargetToLink(depender_index, d));
+        actual_libs.emplace_back(this->ResolveLinkItem(depender_index, d));
       } else if (this->OldLinkDirMode) {
-        cmLinkItem item(d, this->FindTargetToLink(depender_index, d));
+        cmLinkItem item = this->ResolveLinkItem(depender_index, d);
         this->CheckWrongConfigItem(item);
       }
 
@@ -512,7 +514,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
     // Skip entries that will resolve to the target getting linked or
     // are empty.
     cmLinkItem const& item = l;
-    if (item == this->Target->GetName() || item.empty()) {
+    if (item.AsStr() == this->Target->GetName() || item.AsStr().empty()) {
       continue;
     }
 
@@ -553,8 +555,8 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
   }
 }
 
-cmGeneratorTarget const* cmComputeLinkDepends::FindTargetToLink(
-  int depender_index, const std::string& name)
+cmLinkItem cmComputeLinkDepends::ResolveLinkItem(int depender_index,
+                                                 const std::string& name)
 {
   // Look for a target in the scope of the depender.
   cmGeneratorTarget const* from = this->Target;
@@ -564,7 +566,7 @@ cmGeneratorTarget const* cmComputeLinkDepends::FindTargetToLink(
       from = depender;
     }
   }
-  return from->FindTargetToLink(name);
+  return from->ResolveLinkItem(name);
 }
 
 void cmComputeLinkDepends::InferDependencies()
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index dd0e029..fb3a02f 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -79,8 +79,7 @@ private:
   void AddDirectLinkEntries();
   template <typename T>
   void AddLinkEntries(int depender_index, std::vector<T> const& libs);
-  cmGeneratorTarget const* FindTargetToLink(int depender_index,
-                                            const std::string& name);
+  cmLinkItem ResolveLinkItem(int depender_index, const std::string& name);
 
   // One entry for each unique item.
   std::vector<LinkEntry> EntryList;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index efdd3a5..edda2bd 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -229,7 +229,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
       emitted.insert(depender->GetName());
       for (cmLinkImplItem const& lib : impl->Libraries) {
         // Don't emit the same library twice for this target.
-        if (emitted.insert(lib).second) {
+        if (emitted.insert(lib.AsStr()).second) {
           this->AddTargetDepend(depender_index, lib, true);
           this->AddInterfaceDepends(depender_index, lib, it, emitted);
         }
@@ -245,7 +245,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
     emitted.insert(depender->GetName());
     for (cmLinkItem const& litem : tutils) {
       // Don't emit the same utility twice for this target.
-      if (emitted.insert(litem).second) {
+      if (emitted.insert(litem.AsStr()).second) {
         this->AddTargetDepend(depender_index, litem, false);
       }
     }
@@ -261,7 +261,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
         dependee->GetLinkInterface(config, depender)) {
     for (cmLinkItem const& lib : iface->Libraries) {
       // Don't emit the same library twice for this target.
-      if (emitted.insert(lib).second) {
+      if (emitted.insert(lib.AsStr()).second) {
         this->AddTargetDepend(depender_index, lib, true);
         this->AddInterfaceDepends(depender_index, lib, config, emitted);
       }
@@ -324,7 +324,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
         << depender->GetName() << "\" does not exist.";
 
       cmListFileBacktrace const* backtrace =
-        depender->GetUtilityBacktrace(dependee_name);
+        depender->GetUtilityBacktrace(dependee_name.AsStr());
       if (backtrace) {
         cm->IssueMessage(messageType, e.str(), *backtrace);
       } else {
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 75d3374..1c5040a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -831,6 +831,16 @@ void cmExportFileGenerator::SetImportDetailProperties(
   }
 }
 
+static std::string const& asString(std::string const& l)
+{
+  return l;
+}
+
+static std::string const& asString(cmLinkItem const& l)
+{
+  return l.AsStr();
+}
+
 template <typename T>
 void cmExportFileGenerator::SetImportLinkProperty(
   std::string const& suffix, cmGeneratorTarget* target,
@@ -850,7 +860,7 @@ void cmExportFileGenerator::SetImportLinkProperty(
     link_entries += sep;
     sep = ";";
 
-    std::string temp = l;
+    std::string temp = asString(l);
     this->AddTargetNamespace(temp, target, missingTargets);
     link_entries += temp;
   }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 80a99d5..377c008 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -671,9 +671,12 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
     this->UtilityItemsDone = true;
     std::set<std::string> const& utilities = this->GetUtilities();
     for (std::string const& i : utilities) {
-      cmGeneratorTarget* gt =
-        this->LocalGenerator->FindGeneratorTargetToUse(i);
-      this->UtilityItems.insert(cmLinkItem(i, gt));
+      if (cmGeneratorTarget* gt =
+            this->LocalGenerator->FindGeneratorTargetToUse(i)) {
+        this->UtilityItems.insert(cmLinkItem(gt));
+      } else {
+        this->UtilityItems.insert(cmLinkItem(i));
+      }
     }
   }
   return this->UtilityItems;
@@ -816,7 +819,8 @@ static void AddInterfaceEntries(
         thisTarget->GetLinkImplementationLibraries(config)) {
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target) {
-        std::string genex = "$<TARGET_PROPERTY:" + lib + "," + prop + ">";
+        std::string genex =
+          "$<TARGET_PROPERTY:" + lib.AsStr() + "," + prop + ">";
         cmGeneratorExpression ge(lib.Backtrace);
         std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
         cge->SetEvaluateForBuildsystem(true);
@@ -836,7 +840,7 @@ static void AddObjectEntries(
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target &&
           lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
-        std::string genex = "$<TARGET_OBJECTS:" + lib + ">";
+        std::string genex = "$<TARGET_OBJECTS:" + lib.AsStr() + ">";
         cmGeneratorExpression ge(lib.Backtrace);
         std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
         cge->SetEvaluateForBuildsystem(true);
@@ -860,7 +864,7 @@ static bool processSources(
 
   for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
     cmLinkImplItem const& item = entry->LinkImplItem;
-    std::string const& targetName = item;
+    std::string const& targetName = item.AsStr();
     std::vector<std::string> entrySources;
     cmSystemTools::ExpandListArgument(
       entry->ge->Evaluate(tgt->GetLocalGenerator(), config, false, tgt, tgt,
@@ -1756,7 +1760,7 @@ public:
   void Visit(cmLinkItem const& item)
   {
     if (!item.Target) {
-      if (item.find("::") != std::string::npos) {
+      if (item.AsStr().find("::") != std::string::npos) {
         bool noMessage = false;
         cmake::MessageType messageType = cmake::FATAL_ERROR;
         std::ostringstream e;
@@ -1777,7 +1781,7 @@ public:
 
         if (!noMessage) {
           e << "Target \"" << this->Target->GetName()
-            << "\" links to target \"" << item
+            << "\" links to target \"" << item.AsStr()
             << "\" but the target was not found.  Perhaps a find_package() "
                "call is missing for an IMPORTED target, or an ALIAS target is "
                "missing?";
@@ -2477,7 +2481,7 @@ static void processIncludeDirectories(
 {
   for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
     cmLinkImplItem const& item = entry->LinkImplItem;
-    std::string const& targetName = item;
+    std::string const& targetName = item.AsStr();
     bool const fromImported = item.Target && item.Target->IsImported();
     bool const checkCMP0027 = item.FromGenex;
     std::vector<std::string> entryIncludes;
@@ -2615,7 +2619,7 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
     cmLinkImplementationLibraries const* impl =
       this->GetLinkImplementationLibraries(config);
     for (cmLinkImplItem const& lib : impl->Libraries) {
-      std::string libDir = cmSystemTools::CollapseFullPath(lib);
+      std::string libDir = cmSystemTools::CollapseFullPath(lib.AsStr());
 
       static cmsys::RegularExpression frameworkCheck(
         "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
@@ -4495,7 +4499,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
     if (name == this->GetName() || name.empty()) {
       continue;
     }
-    items.emplace_back(name, this->FindTargetToLink(name));
+    items.push_back(this->ResolveLinkItem(name));
   }
 }
 
@@ -4573,12 +4577,12 @@ void cmGeneratorTarget::ComputeLinkInterface(
       // on other shared libraries that are not in the interface.
       std::unordered_set<std::string> emitted;
       for (cmLinkItem const& lib : iface.Libraries) {
-        emitted.insert(lib);
+        emitted.insert(lib.AsStr());
       }
       if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
         cmLinkImplementation const* impl = this->GetLinkImplementation(config);
         for (cmLinkImplItem const& lib : impl->Libraries) {
-          if (emitted.insert(lib).second) {
+          if (emitted.insert(lib.AsStr()).second) {
             if (lib.Target) {
               // This is a runtime dependency on another shared library.
               if (lib.Target->GetType() == cmStateEnums::SHARED_LIBRARY) {
@@ -5603,7 +5607,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
       }
 
       // The entry is meant for this configuration.
-      impl.Libraries.emplace_back(name, this->FindTargetToLink(name), *btIt,
+      impl.Libraries.emplace_back(this->ResolveLinkItem(name), *btIt,
                                   evaluated != *le);
     }
 
@@ -5631,14 +5635,12 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
         continue;
       }
       // Support OLD behavior for CMP0003.
-      impl.WrongConfigLibraries.emplace_back(name,
-                                             this->FindTargetToLink(name));
+      impl.WrongConfigLibraries.push_back(this->ResolveLinkItem(name));
     }
   }
 }
 
-cmGeneratorTarget* cmGeneratorTarget::FindTargetToLink(
-  std::string const& name) const
+cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name) const
 {
   cmGeneratorTarget* tgt =
     this->LocalGenerator->FindGeneratorTargetToUse(name);
@@ -5651,7 +5653,11 @@ cmGeneratorTarget* cmGeneratorTarget::FindTargetToLink(
     tgt = nullptr;
   }
 
-  return tgt;
+  if (tgt) {
+    return cmLinkItem(tgt);
+  }
+
+  return cmLinkItem(name);
 }
 
 std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 1030d91..a847e21 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -357,7 +357,7 @@ public:
                                           cmOptionalLinkImplementation& impl,
                                           const cmGeneratorTarget* head) const;
 
-  cmGeneratorTarget* FindTargetToLink(std::string const& name) const;
+  cmLinkItem ResolveLinkItem(std::string const& name) const;
 
   // Compute the set of languages compiled by the target.  This is
   // computed every time it is called because the languages can change
diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx
new file mode 100644
index 0000000..69b6821
--- /dev/null
+++ b/Source/cmLinkItem.cxx
@@ -0,0 +1,72 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#include "cmLinkItem.h"
+
+#include "cmGeneratorTarget.h"
+
+#include <utility> // IWYU pragma: keep
+
+cmLinkItem::cmLinkItem()
+  : String()
+  , Target(nullptr)
+{
+}
+
+cmLinkItem::cmLinkItem(std::string const& n)
+  : String(n)
+  , Target(nullptr)
+{
+}
+
+cmLinkItem::cmLinkItem(cmGeneratorTarget const* t)
+  : String()
+  , Target(t)
+{
+}
+
+std::string const& cmLinkItem::AsStr() const
+{
+  return this->Target ? this->Target->GetName() : this->String;
+}
+
+bool operator<(cmLinkItem const& l, cmLinkItem const& r)
+{
+  // Order among targets.
+  if (l.Target && r.Target) {
+    return l.Target < r.Target;
+  }
+  // Order targets before strings.
+  if (l.Target) {
+    return true;
+  }
+  if (r.Target) {
+    return false;
+  }
+  // Order among strings.
+  return l.String < r.String;
+}
+
+bool operator==(cmLinkItem const& l, cmLinkItem const& r)
+{
+  return l.Target == r.Target && l.String == r.String;
+}
+
+std::ostream& operator<<(std::ostream& os, cmLinkItem const& item)
+{
+  return os << item.AsStr();
+}
+
+cmLinkImplItem::cmLinkImplItem()
+  : cmLinkItem()
+  , Backtrace()
+  , FromGenex(false)
+{
+}
+
+cmLinkImplItem::cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt,
+                               bool fromGenex)
+  : cmLinkItem(std::move(item))
+  , Backtrace(bt)
+  , FromGenex(fromGenex)
+{
+}
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index e8c9487..74fd298 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -7,6 +7,7 @@
 
 #include <algorithm>
 #include <map>
+#include <ostream>
 #include <string>
 #include <vector>
 
@@ -17,40 +18,27 @@
 class cmGeneratorTarget;
 
 // Basic information about each link item.
-class cmLinkItem : public std::string
+class cmLinkItem
 {
-  typedef std::string std_string;
+  std::string String;
 
 public:
-  cmLinkItem()
-    : std_string()
-    , Target(nullptr)
-  {
-  }
-  cmLinkItem(const std_string& n, cmGeneratorTarget const* t)
-    : std_string(n)
-    , Target(t)
-  {
-  }
+  cmLinkItem();
+  explicit cmLinkItem(std::string const& s);
+  explicit cmLinkItem(cmGeneratorTarget const* t);
+  std::string const& AsStr() const;
   cmGeneratorTarget const* Target;
+  friend bool operator<(cmLinkItem const& l, cmLinkItem const& r);
+  friend bool operator==(cmLinkItem const& l, cmLinkItem const& r);
+  friend std::ostream& operator<<(std::ostream& os, cmLinkItem const& item);
 };
 
 class cmLinkImplItem : public cmLinkItem
 {
 public:
-  cmLinkImplItem()
-    : cmLinkItem()
-    , Backtrace()
-    , FromGenex(false)
-  {
-  }
-  cmLinkImplItem(std::string const& n, cmGeneratorTarget const* t,
-                 cmListFileBacktrace const& bt, bool fromGenex)
-    : cmLinkItem(n, t)
-    , Backtrace(bt)
-    , FromGenex(fromGenex)
-  {
-  }
+  cmLinkImplItem();
+  cmLinkImplItem(cmLinkItem item, cmListFileBacktrace const& bt,
+                 bool fromGenex);
   cmListFileBacktrace Backtrace;
   bool FromGenex;
 };
diff --git a/bootstrap b/bootstrap
index 0b49b74..188193d 100755
--- a/bootstrap
+++ b/bootstrap
@@ -352,6 +352,7 @@ CMAKE_CXX_SOURCES="\
   cmInstallTargetsCommand \
   cmInstalledFile \
   cmLinkDirectoriesCommand \
+  cmLinkItem \
   cmLinkLineComputer \
   cmListCommand \
   cmListFileCache \

-----------------------------------------------------------------------

Summary of changes:
 Modules/FindMPI.cmake                              |  2 +-
 Source/CMakeLists.txt                              |  1 +
 Source/cmCTest.cxx                                 |  6 +-
 Source/cmComputeLinkDepends.cxx                    | 33 ++++----
 Source/cmComputeLinkDepends.h                      |  9 +--
 Source/cmComputeTargetDepends.cxx                  | 46 ++++++------
 Source/cmComputeTargetDepends.h                    |  4 +-
 Source/cmExportBuildAndroidMKGenerator.cxx         |  2 +-
 Source/cmExportFileGenerator.cxx                   | 12 ++-
 Source/cmExportTryCompileFileGenerator.cxx         |  3 +-
 Source/cmExtraSublimeTextGenerator.cxx             | 12 +--
 Source/cmGeneratorExpression.cxx                   | 14 ++--
 Source/cmGeneratorExpression.h                     | 55 ++------------
 Source/cmGeneratorExpressionDAGChecker.cxx         | 13 ++--
 Source/cmGeneratorExpressionDAGChecker.h           | 13 ++--
 Source/cmGeneratorExpressionNode.cxx               | 13 ++--
 Source/cmGeneratorTarget.cxx                       | 87 ++++++++++++----------
 Source/cmGeneratorTarget.h                         |  2 +-
 Source/cmGlobalXCodeGenerator.cxx                  | 12 ++-
 Source/cmLinkItem.cxx                              | 72 ++++++++++++++++++
 Source/cmLinkItem.h                                | 38 ++++------
 Source/cmLocalVisualStudio7Generator.cxx           |  3 +-
 Source/cmMakefileTargetGenerator.cxx               |  3 +-
 Source/cmNinjaTargetGenerator.cxx                  | 11 +--
 Source/cmServerProtocol.cxx                        |  9 +--
 Source/cmVisualStudio10TargetGenerator.cxx         |  3 +-
 Tests/CMakeLists.txt                               |  1 +
 Tests/ImportedSameName/A/CMakeLists.txt            |  8 ++
 Tests/ImportedSameName/A/a.c                       |  3 +
 Tests/ImportedSameName/B/CMakeLists.txt            |  8 ++
 Tests/ImportedSameName/B/b.c                       |  3 +
 Tests/ImportedSameName/CMakeLists.txt              |  8 ++
 Tests/ImportedSameName/main.c                      | 16 ++++
 .../ctest_start/NoAppendDifferentTrack-stdout.txt  |  8 ++
 Tests/RunCMake/ctest_start/RunCMakeTest.cmake      |  1 +
 Tests/RunCMake/ctest_start/test.cmake.in           |  2 +-
 bootstrap                                          |  1 +
 37 files changed, 312 insertions(+), 225 deletions(-)
 create mode 100644 Source/cmLinkItem.cxx
 create mode 100644 Tests/ImportedSameName/A/CMakeLists.txt
 create mode 100644 Tests/ImportedSameName/A/a.c
 create mode 100644 Tests/ImportedSameName/B/CMakeLists.txt
 create mode 100644 Tests/ImportedSameName/B/b.c
 create mode 100644 Tests/ImportedSameName/CMakeLists.txt
 create mode 100644 Tests/ImportedSameName/main.c
 create mode 100644 Tests/RunCMake/ctest_start/NoAppendDifferentTrack-stdout.txt


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list