Explorar el Código

Merge branch 'backport-target-objects' into target-objects

Brad King hace 1 año
padre
commit
d7988ff6b8

+ 8 - 2
Source/cmCommonTargetGenerator.cxx

@@ -171,8 +171,8 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
   cmGlobalCommonGenerator* const gg = this->GlobalCommonGenerator;
   if (cmComputeLinkInformation* cli =
         this->GeneratorTarget->GetLinkInformation(config)) {
-    for (auto const& item : cli->GetItems()) {
-      auto const* linkee = item.Target;
+    auto addLinkedTarget = [this, &lang, &config, &dirs, &emitted,
+                            gg](cmGeneratorTarget const* linkee) {
       if (linkee &&
           !linkee->IsImported()
           // Skip targets that build after this one in a static lib cycle.
@@ -194,6 +194,12 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
         }
         dirs.push_back(std::move(di));
       }
+    };
+    for (auto const& item : cli->GetItems()) {
+      addLinkedTarget(item.Target);
+    }
+    for (cmGeneratorTarget const* target : cli->GetExternalObjectTargets()) {
+      addLinkedTarget(target);
     }
   }
   return dirs;

+ 2 - 20
Source/cmComputeLinkDepends.cxx

@@ -27,7 +27,6 @@
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmRange.h"
-#include "cmSourceFile.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmTarget.h"
@@ -321,9 +320,6 @@ cmComputeLinkDepends::Compute()
   // Follow the link dependencies of the target to be linked.
   this->AddDirectLinkEntries();
 
-  // Add dependencies on targets named by $<TARGET_OBJECTS:...> sources.
-  this->AddTargetObjectEntries();
-
   // Complete the breadth-first search of dependencies.
   while (!this->BFSQueue.empty()) {
     // Get the next entry.
@@ -504,6 +500,8 @@ std::pair<size_t, bool> cmComputeLinkDepends::AddLinkEntry(
 
 void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item)
 {
+  assert(!item.Target); // The item is an object file, not its target.
+
   // Allocate a spot for the item entry.
   auto lei = this->AllocateLinkEntry(item);
 
@@ -517,7 +515,6 @@ void cmComputeLinkDepends::AddLinkObject(cmLinkItem const& item)
   LinkEntry& entry = this->EntryList[index];
   entry.Item = BT<std::string>(item.AsStr(), item.Backtrace);
   entry.Kind = LinkEntry::Object;
-  entry.Target = item.Target;
 
   // Record explicitly linked object files separately.
   this->ObjectEntries.emplace_back(index);
@@ -706,21 +703,6 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
   }
 }
 
-void cmComputeLinkDepends::AddTargetObjectEntries()
-{
-  std::vector<cmSourceFile const*> externalObjects;
-  this->Target->GetExternalObjects(externalObjects, this->Config);
-  for (auto const* externalObject : externalObjects) {
-    std::string const& objLib = externalObject->GetObjectLibrary();
-    if (objLib.empty()) {
-      continue;
-    }
-    cmLinkItem const& objItem =
-      this->Target->ResolveLinkItem(BT<std::string>(objLib));
-    this->AddLinkObject(objItem);
-  }
-}
-
 template <typename T>
 void cmComputeLinkDepends::AddLinkEntries(size_t depender_index,
                                           std::vector<T> const& libs)

+ 0 - 1
Source/cmComputeLinkDepends.h

@@ -100,7 +100,6 @@ private:
   void AddLinkObject(cmLinkItem const& item);
   void AddVarLinkEntries(size_t depender_index, const char* value);
   void AddDirectLinkEntries();
-  void AddTargetObjectEntries();
   template <typename T>
   void AddLinkEntries(size_t depender_index, std::vector<T> const& libs);
   void AddLinkObjects(std::vector<cmLinkItem> const& objs);

+ 31 - 0
Source/cmComputeLinkInformation.cxx

@@ -15,6 +15,7 @@
 #include "cmComputeLinkDepends.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
+#include "cmLinkItem.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
@@ -23,6 +24,7 @@
 #include "cmOrderDirectories.h"
 #include "cmPlaceholderExpander.h"
 #include "cmPolicies.h"
+#include "cmSourceFile.h"
 #include "cmState.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -536,6 +538,12 @@ cmComputeLinkInformation::GetSharedLibrariesLinked() const
   return this->SharedLibrariesLinked;
 }
 
