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:
parent
e45ef47bb8
commit
57a9e26c15
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue