From f8f5dde2eec468f8c2ccebabb9771b5f8d21f864 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 29 Jul 2008 14:57:00 -0400 Subject: 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. --- Source/cmComputeLinkInformation.cxx | 4 +++ Source/cmOrderDirectories.cxx | 72 +++++++++++++++++++++++++++++++++++-- Source/cmOrderDirectories.h | 2 ++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 0c72e4f..119248e 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -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; } diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx index c618a57..54f23f7 100644 --- a/Source/cmOrderDirectories.cxx +++ b/Source/cmOrderDirectories.cxx @@ -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::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()); } //---------------------------------------------------------------------------- diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h index aa09a4e..5407733 100644 --- a/Source/cmOrderDirectories.h +++ b/Source/cmOrderDirectories.h @@ -54,6 +54,7 @@ private: bool OrderedDirectoriesComputed; std::vector ConstraintEntries; + std::vector ImplicitDirEntries; std::vector UserDirectories; cmsys::RegularExpression RemoveLibraryExtension; std::vector 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(); -- cgit v0.12