Commit f8f5dde2 authored by Brad King's avatar Brad King

ENH: Warn when system libraries may be hidden.

We never explicitly specify system library directories in linker or
runtime search paths.  Furthermore, libraries in these directories are
always linked by asking the linker to search for them.  We need to
generate a warning when explicitly specified search directories contain
files that may hide the system libraries during the search.
parent 01d143c7
......@@ -1131,6 +1131,10 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
// portion. This will allow the system linker to locate the proper
// library for the architecture at link time.
this->AddUserItem(file, false);
// Make sure the link directory ordering will find the library.
this->OrderLinkerSearchPath->AddLinkLibrary(item);
return true;
}
......
......@@ -69,6 +69,29 @@ public:
}
}
}
void FindImplicitConflicts(cmOStringStream& w)
{
bool first = true;
for(unsigned int i=0; i < this->OD->OriginalDirectories.size(); ++i)
{
// Check if this directory conflicts with the entry.
std::string const& dir = this->OD->OriginalDirectories[i];
if(dir != this->Directory && this->FindConflict(dir))
{
// The library will be found in this directory but it is
// supposed to be found in an implicit search directory.
if(first)
{
first = false;
w << " ";
this->Report(w);
w << " in " << this->Directory << " may be hidden by files in:\n";
}
w << " " << dir << "\n";
}
}
}
protected:
virtual bool FindConflict(std::string const& dir) = 0;
......@@ -258,6 +281,12 @@ cmOrderDirectories::~cmOrderDirectories()
{
delete *i;
}
for(std::vector<cmOrderDirectoriesConstraint*>::iterator
i = this->ImplicitDirEntries.begin();
i != this->ImplicitDirEntries.end(); ++i)
{
delete *i;
}
}
//----------------------------------------------------------------------------
......@@ -280,13 +309,15 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
// Add the runtime library at most once.
if(this->EmmittedConstraintSOName.insert(fullPath).second)
{
// Avoid dealing with implicit directories.
// Implicit link directories need special handling.
if(!this->ImplicitDirectories.empty())
{
std::string dir = cmSystemTools::GetFilenamePath(fullPath);
if(this->ImplicitDirectories.find(dir) !=
this->ImplicitDirectories.end())
{
this->ImplicitDirEntries.push_back(
new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
return;
}
}
......@@ -313,13 +344,15 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath)
// Add the link library at most once.
if(this->EmmittedConstraintLibrary.insert(fullPath).second)
{
// Avoid dealing with implicit directories.
// Implicit link directories need special handling.
if(!this->ImplicitDirectories.empty())
{
std::string dir = cmSystemTools::GetFilenamePath(fullPath);
if(this->ImplicitDirectories.find(dir) !=
this->ImplicitDirectories.end())
{
this->ImplicitDirEntries.push_back(
new cmOrderDirectoriesConstraintLibrary(this, fullPath));
return;
}
}
......@@ -367,7 +400,7 @@ void cmOrderDirectories::CollectOriginalDirectories()
di = this->UserDirectories.begin();
di != this->UserDirectories.end(); ++di)
{
// Avoid dealing with implicit directories.
// We never explicitly specify implicit link directories.
if(this->ImplicitDirectories.find(*di) !=
this->ImplicitDirectories.end())
{
......@@ -450,6 +483,39 @@ void cmOrderDirectories::FindConflicts()
std::unique(i->begin(), i->end(), cmOrderDirectoriesCompare());
i->erase(last, i->end());
}
// Check items in implicit link directories.
this->FindImplicitConflicts();
}
//----------------------------------------------------------------------------
void cmOrderDirectories::FindImplicitConflicts()
{
// Check for items in implicit link directories that have conflicts
// in the explicit directories.
cmOStringStream conflicts;
for(unsigned int i=0; i < this->ImplicitDirEntries.size(); ++i)
{
this->ImplicitDirEntries[i]->FindImplicitConflicts(conflicts);
}
// Skip warning if there were no conflicts.
std::string text = conflicts.str();
if(text.empty())
{
return;
}
// Warn about the conflicts.
cmOStringStream w;
w << "Cannot generate a safe " << this->Purpose
<< " for target " << this->Target->GetName()
<< " because files in some directories may conflict with "
<< " libraries in implicit directories:\n"
<< text
<< "Some of these libraries may not be found correctly.";
this->GlobalGenerator->GetCMakeInstance()
->IssueMessage(cmake::WARNING, w.str(), this->Target->GetBacktrace());
}
//----------------------------------------------------------------------------
......
......@@ -54,6 +54,7 @@ private:
bool OrderedDirectoriesComputed;
std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
std::vector<cmOrderDirectoriesConstraint*> ImplicitDirEntries;
std::vector<std::string> UserDirectories;
cmsys::RegularExpression RemoveLibraryExtension;
std::vector<std::string> LinkExtensions;
......@@ -66,6 +67,7 @@ private:
void CollectOriginalDirectories();
int AddOriginalDirectory(std::string const& dir);
void FindConflicts();
void FindImplicitConflicts();
void OrderDirectories();
void VisitDirectory(unsigned int i);
void DiagnoseCycle();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment