Browse Source

OPTIMIZE_DEPENDENCIES: Skip order-only deps for non-linking targets

Fixes: #21517
Craig Scott 2 years ago
parent
commit
84eae7aeda

+ 5 - 0
Source/cmGeneratorTarget.cxx

@@ -1224,6 +1224,11 @@ bool cmGeneratorTarget::IsNormal() const
   return this->Target->IsNormal();
 }
 
+bool cmGeneratorTarget::IsRuntimeBinary() const
+{
+  return this->Target->IsRuntimeBinary();
+}
+
 bool cmGeneratorTarget::IsSynthetic() const
 {
   return this->Target->IsSynthetic();

+ 1 - 0
Source/cmGeneratorTarget.h

@@ -51,6 +51,7 @@ public:
 
   bool IsInBuildSystem() const;
   bool IsNormal() const;
+  bool IsRuntimeBinary() const;
   bool IsSynthetic() const;
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;

+ 5 - 3
Source/cmNinjaNormalTargetGenerator.cxx

@@ -1469,9 +1469,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
     gt, linkBuild.OrderOnlyDeps, config, fileConfig, DependOnTargetArtifact);
 
   // Add order-only dependencies on versioning symlinks of shared libs we link.
-  if (!this->GeneratorTarget->IsDLLPlatform()) {
-    if (cmComputeLinkInformation* cli =
-          this->GeneratorTarget->GetLinkInformation(config)) {
+  // If our target is not producing a runtime binary, it doesn't need the
+  // symlinks (anything that links to the target might, but that consumer will
+  // get its own order-only dependency).
+  if (!gt->IsDLLPlatform() && gt->IsRuntimeBinary()) {
+    if (cmComputeLinkInformation* cli = gt->GetLinkInformation(config)) {
       for (auto const& item : cli->GetItems()) {
         if (item.Target &&
             item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&

+ 18 - 0
Source/cmTarget.cxx

@@ -2652,6 +2652,24 @@ bool cmTarget::IsPerConfig() const
   return this->impl->PerConfig;
 }
 
+bool cmTarget::IsRuntimeBinary() const
+{
+  switch (this->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+      return true;
+    case cmStateEnums::OBJECT_LIBRARY:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::INTERFACE_LIBRARY:
+    case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::UNKNOWN_LIBRARY:
+      break;
+  }
+  return false;
+}
+
 bool cmTarget::CanCompileSources() const
 {
   if (this->IsImported()) {

+ 1 - 0
Source/cmTarget.h

@@ -212,6 +212,7 @@ public:
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
   bool IsPerConfig() const;
+  bool IsRuntimeBinary() const;
   bool CanCompileSources() const;
 
   bool GetMappedConfig(std::string const& desired_config, cmValue& loc,

+ 2 - 0
Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake

@@ -59,3 +59,5 @@ run_optimize_test(OptimizeStatic StaticTop)
 if(CMAKE_Fortran_COMPILER)
   run_optimize_test(OptimizeFortran FortranTop)
 endif()
+
+run_cmake_build(RuntimeTargets mylib SharedTop)

+ 18 - 0
Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake

@@ -0,0 +1,18 @@
+enable_language(C)
+
+set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE)
+add_library(mylib STATIC mylib.c)
+add_library(neverbuild SHARED neverbuild.c)
+
+# Building mylib should not require building neverbuild
+target_link_libraries(mylib PRIVATE neverbuild)
+set_target_properties(neverbuild PROPERTIES EXCLUDE_FROM_ALL YES)
+
+# Building SharedTop should require SharedBottom to be built
+add_library(SharedTop SHARED top.c)
+add_library(StaticMiddle STATIC middle.c)
+add_library(SharedBottom SHARED bottom.c)
+target_link_libraries(SharedTop PRIVATE StaticMiddle)
+target_link_libraries(StaticMiddle PRIVATE SharedBottom)
+set_target_properties(StaticMiddle SharedBottom PROPERTIES EXCLUDE_FROM_ALL YES)
+set_target_properties(StaticMiddle PROPERTIES POSITION_INDEPENDENT_CODE YES)

+ 7 - 0
Tests/RunCMake/DependencyGraph/bottom.c

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  int bottom(void)
+{
+  return 23;
+}

+ 9 - 0
Tests/RunCMake/DependencyGraph/middle.c

@@ -0,0 +1,9 @@
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+  int bottom(void);
+
+int middle(void)
+{
+  return bottom() + 19;
+}

+ 1 - 0
Tests/RunCMake/DependencyGraph/neverbuild.c

@@ -0,0 +1 @@
+#error I should not be built

+ 9 - 0
Tests/RunCMake/DependencyGraph/top.c

@@ -0,0 +1,9 @@
+int middle(void);
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  int top(void)
+{
+  return middle() + 2;
+}