diff options
author | Brad King <brad.king@kitware.com> | 2006-04-04 18:25:17 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2006-04-04 18:25:17 (GMT) |
commit | 57a9e26c151f429bc41dd90e86bc50ada9600bd1 (patch) | |
tree | 85d6261d26a455c99ecb59a518058d26d0481081 | |
parent | e45ef47bb8081ddc20f3f1997f253184e4adfcc8 (diff) | |
download | CMake-57a9e26c151f429bc41dd90e86bc50ada9600bd1.zip CMake-57a9e26c151f429bc41dd90e86bc50ada9600bd1.tar.gz CMake-57a9e26c151f429bc41dd90e86bc50ada9600bd1.tar.bz2 |
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.
-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) { |