BUG: Fixed cmOrderLinkDirectories to make sure cmake-built libraries are found properly. Also taking libraries that will be built but may not yet exist into account. The per-configuration subdirectories that are included by generators in the link path are checked for conflicting libraries also. Potentially conflicting libraries that are actually symlinks back to the desired library are no longer considered conflicting, which avoids bogus impossible ordering warnings.

This commit is contained in:
Brad King 2006-04-04 14:25:17 -04:00
parent e45ef47bb8
commit 57a9e26c15
6 changed files with 104 additions and 19 deletions

View File

@ -1392,10 +1392,11 @@ cmLocalGenerator::ComputeLinkInformation(cmTarget& target,
if(tgt)
{
// This is a CMake target. Ask the target for its real name.
linkLibraries.push_back(tgt->GetFullName(config));
std::string realLibrary = tgt->GetFullPath(config);
linkLibraries.push_back(realLibrary);
if(fullPathLibs)
{
fullPathLibs->push_back(tgt->GetFullPath(config));
fullPathLibs->push_back(realLibrary);
}
}
else
@ -1433,9 +1434,14 @@ cmLocalGenerator::ComputeLinkInformation(cmTarget& target,
orderLibs.AddLinkExtension(i->c_str());
}
}
std::string configSubdir;
cmGlobalGenerator* gg = this->GetGlobalGenerator();
gg->AppendDirectoryForConfig("", config, "", configSubdir);
orderLibs.SetLinkInformation(target.GetName(),
linkLibraries,
linkDirectories);
linkDirectories,
gg->GetTargetManifest(),
configSubdir.c_str());
orderLibs.DetermineLibraryPathOrder();
std::vector<cmStdString> orderedLibs;
orderLibs.GetLinkerInformation(outDirs, orderedLibs);

View File

