BUG: Avoid bogus dependency on executable targets
When an executable target within the project is named in target_link_libraries for another target, but the executable does not have the ENABLE_EXPORTS property set, then the executable cannot really be linked. This is probably a case where the user intends to link to a third-party library that happens to have the same name as an executable target in the project (or else will get an error at build time). We need to avoid making the other target depend on the executable target incorrectly, since the executable may actually want to link to that target and this is not a circular depenency.
This commit is contained in:
parent
37a009b7f7
commit
d76b20bf3a
|
@ -292,7 +292,7 @@ int cmComputeLinkDepends::AddLinkEntry(std::string const& item)
|
||||||
int index = lei->second;
|
int index = lei->second;
|
||||||
LinkEntry& entry = this->EntryList[index];
|
LinkEntry& entry = this->EntryList[index];
|
||||||
entry.Item = item;
|
entry.Item = item;
|
||||||
entry.Target = this->Makefile->FindTargetToUse(entry.Item.c_str());
|
entry.Target = this->FindTargetToLink(entry.Item.c_str());
|
||||||
|
|
||||||
// If the item has dependencies queue it to follow them.
|
// If the item has dependencies queue it to follow them.
|
||||||
if(entry.Target)
|
if(entry.Target)
|
||||||
|
@ -387,7 +387,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
|
||||||
// Initialize the item entry.
|
// Initialize the item entry.
|
||||||
LinkEntry& entry = this->EntryList[lei->second];
|
LinkEntry& entry = this->EntryList[lei->second];
|
||||||
entry.Item = dep.Item;
|
entry.Item = dep.Item;
|
||||||
entry.Target = this->Makefile->FindTargetToUse(dep.Item.c_str());
|
entry.Target = this->FindTargetToLink(dep.Item.c_str());
|
||||||
|
|
||||||
// This item was added specifically because it is a dependent
|
// This item was added specifically because it is a dependent
|
||||||
// shared library. It may get special treatment
|
// shared library. It may get special treatment
|
||||||
|
@ -654,6 +654,25 @@ std::string cmComputeLinkDepends::CleanItemName(std::string const& item)
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget* cmComputeLinkDepends::FindTargetToLink(const char* name)
|
||||||
|
{
|
||||||
|
// Look for a target.
|
||||||
|
cmTarget* tgt = this->Makefile->FindTargetToUse(name);
|
||||||
|
|
||||||
|
// Skip targets that will not really be linked. This is probably a
|
||||||
|
// name conflict between an external library and an executable
|
||||||
|
// within the project.
|
||||||
|
if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
|
||||||
|
!tgt->IsExecutableWithExports())
|
||||||
|
{
|
||||||
|
tgt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the target found, if any.
|
||||||
|
return tgt;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmComputeLinkDepends::InferDependencies()
|
void cmComputeLinkDepends::InferDependencies()
|
||||||
{
|
{
|
||||||
|
@ -862,7 +881,7 @@ void cmComputeLinkDepends::CheckWrongConfigItem(std::string const& item)
|
||||||
// For CMake 2.4 bug-compatibility we need to consider the output
|
// For CMake 2.4 bug-compatibility we need to consider the output
|
||||||
// directories of targets linked in another configuration as link
|
// directories of targets linked in another configuration as link
|
||||||
// directories.
|
// directories.
|
||||||
if(cmTarget* tgt = this->Makefile->FindTargetToUse(item.c_str()))
|
if(cmTarget* tgt = this->FindTargetToLink(item.c_str()))
|
||||||
{
|
{
|
||||||
if(!tgt->IsImported())
|
if(!tgt->IsImported())
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,6 +85,7 @@ private:
|
||||||
void AddLinkEntries(int depender_index,
|
void AddLinkEntries(int depender_index,
|
||||||
std::vector<std::string> const& libs);
|
std::vector<std::string> const& libs);
|
||||||
std::string CleanItemName(std::string const& item);
|
std::string CleanItemName(std::string const& item);
|
||||||
|
cmTarget* FindTargetToLink(const char* name);
|
||||||
|
|
||||||
// One entry for each unique item.
|
// One entry for each unique item.
|
||||||
std::vector<LinkEntry> EntryList;
|
std::vector<LinkEntry> EntryList;
|
||||||
|
|
|
@ -214,7 +214,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
|
||||||
// Don't emit the same library twice for this target.
|
// Don't emit the same library twice for this target.
|
||||||
if(emitted.insert(lib->first).second)
|
if(emitted.insert(lib->first).second)
|
||||||
{
|
{
|
||||||
this->AddTargetDepend(depender_index, lib->first.c_str());
|
this->AddTargetDepend(depender_index, lib->first.c_str(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,14 +226,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
|
||||||
// Don't emit the same utility twice for this target.
|
// Don't emit the same utility twice for this target.
|
||||||
if(emitted.insert(*util).second)
|
if(emitted.insert(*util).second)
|
||||||
{
|
{
|
||||||
this->AddTargetDepend(depender_index, util->c_str());
|
this->AddTargetDepend(depender_index, util->c_str(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||||
const char* dependee_name)
|
const char* dependee_name,
|
||||||
|
bool linking)
|
||||||
{
|
{
|
||||||
// Get the depender.
|
// Get the depender.
|
||||||
cmTarget* depender = this->Targets[depender_index];
|
cmTarget* depender = this->Targets[depender_index];
|
||||||
|
@ -248,6 +249,16 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||||
dependee = this->GlobalGenerator->FindTarget(0, dependee_name);
|
dependee = this->GlobalGenerator->FindTarget(0, dependee_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip targets that will not really be linked. This is probably a
|
||||||
|
// name conflict between an external library and an executable
|
||||||
|
// within the project.
|
||||||
|
if(linking && dependee &&
|
||||||
|
dependee->GetType() == cmTarget::EXECUTABLE &&
|
||||||
|
!dependee->IsExecutableWithExports())
|
||||||
|
{
|
||||||
|
dependee = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// If not found then skip then the dependee.
|
// If not found then skip then the dependee.
|
||||||
if(!dependee)
|
if(!dependee)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,8 @@ private:
|
||||||
void CollectTargets();
|
void CollectTargets();
|
||||||
void CollectDepends();
|
void CollectDepends();
|
||||||
void CollectTargetDepends(int depender_index);
|
void CollectTargetDepends(int depender_index);
|
||||||
void AddTargetDepend(int depender_index, const char* dependee_name);
|
void AddTargetDepend(int depender_index, const char* dependee_name,
|
||||||
|
bool linking);
|
||||||
void ComputeFinalDepends(cmComputeComponentGraph const& ccg);
|
void ComputeFinalDepends(cmComputeComponentGraph const& ccg);
|
||||||
|
|
||||||
cmGlobalGenerator* GlobalGenerator;
|
cmGlobalGenerator* GlobalGenerator;
|
||||||
|
|
Loading…
Reference in New Issue