diff options
-rw-r--r-- | Source/cmLocalGenerator.cxx | 12 | ||||
-rw-r--r-- | Source/cmOrderLinkDirectories.cxx | 86 | ||||
-rw-r--r-- | Source/cmOrderLinkDirectories.h | 13 | ||||
-rw-r--r-- | Tests/Complex/Executable/complex.cxx | 4 | ||||
-rw-r--r-- | Tests/ComplexOneConfig/Executable/complex.cxx | 4 | ||||
-rw-r--r-- | Tests/ComplexRelativePaths/Executable/complex.cxx | 4 |
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) { |