ソースを参照

Restore support for exporting INTERFACE with missing dependencies

Since commit c16acd35b3 (GenEx: Add support for custom transitive link
properties, 2024-05-09, v3.30.0-rc1~82^2) evaluation of
`TRANSITIVE_LINK_PROPERTIES` by `install(EXPORT)` enables discovery of
missing dependencies on INTERFACE libraries that we did not previously
diagnose.  This regressed existing projects that relied on such
non-diagnosis.  Although commit 2fc9e482a9 (Evaluation of
TRANSITIVE_LINK_PROPERTIES isn't considered a usage, 2024-07-05) fixed
this, it also made a significant change to the `UseTo` infrastructure
that may have other subtle effects.  Replace the fix with an approach
that explicitly models suppression of the relevant diagnostics.

Fixes: #26108
Brad King 1 年間 前
コミット
7a77a6c642

+ 1 - 0
Source/cmExportFileGenerator.cxx

@@ -613,6 +613,7 @@ void cmExportFileGenerator::PopulateCustomTransitiveInterfaceProperties(
                                   properties);
   this->PopulateInterfaceProperty("TRANSITIVE_LINK_PROPERTIES", target,
                                   properties);
+  cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII cllSuppressRAII;
   std::set<std::string> ifaceProperties;
   for (std::string const& config : this->Configurations) {
     for (auto const& i : target->GetCustomTransitiveProperties(

+ 7 - 1
Source/cmGeneratorTarget.h

@@ -99,6 +99,13 @@ public:
   // Call this after generation is complete.
   void CheckLinkLibraries() const;
 
+  class CheckLinkLibrariesSuppressionRAII
+  {
+  public:
+    CheckLinkLibrariesSuppressionRAII();
+    ~CheckLinkLibrariesSuppressionRAII();
+  };
+
   cmStateEnums::TargetType GetType() const;
   const std::string& GetName() const;
   std::string GetExportName() const;
@@ -264,7 +271,6 @@ public:
   {
     Compile, // Usage requirements for compiling.  Excludes $<LINK_ONLY>.
     Link,    // Usage requirements for linking.  Includes $<LINK_ONLY>.
-    LinkInterfaceEval,
   };
 
   cmLinkInterfaceLibraries const* GetLinkInterfaceLibraries(

+ 34 - 5
Source/cmGeneratorTarget_Link.cxx

@@ -54,6 +54,20 @@ const std::string kINTERFACE_LINK_LIBRARIES_DIRECT =
   "INTERFACE_LINK_LIBRARIES_DIRECT";
 const std::string kINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE =
   "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE";
+
+unsigned int CheckLinkLibrariesSuppressionRAIICount;
+void MaybeEnableCheckLinkLibraries(cmOptionalLinkImplementation& impl)
+{
+  if (CheckLinkLibrariesSuppressionRAIICount == 0) {
+    impl.CheckLinkLibraries = true;
+  }
+}
+void MaybeEnableCheckLinkLibraries(cmOptionalLinkInterface& iface)
+{
+  if (CheckLinkLibrariesSuppressionRAIICount == 0) {
+    iface.CheckLinkLibraries = true;
+  }
+}
 }
 
 class cmTargetCollectLinkLanguages
@@ -372,7 +386,8 @@ void cmGeneratorTarget::CheckLinkLibraries() const
     // There could be several entries used when computing the pre-CMP0022
     // default link interface.  Check only the entry for our own link impl.
     auto const hmi = hm.find(this);
-    if (hmi == hm.end() || !hmi->second.LibrariesDone) {
+    if (hmi == hm.end() || !hmi->second.LibrariesDone ||
+        !hmi->second.CheckLinkLibraries) {
       continue;
     }
     for (cmLinkImplItem const& item : hmi->second.Libraries) {
@@ -392,7 +407,7 @@ void cmGeneratorTarget::CheckLinkLibraries() const
   // should be a subset of LinkInterfaceMap (with LINK_ONLY left out).
   for (auto const& hmp : this->LinkInterfaceMap) {
     for (auto const& hmi : hmp.second) {
-      if (!hmi.second.LibrariesDone || hmi.second.LinkOnlyEval) {
+      if (!hmi.second.LibrariesDone || !hmi.second.CheckLinkLibraries) {
         continue;
       }
       for (cmLinkItem const& item : hmi.second.Libraries) {
@@ -408,6 +423,18 @@ void cmGeneratorTarget::CheckLinkLibraries() const
   }
 }
 
+cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII::
+  CheckLinkLibrariesSuppressionRAII()
+{
+  ++CheckLinkLibrariesSuppressionRAIICount;
+}
+
+cmGeneratorTarget::CheckLinkLibrariesSuppressionRAII::
+  ~CheckLinkLibrariesSuppressionRAII()
+{
+  --CheckLinkLibrariesSuppressionRAIICount;
+}
+
 namespace {
 cm::string_view missingTargetPossibleReasons =
   "Possible reasons include:\n"
@@ -642,7 +669,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
   if (secondPass) {
     iface = cmOptionalLinkInterface();
   }
-  iface.LinkOnlyEval = false;
+  MaybeEnableCheckLinkLibraries(iface);
   if (!iface.LibrariesDone) {
     iface.LibrariesDone = true;
     this->ComputeLinkInterfaceLibraries(config, iface, head, UseTo::Link);
@@ -766,7 +793,7 @@ const cmLinkInterfaceLibraries* cmGeneratorTarget::GetLinkInterfaceLibraries(
   }
 
   cmOptionalLinkInterface& iface = hm[head];
-  iface.LinkOnlyEval = (usage == UseTo::LinkInterfaceEval);
+  MaybeEnableCheckLinkLibraries(iface);
   if (!iface.LibrariesDone) {
     iface.LibrariesDone = true;
     this->ComputeLinkInterfaceLibraries(config, iface, head, usage);
@@ -1036,7 +1063,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
   if (secondPass) {
     iface = cmOptionalLinkInterface();
   }
-  iface.LinkOnlyEval = (usage == UseTo::LinkInterfaceEval);
+  MaybeEnableCheckLinkLibraries(iface);
   if (!iface.AllDone) {
     iface.AllDone = true;
     iface.LibrariesDone = true;
@@ -1109,6 +1136,7 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
   if (secondPass) {
     impl = cmOptionalLinkImplementation();
   }
+  MaybeEnableCheckLinkLibraries(impl);
   if (!impl.LibrariesDone) {
     impl.LibrariesDone = true;
     this->ComputeLinkImplementationLibraries(config, impl, this, usage);
@@ -1165,6 +1193,7 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
   }
 
   cmOptionalLinkImplementation& impl = hm[head];
+  MaybeEnableCheckLinkLibraries(impl);
   if (!impl.LibrariesDone) {
     impl.LibrariesDone = true;
     this->ComputeLinkImplementationLibraries(config, impl, head, usage);

+ 1 - 2
Source/cmGeneratorTarget_TransitiveProperty.cxx

@@ -286,8 +286,7 @@ cmGeneratorTarget::GetCustomTransitiveProperties(std::string const& config,
         }
       }
     };
-    addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES",
-                            UseTo::LinkInterfaceEval);
+    addTransitiveProperties("TRANSITIVE_LINK_PROPERTIES", UseTo::Link);
     addTransitiveProperties("TRANSITIVE_COMPILE_PROPERTIES", UseTo::Compile);
     i = ctpm.emplace(config, std::move(ctp)).first;
   }

+ 2 - 1
Source/cmLinkItem.h

@@ -120,11 +120,11 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
 
 struct cmOptionalLinkInterface : public cmLinkInterface
 {
-  bool LinkOnlyEval = false;
   bool LibrariesDone = false;
   bool AllDone = false;
   bool Exists = false;
   bool Explicit = false;
+  bool CheckLinkLibraries = false;
 };
 
 struct cmHeadToLinkInterfaceMap
@@ -149,6 +149,7 @@ struct cmOptionalLinkImplementation : public cmLinkImplementation
   bool LibrariesDone = false;
   bool LanguagesDone = false;
   bool HadHeadSensitiveCondition = false;
+  bool CheckLinkLibraries = false;
 };
 
 /** Compute the link type to use for the given configuration.  */