Fix scope of transitive target name lookups

In cmTarget, cmGeneratorTarget, and cmGeneratorExpressionEvaluator, fix
target name lookups to occur in the cmMakefile context of the target
that referenced the name, not the current 'head' target.  The context
matters for imported targets because they are directory-scoped instead
of globally unique.  We already do this in cmComputeLinkDepends and
cmComputeTargetDepends.

Extend the InterfaceLibrary test with an example covering this behavior.
This commit is contained in:
Brad King 2014-06-16 10:10:18 -04:00
parent 069d60fe03
commit a272344228
7 changed files with 36 additions and 18 deletions

View File

@ -828,7 +828,7 @@ std::string getLinkedTargetsContent(
sep = ";";
}
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
std::string linkedTargetsContent = cge->Evaluate(target->GetMakefile(),
context->Config,
context->Quiet,
headTarget,
@ -853,7 +853,7 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
it = libraries.begin();
it != libraries.end(); ++it)
{
if (cmTarget const *tgt = context->Makefile->FindTargetToUse(*it))
if (cmTarget const *tgt = target->FindTargetToLink(*it))
{
tgts.push_back(tgt);
}

View File

@ -478,7 +478,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li)
{
cmTarget const* tgt = this->Makefile->FindTargetToUse(*li);
cmTarget const* tgt = this->Target->FindTargetToLink(*li);
if (!tgt)
{
continue;

View File

@ -3492,9 +3492,9 @@ public:
Makefile(target->GetMakefile()), Target(target)
{ this->Visited.insert(target); }
void Visit(const std::string& name)
void Visit(cmTarget const* from, const std::string& name)
{
cmTarget *target = this->Makefile->FindTargetToUse(name);
cmTarget const *target = from->FindTargetToLink(name);
if(!target)
{
@ -3553,7 +3553,7 @@ public:
for(std::vector<std::string>::const_iterator
li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
{
this->Visit(*li);
this->Visit(target, *li);
}
}
private:
@ -3659,7 +3659,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li)
{
cll.Visit(*li);
cll.Visit(this, *li);
}
// Store the transitive closure of languages.
@ -6149,13 +6149,12 @@ cmTarget::GetImportLinkInterface(const std::string& config,
//----------------------------------------------------------------------------
void processILibs(const std::string& config,
cmTarget const* headTarget,
cmTarget const* curTarget,
std::string const& name,
std::vector<cmTarget const*>& tgts,
std::set<cmTarget const*>& emitted)
{
cmTarget* tgt = headTarget->GetMakefile()
->FindTargetToUse(name);
if (tgt && emitted.insert(tgt).second)
if (cmTarget const* tgt = curTarget->FindTargetToLink(name))
{
tgts.push_back(tgt);
if(cmTarget::LinkInterface const* iface =
@ -6165,7 +6164,7 @@ void processILibs(const std::string& config,
it = iface->Libraries.begin();
it != iface->Libraries.end(); ++it)
{
processILibs(config, headTarget, *it, tgts, emitted);
processILibs(config, headTarget, tgt, *it, tgts, emitted);
}
}
}
@ -6188,7 +6187,7 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it)
{
processILibs(config, this, *it, tgts , emitted);
processILibs(config, this, this, *it, tgts , emitted);
}
}
return tgts;
@ -6212,8 +6211,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
it != iface->Libraries.end(); ++it)
{
if (cmTarget const* tgt = headTarget->GetMakefile()
->FindTargetToUse(*it))
if (cmTarget const* tgt = this->FindTargetToLink(*it))
{
tgts.push_back(tgt);
}
@ -6245,8 +6243,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
for(std::vector<std::string>::const_iterator it = libs.begin();
it != libs.end(); ++it)
{
if (cmTarget* tgt = headTarget->GetMakefile()
->FindTargetToUse(*it))
if (cmTarget const* tgt = this->FindTargetToLink(*it))
{
tgts.push_back(tgt);
}

View File

@ -8,8 +8,18 @@ target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
add_subdirectory(headerdir)
# Add an interface target in a subdirectory that uses an imported interface.
add_subdirectory(ifacedir)
# Poison an imported interface with the same name as that in the subdir
# to ensure that the transitive lookup occurs in the subdir.
add_library(imp::iface INTERFACE IMPORTED)
set_property(TARGET imp::iface APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
set_property(TARGET imp::iface PROPERTY INTERFACE_SOMEPROP OFF)
set_property(TARGET imp::iface PROPERTY INTERFACE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist.cpp)
add_executable(InterfaceLibrary definetestexe.cpp)
target_link_libraries(InterfaceLibrary iface_nodepends headeriface)
target_link_libraries(InterfaceLibrary iface_nodepends headeriface subiface)
add_subdirectory(libsdir)

View File

@ -15,7 +15,9 @@
#error Expected IFACE_HEADER_BUILDDIR
#endif
extern int sub();
int main(int,char**)
{
return 0;
return sub();
}

View File

@ -0,0 +1,8 @@
add_library(imp::iface INTERFACE IMPORTED)
set_property(TARGET imp::iface APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
set_property(TARGET imp::iface PROPERTY INTERFACE_SOMEPROP ON)
set_property(TARGET imp::iface PROPERTY INTERFACE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sub.cpp)
add_library(subiface INTERFACE)
target_link_libraries(subiface INTERFACE imp::iface)
set_property(TARGET subiface PROPERTY INTERFACE_SOMEPROP ON)

View File

@ -0,0 +1 @@
int sub() { return 0; }