Ver Fonte

target_link_libraries: Restore transitive out-of-dir linking

Refactoring in commit 7f506b95a7 (cmGeneratorTarget: Refactor link item
lookup, 2021-05-26, v3.21.0-rc1~103^2~4) accidentally dropped the
persistent lookup scope tracking across multiple items that was added by
commit f0e67da061 (target_link_libraries: Fix out-of-dir linking of a
list of targets, 2020-01-14, v3.17.0-rc1~149^2).  This broke a
transitive out-of-dir linking case not covered by our test suite.
Restore the scope tracking and add a test case.

Fixes: #22363
Brad King há 4 anos atrás
pai
commit
e27a76f131

+ 8 - 6
Source/cmGeneratorTarget.cxx

@@ -6346,11 +6346,11 @@ bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n,
 }
 }
 
 
 cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
 cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
-  std::string const& n, cmListFileBacktrace const& bt) const
+  std::string const& n, cmListFileBacktrace const& bt,
+  LookupLinkItemScope* scope) const
 {
 {
   cm::optional<cmLinkItem> maybeItem;
   cm::optional<cmLinkItem> maybeItem;
-  cmLocalGenerator const* lg = this->LocalGenerator;
-  if (this->IsLinkLookupScope(n, lg)) {
+  if (this->IsLinkLookupScope(n, scope->LG)) {
     return maybeItem;
     return maybeItem;
   }
   }
 
 
@@ -6358,7 +6358,7 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
   if (name == this->GetName() || name.empty()) {
   if (name == this->GetName() || name.empty()) {
     return maybeItem;
     return maybeItem;
   }
   }
-  maybeItem = this->ResolveLinkItem(name, bt, lg);
+  maybeItem = this->ResolveLinkItem(name, bt, scope->LG);
   return maybeItem;
   return maybeItem;
 }
 }
 
 
@@ -6385,9 +6385,10 @@ void cmGeneratorTarget::ExpandLinkItems(
                              &dagChecker, this, headTarget->LinkerLanguage),
                              &dagChecker, this, headTarget->LinkerLanguage),
                libs);
                libs);
   cmMakefile const* mf = this->LocalGenerator->GetMakefile();
   cmMakefile const* mf = this->LocalGenerator->GetMakefile();
+  LookupLinkItemScope scope{ this->LocalGenerator };
   for (std::string const& lib : libs) {
   for (std::string const& lib : libs) {
     if (cm::optional<cmLinkItem> maybeItem =
     if (cm::optional<cmLinkItem> maybeItem =
-          this->LookupLinkItem(lib, cge->GetBacktrace())) {
+          this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) {
       if (!maybeItem->Target) {
       if (!maybeItem->Target) {
         // Report explicitly linked object files separately.
         // Report explicitly linked object files separately.
         std::string const& maybeObj = maybeItem->AsStr();
         std::string const& maybeObj = maybeItem->AsStr();
@@ -7089,9 +7090,10 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
                           iface.HadContextSensitiveCondition,
                           iface.HadContextSensitiveCondition,
                           iface.HadLinkLanguageSensitiveCondition);
                           iface.HadLinkLanguageSensitiveCondition);
     std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
     std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
+    LookupLinkItemScope scope{ this->LocalGenerator };
     for (std::string const& dep : deps) {
     for (std::string const& dep : deps) {
       if (cm::optional<cmLinkItem> maybeItem =
       if (cm::optional<cmLinkItem> maybeItem =
-            this->LookupLinkItem(dep, cmListFileBacktrace())) {
+            this->LookupLinkItem(dep, cmListFileBacktrace(), &scope)) {
         iface.SharedDeps.emplace_back(std::move(*maybeItem));
         iface.SharedDeps.emplace_back(std::move(*maybeItem));
       }
       }
     }
     }

+ 6 - 1
Source/cmGeneratorTarget.h

@@ -1042,8 +1042,13 @@ private:
                        bool& hadHeadSensitiveCondition,
                        bool& hadHeadSensitiveCondition,
                        bool& hadContextSensitiveCondition,
                        bool& hadContextSensitiveCondition,
                        bool& hadLinkLanguageSensitiveCondition) const;
                        bool& hadLinkLanguageSensitiveCondition) const;
+  struct LookupLinkItemScope
+  {
+    cmLocalGenerator const* LG;
+  };
   cm::optional<cmLinkItem> LookupLinkItem(std::string const& n,
   cm::optional<cmLinkItem> LookupLinkItem(std::string const& n,
-                                          cmListFileBacktrace const& bt) const;
+                                          cmListFileBacktrace const& bt,
+                                          LookupLinkItemScope* scope) const;
 
 
   std::vector<BT<std::string>> GetSourceFilePaths(
   std::vector<BT<std::string>> GetSourceFilePaths(
     std::string const& config) const;
     std::string const& config) const;

+ 2 - 0
Tests/CMakeCommands/target_link_libraries/CMakeLists.txt

@@ -140,6 +140,8 @@ cmake_policy(PUSH)
 cmake_policy(SET CMP0022 NEW)
 cmake_policy(SET CMP0022 NEW)
 cmake_policy(SET CMP0079 NEW)
 cmake_policy(SET CMP0079 NEW)
 add_executable(TopDir TopDir.c)
 add_executable(TopDir TopDir.c)
+add_library(TopDirInterface INTERFACE)
+target_link_libraries(TopDir PRIVATE TopDirInterface)
 add_subdirectory(SubDirA)
 add_subdirectory(SubDirA)
 add_subdirectory(SubDirB)
 add_subdirectory(SubDirB)
 target_link_libraries(SubDirB TopDirImported)
 target_link_libraries(SubDirB TopDirImported)

+ 4 - 0
Tests/CMakeCommands/target_link_libraries/SubDirA/CMakeLists.txt

@@ -3,6 +3,8 @@ add_executable(SubDirA SubDirA.c)
 # Link to a target imported in this directory that would not normally
 # Link to a target imported in this directory that would not normally
 # be visible to the directory in which TopDir is defined.
 # be visible to the directory in which TopDir is defined.
 target_link_libraries(TopDir PUBLIC SameNameImported)
 target_link_libraries(TopDir PUBLIC SameNameImported)
+# Do the same through an interface library in the top.
+target_link_libraries(TopDirInterface INTERFACE SameNameImported2)
 
 
 # Link SubDirA to a target imported in this directory that has the same
 # Link SubDirA to a target imported in this directory that has the same
 # name as a target imported in SubDirB's directory.  SubDirB will also
 # name as a target imported in SubDirB's directory.  SubDirB will also
@@ -13,3 +15,5 @@ target_link_libraries(SubDirA PRIVATE SameNameImported)
 # Distinguish this copy by having a unique usage requirement.
 # Distinguish this copy by having a unique usage requirement.
 add_library(SameNameImported IMPORTED INTERFACE)
 add_library(SameNameImported IMPORTED INTERFACE)
 target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirA)
 target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirA)