+const std::vector<const cmGeneratorTarget*>&
+cmComputeLinkInformation::GetExternalObjectTargets() const
+{
+  return this->ExternalObjectTargets;
+}
+
 bool cmComputeLinkInformation::Compute()
 {
   // Skip targets that do not link or have link-like information consumers may
@@ -683,6 +691,9 @@ bool cmComputeLinkInformation::Compute()
                                       this->Target->GetBacktrace());
   }
 
+  // Record targets referenced by $<TARGET_OBJECTS:...> sources.
+  this->AddExternalObjectTargets();
+
   return true;
 }
 
@@ -1057,6 +1068,26 @@ cmComputeLinkInformation::GetGroupFeature(std::string const& feature)
     .first->second;
 }
 
+void cmComputeLinkInformation::AddExternalObjectTargets()
+{
+  std::vector<cmSourceFile const*> externalObjects;
+  this->Target->GetExternalObjects(externalObjects, this->Config);
+  std::set<std::string> emitted;
+  for (auto const* externalObject : externalObjects) {
+    std::string const& objLib = externalObject->GetObjectLibrary();
+    if (objLib.empty()) {
+      continue;
+    }
+    if (emitted.insert(objLib).second) {
+      cmLinkItem const& objItem =
+        this->Target->ResolveLinkItem(BT<std::string>(objLib));
+      if (objItem.Target) {
+        this->ExternalObjectTargets.emplace_back(objItem.Target);
+      }
+    }
+  }
+}
+
 void cmComputeLinkInformation::AddImplicitLinkInfo()
 {
   // The link closure lists all languages whose implicit info is needed.

+ 5 - 0
Source/cmComputeLinkInformation.h

@@ -97,6 +97,8 @@ public:
   std::string GetRPathString(bool for_install) const;
   std::string GetChrpathString() const;
   std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
+  std::vector<cmGeneratorTarget const*> const& GetExternalObjectTargets()
+    const;
   std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
   {
     return this->RuntimeDLLs;
@@ -134,6 +136,7 @@ private:
   std::vector<std::string> XcFrameworkHeaderPaths;
   std::vector<std::string> RuntimeSearchPath;
   std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
+  std::vector<cmGeneratorTarget const*> ExternalObjectTargets;
   std::vector<cmGeneratorTarget const*> RuntimeDLLs;
 
   // Context information.
@@ -221,6 +224,8 @@ private:
   bool FinishLinkerSearchDirectories();
   void PrintLinkPolicyDiagnosis(std::ostream&);
 
+  void AddExternalObjectTargets();
+
   // Implicit link libraries and directories for linker language.
   void LoadImplicitLinkInfo();
   void AddImplicitLinkInfo();

+ 2 - 0
Tests/ObjectLibrary/CMakeLists.txt

@@ -77,3 +77,5 @@ add_subdirectory(ExportLanguages)
 add_subdirectory(LinkObjects)
 
 add_subdirectory(Transitive)
+
+add_subdirectory(TransitiveLinkDeps)

+ 15 - 0
Tests/ObjectLibrary/TransitiveLinkDeps/CMakeLists.txt

@@ -0,0 +1,15 @@
+add_library(implgather INTERFACE)
+
+add_library(dep STATIC dep.c)
+
+add_library(deps INTERFACE)
+target_link_libraries(deps INTERFACE dep)
+
+add_library(impl_obj OBJECT impl_obj.c)
+target_link_libraries(impl_obj PUBLIC deps)
+
+target_sources(implgather INTERFACE "$<TARGET_OBJECTS:impl_obj>")
+target_link_libraries(implgather INTERFACE impl_obj)
+
+add_executable(useimpl main.c)
+target_link_libraries(useimpl PRIVATE implgather)

+ 4 - 0
Tests/ObjectLibrary/TransitiveLinkDeps/dep.c

@@ -0,0 +1,4 @@
+int from_dep(void)
+{
+  return 0;
+}

+ 6 - 0
Tests/ObjectLibrary/TransitiveLinkDeps/impl_obj.c

@@ -0,0 +1,6 @@
+int from_dep(void);
+
+int impl_obj(void)
+{
+  return from_dep();
+}

+ 6 - 0
Tests/ObjectLibrary/TransitiveLinkDeps/main.c

@@ -0,0 +1,6 @@
+int impl_obj(void);
+
+int main(int argc, char* argv[])
+{
+  return impl_obj();
+}