diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e51095e68..18ba7c894 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2832,12 +2832,54 @@ public: cmTargetCollectLinkLanguages(cmTarget const* target, const char* config, std::set& 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::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& Languages; cmTarget const* HeadTarget; + cmMakefile* Makefile; + const cmTarget* Target; std::set Visited; }; @@ -2964,7 +3007,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc, for(std::vector::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); diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface-stderr.txt new file mode 100644 index 000000000..e2108f46c --- /dev/null +++ b/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\) diff --git a/Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake b/Tests/RunCMake/CMP0028/CMP0028-NEW-iface.cmake new file mode 100644 index 000000000..1a7143306 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake b/Tests/RunCMake/CMP0028/CMP0028-OLD-iface.cmake new file mode 100644 index 000000000..d7bd60e4b --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface-stderr.txt new file mode 100644 index 000000000..0c5c65378 --- /dev/null +++ b/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. diff --git a/Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake b/Tests/RunCMake/CMP0028/CMP0028-WARN-iface.cmake new file mode 100644 index 000000000..927002340 --- /dev/null +++ b/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) diff --git a/Tests/RunCMake/CMP0028/RunCMakeTest.cmake b/Tests/RunCMake/CMP0028/RunCMakeTest.cmake index 293e27bb2..0c72ca296 100644 --- a/Tests/RunCMake/CMP0028/RunCMakeTest.cmake +++ b/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)