+add_library(SameNameImported2 INTERFACE IMPORTED)
+target_compile_definitions(SameNameImported2 INTERFACE DEF_SameNameImported2SubDirA)

+ 4 - 0
Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt

@@ -3,6 +3,8 @@ add_executable(SubDirB SubDirB.c)
 # Link to a target imported in this directory that would not normally
 # Link to a target imported in this directory that would not normally
 # be visible to the directory in which TopDir is defined.
 # be visible to the directory in which TopDir is defined.
 target_link_libraries(TopDir PUBLIC debug SameNameImported optimized SameNameImported)
 target_link_libraries(TopDir PUBLIC debug SameNameImported optimized SameNameImported)
+# Do the same through an interface library in the top.
+target_link_libraries(TopDirInterface INTERFACE debug SameNameImported2 optimized SameNameImported2)
 
 
 # Link to a list of targets imported in this directory that would not
 # Link to a list of targets imported in this directory that would not
 # normally be visible to the directory in which TopDir is defined.
 # normally be visible to the directory in which TopDir is defined.
@@ -17,3 +19,5 @@ target_link_libraries(SubDirA PRIVATE SameNameImported)
 # Distinguish this copy by having a unique usage requirement.
 # Distinguish this copy by having a unique usage requirement.
 add_library(SameNameImported IMPORTED INTERFACE)
 add_library(SameNameImported IMPORTED INTERFACE)
 target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirB)
 target_compile_definitions(SameNameImported INTERFACE DEF_SameNameImportedSubDirB)
+add_library(SameNameImported2 INTERFACE IMPORTED)
+target_compile_definitions(SameNameImported2 INTERFACE DEF_SameNameImported2SubDirB)

+ 6 - 0
Tests/CMakeCommands/target_link_libraries/TopDir.c

@@ -4,6 +4,12 @@
 #ifndef DEF_SameNameImportedSubDirB
 #ifndef DEF_SameNameImportedSubDirB
 #  error "DEF_SameNameImportedSubDirB is not defined but should be!"
 #  error "DEF_SameNameImportedSubDirB is not defined but should be!"
 #endif
 #endif
+#ifndef DEF_SameNameImported2SubDirA
+#  error "DEF_SameNameImported2SubDirA is not defined but should be!"
+#endif
+#ifndef DEF_SameNameImported2SubDirB
+#  error "DEF_SameNameImported2SubDirB is not defined but should be!"
+#endif
 #ifdef DEF_TopDirImported
 #ifdef DEF_TopDirImported
 #  error "DEF_TopDirImported is defined but should not be!"
 #  error "DEF_TopDirImported is defined but should not be!"
 #endif
 #endif