Browse Source

CMP0028: Trigger on libraries from INTERFACE of dependencies.

Stephen Kelly 11 years ago
parent
commit
b29152387d

+ 49 - 46
Source/cmTarget.cxx

@@ -2832,12 +2832,54 @@ public:
   cmTargetCollectLinkLanguages(cmTarget const* target, const char* config,
                                std::set<cmStdString>& languages,
                                cmTarget const* head):
-    Config(config), Languages(languages), HeadTarget(head)
+    Config(config), Languages(languages), HeadTarget(head),
+    Makefile(target->GetMakefile()), Target(target)
   { this->Visited.insert(target); }
 
-  void Visit(cmTarget const* target)
+  void Visit(const std::string& name)
     {
-    if(!target || !this->Visited.insert(target).second)
+    cmTarget *target = this->Makefile->FindTargetToUse(name);
+
+    if(!target)
+      {
+      if(name.find("::") != std::string::npos)
+        {
+        bool noMessage = false;
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        cmOStringStream e;
+        switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
+          {
+          case cmPolicies::WARN:
+            {
+            e << (this->Makefile->GetPolicies()
+                  ->GetPolicyWarning(cmPolicies::CMP0028)) << "\n";
+            messageType = cmake::AUTHOR_WARNING;
+            }
+            break;
+          case cmPolicies::OLD:
+            noMessage = true;
+          case cmPolicies::REQUIRED_IF_USED:
+          case cmPolicies::REQUIRED_ALWAYS:
+          case cmPolicies::NEW:
+            // Issue the fatal message.
+            break;
+          }
+
+        if(!noMessage)
+          {
+          e << "Target \"" << this->Target->GetName()
+            << "\" links to target \"" << name
+            << "\" but the target was not found.  Perhaps a find_package() "
+            "call is missing for an IMPORTED target, or an ALIAS target is "
+            "missing?";
+          this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
+                                                e.str(),
+                                                this->Target->GetBacktrace());
+          }
+        }
+      return;
+      }
+    if(!this->Visited.insert(target).second)
       {
       return;
       }
@@ -2852,17 +2894,18 @@ public:
       this->Languages.insert(*li);
       }
 
-    cmMakefile* mf = target->GetMakefile();
     for(std::vector<std::string>::const_iterator
           li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
       {
-      this->Visit(mf->FindTargetToUse(*li));
+      this->Visit(*li);
       }
     }
 private:
   const char* Config;
   std::set<cmStdString>& Languages;
   cmTarget const* HeadTarget;
+  cmMakefile* Makefile;
+  const cmTarget* Target;
   std::set<cmTarget const*> Visited;
 };
 
@@ -2964,7 +3007,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc,
   for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
     {
-    cll.Visit(this->Makefile->FindTargetToUse(*li));
+    cll.Visit(*li);
     }
 
   // Store the transitive closure of languages.
@@ -5619,46 +5662,6 @@ void cmTarget::ComputeLinkImplementation(const char* config,
         }
       continue;
       }
-    cmTarget *tgt = this->Makefile->FindTargetToUse(*li);
-
-    if(!tgt && std::string(item).find("::") != std::string::npos)
-      {
-      bool noMessage = false;
-      cmake::MessageType messageType = cmake::FATAL_ERROR;
-      cmOStringStream e;
-      switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
-        {
-        case cmPolicies::WARN:
-          {
-          e << (this->Makefile->GetPolicies()
-                ->GetPolicyWarning(cmPolicies::CMP0028)) << "\n";
-          messageType = cmake::AUTHOR_WARNING;
-          }
-          break;
-        case cmPolicies::OLD:
-          noMessage = true;
-        case cmPolicies::REQUIRED_IF_USED:
-        case cmPolicies::REQUIRED_ALWAYS:
-        case cmPolicies::NEW:
-          // Issue the fatal message.
-          break;
-        }
-
-      if(!noMessage)
-        {
-        e << "Target \"" << this->GetName() << "\" links to target \"" << item
-          << "\" but the target was not found.  Perhaps a find_package() "
-          "call is missing for an IMPORTED target, or an ALIAS target is "
-          "missing?";
-        this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
-                                                      e.str(),
-                                                      this->GetBacktrace());
-        if (messageType == cmake::FATAL_ERROR)
-          {
-          return;
-          }
-        }
-      }
 
     // The entry is meant for this configuration.
     impl.Libraries.push_back(item);

+ 1 - 0
Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt

@@ -0,0 +1,6 @@
+CMake Error at CMP0028-NEW-iface.cmake:6 \(add_library\):
+  Target "foo" links to target "External::Library" but the target was not
+  found.  Perhaps a find_package\(\) call is missing for an IMPORTED target, or
+  an ALIAS target is missing\?
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 7 - 0
Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake

@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0028 NEW)
+
+add_library(iface INTERFACE)
+target_link_libraries(iface INTERFACE External::Library)
+add_library(foo empty.cpp)
+target_link_libraries(foo iface)

+ 1 - 0
Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt

@@ -0,0 +1 @@
+0

+ 1 - 0
Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt

@@ -0,0 +1 @@
+^$

+ 7 - 0
Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake

@@ -0,0 +1,7 @@
+
+cmake_policy(SET CMP0028 OLD)
+
+add_library(iface INTERFACE)
+target_link_libraries(iface INTERFACE External::Library)
+add_library(foo empty.cpp)
+target_link_libraries(foo iface)

+ 1 - 0
Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt

@@ -0,0 +1 @@
+0

+ 11 - 0
Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt

@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at CMP0028-WARN-iface.cmake:4 \(add_library\):
+  Policy CMP0028 is not set: Double colon in target name means ALIAS or
+  IMPORTED target.  Run "cmake --help-policy CMP0028" for policy details.
+  Use the cmake_policy command to set the policy and suppress this warning.
+
+  Target "foo" links to target "External::Library" but the target was not
+  found.  Perhaps a find_package\(\) call is missing for an IMPORTED target, or
+  an ALIAS target is missing\?
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 5 - 0
Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake

@@ -0,0 +1,5 @@
+
+add_library(iface INTERFACE)
+target_link_libraries(iface INTERFACE External::Library)
+add_library(foo empty.cpp)
+target_link_libraries(foo iface)

+ 3 - 0
Tests/RunCMake/CMP0028/RunCMakeTest.cmake

@@ -3,3 +3,6 @@ include(RunCMake)
 run_cmake(CMP0028-NEW)
 run_cmake(CMP0028-OLD)
 run_cmake(CMP0028-WARN)
+run_cmake(CMP0028-NEW-iface)
+run_cmake(CMP0028-OLD-iface)
+run_cmake(CMP0028-WARN-iface)