Procházet zdrojové kódy

Merge topic 'ninja-depend-shared-symlinks'

4891f0f966 Ninja: Ensure shared library version symlinks are created for dependents

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3875
Brad King před 6 roky
rodič
revize
a1f78a481c

+ 21 - 0
Source/cmNinjaNormalTargetGenerator.cxx

@@ -13,6 +13,7 @@
 #include <cm/memory>
 
 #include "cmAlgorithms.h"
+#include "cmComputeLinkInformation.h"
 #include "cmCustomCommand.h" // IWYU pragma: keep
 #include "cmCustomCommandGenerator.h"
 #include "cmGeneratedFileStream.h"
@@ -1049,6 +1050,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
   // Gather order-only dependencies.
   this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
 
+  // Add order-only dependencies on versioning symlinks of shared libs we link.
+  if (!this->GeneratorTarget->IsDLLPlatform()) {
+    if (cmComputeLinkInformation* cli =
+          this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
+      for (auto const& item : cli->GetItems()) {
+        if (item.Target &&
+            item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
+            !item.Target->IsFrameworkOnApple()) {
+          std::string const& lib = this->ConvertToNinjaPath(
+            item.Target->GetFullPath(this->GetConfigName()));
+          if (std::find(linkBuild.ImplicitDeps.begin(),
+                        linkBuild.ImplicitDeps.end(),
+                        lib) == linkBuild.ImplicitDeps.end()) {
+            linkBuild.OrderOnlyDeps.emplace_back(lib);
+          }
+        }
+      }
+    }
+  }
+
   // Ninja should restat after linking if and only if there are byproducts.
   vars["RESTAT"] = byproducts.empty() ? "" : "1";
 

+ 17 - 0
Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.c

@@ -0,0 +1,17 @@
+#ifndef REQUIRED
+#  error "REQUIRED not defined"
+#endif
+
+#if defined(_WIN32)
+#  define IMPORT __declspec(dllimport)
+#else
+#  define IMPORT
+#endif
+
+IMPORT int a(void);
+extern int required(void);
+
+int main(void)
+{
+  return required() + a();
+}

+ 10 - 2
Tests/RunCMake/ObjectLibrary/LinkObjLHSShared.cmake

@@ -1,7 +1,15 @@
 project(LinkObjLHSShared C)
 
+# Create a versioned shared library that does not build as part of "all".
 add_library(OtherLib SHARED a.c)
-target_compile_definitions(OtherLib INTERFACE REQUIRED)
+target_compile_definitions(OtherLib INTERFACE REQUIRED PRIVATE COMPILE_FOR_SHARED_LIB)
+set_target_properties(OtherLib PROPERTIES SOVERSION 0 VERSION 0.0.0 EXCLUDE_FROM_ALL ON)
 
 add_library(AnObjLib OBJECT requires.c)
-target_link_libraries(AnObjLib OtherLib)
+target_link_libraries(AnObjLib PUBLIC OtherLib)
+
+add_executable(LinkObjLHSShared LinkObjLHSShared.c)
+target_link_libraries(LinkObjLHSShared AnObjLib)
+
+# Verify that our dependency on OtherLib generated its versioning symlinks.
+add_custom_command(TARGET LinkObjLHSShared POST_BUILD COMMAND LinkObjLHSShared)