summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmLocalGenerator.cxx12
-rw-r--r--Source/cmOrderLinkDirectories.cxx86
-rw-r--r--Source/cmOrderLinkDirectories.h13
-rw-r--r--Tests/Complex/Executable/complex.cxx4
-rw-r--r--Tests/ComplexOneConfig/Executable/complex.cxx4
-rw-r--r--Tests/ComplexRelativePaths/Executable/complex.cxx4
6 files changed, 104 insertions, 19 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 9d65c2b..cb60d47 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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);
diff --git a/Source/cmOrderLinkDirectories.cxx b/Source/cmOrderLinkDirectories.cxx
index 4d74c47..5a3b405 100644
--- a/Source/cmOrderLinkDirectories.cxx
+++ b/Source/cmOrderLinkDirectories.cxx
@@ -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;
+}
diff --git a/Source/cmOrderLinkDirectories.h b/Source/cmOrderLinkDirectories.h
index f5aca3d..37c1462 100644
--- a/Source/cmOrderLinkDirectories.h
+++ b/Source/cmOrderLinkDirectories.h
@@ -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;
diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx
index 5b8cebd..1f4c21a 100644
--- a/Tests/Complex/Executable/complex.cxx
+++ b/Tests/Complex/Executable/complex.cxx
@@ -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)
{
diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx
index 5b8cebd..1f4c21a 100644
--- a/Tests/ComplexOneConfig/Executable/complex.cxx
+++ b/Tests/ComplexOneConfig/Executable/complex.cxx
@@ -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)
{
diff --git a/Tests/ComplexRelativePaths/Executable/complex.cxx b/Tests/ComplexRelativePaths/Executable/complex.cxx
index 5b8cebd..1f4c21a 100644
--- a/Tests/ComplexRelativePaths/Executable/complex.cxx
+++ b/Tests/ComplexRelativePaths/Executable/complex.cxx
@@ -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)
{