@ -11,14 +11,12 @@ cmOrderLinkDirectories::cmOrderLinkDirectories()
}
//-------------------------------------------------------------------
bool cmOrderLinkDirectories::LibraryInDirectory(const char* dir,
bool cmOrderLinkDirectories::LibraryInDirectory(const char* desiredLib,
const char* dir,
const char* libIn)
{
cmStdString path = dir;
path += "/";
path += libIn;
// first look for the library as given
if(cmSystemTools::FileExists(path.c_str()))
if(this->LibraryMayConflict(desiredLib, dir, libIn))
{
return true;
}
@ -33,10 +31,9 @@ bool cmOrderLinkDirectories::LibraryInDirectory(const char* dir,
{
if(ext != *i)
{
path = dir;
path += "/";
path += lib + *i;
if(cmSystemTools::FileExists(path.c_str()))
std::string fname = lib;
lib += *i;
if(this->LibraryMayConflict(desiredLib, dir, fname.c_str()))
{
return true;
}
@ -58,7 +55,8 @@ void cmOrderLinkDirectories::FindLibrariesInSearchPaths()
{
if(lib->second.Path != *dir)
{
if(this->LibraryInDirectory(dir->c_str(), lib->second.File.c_str()))
if(this->LibraryInDirectory(lib->second.FullPath.c_str(),
dir->c_str(), lib->second.File.c_str()))
{
this->LibraryToDirectories[lib->second.FullPath].push_back(*dir);
}
@ -244,12 +242,17 @@ void cmOrderLinkDirectories::OrderPaths(std::vector<cmStdString>&
void cmOrderLinkDirectories::SetLinkInformation(
const char* targetName,
const std::vector<std::string>& linkLibraries,
const std::vector<std::string>& linkDirectories
const std::vector<std::string>& linkDirectories,
const cmTargetManifest& manifest,
const char* configSubdir
)
{
// Save the target name.
this->TargetName = targetName;
// Save the subdirectory used for linking in this configuration.
this->ConfigSubdir = configSubdir? configSubdir : "";
// Merge the link directory search path given into our path set.
std::vector<cmStdString> empty;
for(std::vector<std::string>::const_iterator p = linkDirectories.begin();
@ -270,6 +273,17 @@ void cmOrderLinkDirectories::SetLinkInformation(
{
this->RawLinkItems.push_back(*l);
}
// Construct a set of files that will exist after building.
for(cmTargetManifest::const_iterator i = manifest.begin();
i != manifest.end(); ++i)
{
for(cmTargetSet::const_iterator j = i->second.begin();
j != i->second.end(); ++j)
{
this->ManifestFiles.insert(*j);
}
}
}
//-------------------------------------------------------------------
@ -464,3 +478,53 @@ void cmOrderLinkDirectories::GetFullPathLibraries(std::vector<cmStdString>&
}
}
//----------------------------------------------------------------------------
bool cmOrderLinkDirectories::LibraryMayConflict(const char* desiredLib,
const char* dir,
const char* fname)
{
// We need to check whether the given file may be picked up by the
// linker. This will occur if it exists as given or may be built
// using the name given.
bool found = false;
std::string path = dir;
path += "/";
path += fname;
if(this->ManifestFiles.find(path) != this->ManifestFiles.end())
{
found = true;
}
else if(cmSystemTools::FileExists(path.c_str()))
{
found = true;
}
// When linking with a multi-configuration build tool the
// per-configuration subdirectory is added to each link path. Check
// this subdirectory too.
if(!found && !this->ConfigSubdir.empty())
{
path = dir;
path += "/";
path += this->ConfigSubdir;
path += "/";
path += fname;
if(this->ManifestFiles.find(path) != this->ManifestFiles.end())
{
found = true;
}
else if(cmSystemTools::FileExists(path.c_str()))
{
found = true;
}
}
// A library conflicts if it is found and is not a symlink back to
// the desired library.
if(found)
{
return !cmSystemTools::SameFile(desiredLib, path.c_str());
}
return false;
}

View File

@ -51,7 +51,9 @@ public:
///! set link information from the target
void SetLinkInformation(const char* targetName,
const std::vector<std::string>& linkLibraries,
const std::vector<std::string>& linkDirectories);
const std::vector<std::string>& linkDirectories,
const cmTargetManifest& manifest,
const char* configSubdir);
///! Compute the best order for -L paths from GetLinkLibraries
bool DetermineLibraryPathOrder();
///! Get the results from DetermineLibraryPathOrder
@ -103,7 +105,8 @@ private:
std::vector<cmStdString>& libs,
std::vector<cmStdString>& sortedPaths);
void PrepareLinkTargets();
bool LibraryInDirectory(const char* dir, const char* lib);
bool LibraryInDirectory(const char* desiredLib,
const char* dir, const char* lib);
void FindLibrariesInSearchPaths();
void FindIndividualLibraryOrders();
void PrintMap(const char* name,
@ -114,7 +117,11 @@ private:
void OrderPaths(std::vector<cmStdString>& paths);
bool FindPathNotInDirectoryToAfterList(cmStdString& path);
std::string NoCaseExpression(const char* str);
bool LibraryMayConflict(const char* desiredLib,
const char* dir, const char* fname);
private:
// set of files that will exist when the build occurs
std::set<cmStdString> ManifestFiles;
// map from library to directories that it is in other than its full path
std::map<cmStdString, std::vector<cmStdString> > LibraryToDirectories;
// map from directory to vector of directories that must be after it
@ -144,6 +151,8 @@ private:
std::set<cmStdString> ImpossibleDirectories;
// Name of target
cmStdString TargetName;
// Subdirectory used for this configuration if any.
cmStdString ConfigSubdir;
// library regular expressions
cmsys::RegularExpression RemoveLibraryExtension;
cmsys::RegularExpression ExtractBaseLibraryName;

View File

@ -91,7 +91,9 @@ bool TestLibraryOrder(bool shouldFail)
orderLibs.AddLinkExtension(".so");
orderLibs.AddLinkExtension(".a");
orderLibs.SetLinkPrefix("lib");
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories);
cmTargetManifest manifest;
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
manifest, "");
bool ret = orderLibs.DetermineLibraryPathOrder();
if(!ret)
{

View File

@ -91,7 +91,9 @@ bool TestLibraryOrder(bool shouldFail)
orderLibs.AddLinkExtension(".so");
orderLibs.AddLinkExtension(".a");
orderLibs.SetLinkPrefix("lib");
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories);
cmTargetManifest manifest;
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
manifest, "");
bool ret = orderLibs.DetermineLibraryPathOrder();
if(!ret)
{

View File

@ -91,7 +91,9 @@ bool TestLibraryOrder(bool shouldFail)
orderLibs.AddLinkExtension(".so");
orderLibs.AddLinkExtension(".a");
orderLibs.SetLinkPrefix("lib");
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories);
cmTargetManifest manifest;
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
manifest, "");
bool ret = orderLibs.DetermineLibraryPathOrder();
if(!ret)
{