CMP0028: Trigger on libraries from INTERFACE of dependencies.

This commit is contained in:
Stephen Kelly 2014-02-09 15:35:28 +01:00
parent 1cc3e9f2e7
commit b29152387d
11 changed files with 92 additions and 46 deletions

View File

@ -2832,12 +2832,54 @@ public:
cmTargetCollectLinkLanguages(cmTarget const* target, const char* config, cmTargetCollectLinkLanguages(cmTarget const* target, const char* config,
std::set<cmStdString>& languages, std::set<cmStdString>& languages,
cmTarget const* head): cmTarget const* head):
Config(config), Languages(languages), HeadTarget(head) Config(config), Languages(languages), HeadTarget(head),
Makefile(target->GetMakefile()), Target(target)
{ this->Visited.insert(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; return;
} }
@ -2852,17 +2894,18 @@ public:
this->Languages.insert(*li); this->Languages.insert(*li);
} }
cmMakefile* mf = target->GetMakefile();
for(std::vector<std::string>::const_iterator for(std::vector<std::string>::const_iterator
li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li) li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
{ {
this->Visit(mf->FindTargetToUse(*li)); this->Visit(*li);
} }
} }
private: private:
const char* Config; const char* Config;
std::set<cmStdString>& Languages; std::set<cmStdString>& Languages;
cmTarget const* HeadTarget; cmTarget const* HeadTarget;
cmMakefile* Makefile;
const cmTarget* Target;
std::set<cmTarget const*> Visited; 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(); for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li) li != impl->Libraries.end(); ++li)
{ {
cll.Visit(this->Makefile->FindTargetToUse(*li)); cll.Visit(*li);
} }
// Store the transitive closure of languages. // Store the transitive closure of languages.
@ -5619,46 +5662,6 @@ void cmTarget::ComputeLinkImplementation(const char* config,
} }
continue; 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. // The entry is meant for this configuration.
impl.Libraries.push_back(item); impl.Libraries.push_back(item);

View File

@ -0,0 +1 @@
1

View File

@ -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\)

View File

@ -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)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -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)

View File

@ -0,0 +1 @@
0

View File

@ -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.

View File

@ -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)

View File

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