diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2005-02-24 18:16:41 (GMT) |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2005-02-24 18:16:41 (GMT) |
commit | ff812580ebec0b7ff908feeb256ad263bfc0c41a (patch) | |
tree | 0d99dfaa7a1790bd9435481d0ff8fdbe215a99c9 | |
parent | 9c4997bf06361b05ddad6d23388086b012d381fb (diff) | |
download | CMake-ff812580ebec0b7ff908feeb256ad263bfc0c41a.zip CMake-ff812580ebec0b7ff908feeb256ad263bfc0c41a.tar.gz CMake-ff812580ebec0b7ff908feeb256ad263bfc0c41a.tar.bz2 |
ENH: add a new library path ordering algorithm to make sure -L paths will pick the correct libraries if possible
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 156 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmOrderLinkDirectories.cxx | 356 | ||||
-rw-r--r-- | Source/cmOrderLinkDirectories.h | 126 | ||||
-rwxr-xr-x | bootstrap | 1 |
6 files changed, 550 insertions, 94 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 8e09cfd..6ded4e8 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -44,6 +44,7 @@ SET(SRCS cmMakeDepend.h cmMakefile.cxx cmMakefile.h + cmOrderLinkDirectories.cxx cmSourceFile.cxx cmSourceFile.h cmSourceGroup.cxx diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 0943c0c..3b91dc8 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -20,6 +20,7 @@ #include "cmMakefile.h" #include "cmGeneratedFileStream.h" #include "cmSourceFile.h" +#include "cmOrderLinkDirectories.h" cmLocalGenerator::cmLocalGenerator() { @@ -1077,6 +1078,16 @@ void cmLocalGenerator::GetTargetFlags(std::string& linkLibs, } +void +cmLocalGenerator::DetermineLibraryPathOrder(const cmTarget& target, + std::vector<std::string>& + linkPaths, + std::vector<std::string>& + linkLibs) +{ + +} + /** * Output the linking rules on a command line. For executables, * targetLibrary should be a NULL pointer. For libraries, it should point @@ -1088,7 +1099,6 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, { // Try to emit each search path once std::set<cmStdString> emitted; - // Embed runtime search paths if possible and if required. bool outputRuntime = true; std::string runtimeFlag; @@ -1097,12 +1107,21 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); buildType = cmSystemTools::UpperCase(buildType); - + cmTarget::LinkLibraryType cmakeBuildType = cmTarget::GENERAL; + if(buildType == "DEBUG") + { + cmakeBuildType = cmTarget::DEBUG; + } + if(buildType.size()) + { + cmakeBuildType = cmTarget::OPTIMIZED; + } const char* linkLanguage = tgt.GetLinkerLanguage(this->GetGlobalGenerator()); if(!linkLanguage) { - cmSystemTools::Error("CMake can not determine linker language for target:", - tgt.GetName()); + cmSystemTools:: + Error("CMake can not determine linker language for target:", + tgt.GetName()); return; } std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; @@ -1137,8 +1156,32 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, linkLibs += " "; } - const std::vector<std::string>& libdirs = tgt.GetLinkDirectories(); - for(std::vector<std::string>::const_iterator libDir = libdirs.begin(); + cmOrderLinkDirectories orderLibs; + std::string ext = + m_Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"); + if(ext.size()) + { + orderLibs.AddLinkExtension(ext.c_str()); + } + ext = + m_Makefile->GetSafeDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"); + if(ext.size()) + { + orderLibs.AddLinkExtension(ext.c_str()); + } + ext = + m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); + if(ext.size()) + { + orderLibs.AddLinkExtension(ext.c_str()); + } + // compute the correct order for -L paths + orderLibs.SetLinkInformation(tgt, cmakeBuildType, targetLibrary); + orderLibs.DetermineLibraryPathOrder(); + std::vector<cmStdString> libdirs; + std::vector<cmStdString> linkItems; + orderLibs.GetLinkerInformation(libdirs, linkItems); + for(std::vector<cmStdString>::const_iterator libDir = libdirs.begin(); libDir != libdirs.end(); ++libDir) { std::string libpath = this->ConvertToOutputForExisting(libDir->c_str()); @@ -1169,103 +1212,30 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout, } } - std::string linkSuffix = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); + std::string linkSuffix = + m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX"); std::string regexp = ".*\\"; regexp += linkSuffix; regexp += "$"; cmsys::RegularExpression hasSuffix(regexp.c_str()); std::string librariesLinked; - const cmTarget::LinkLibraries& libs = tgt.GetLinkLibraries(); - for(cmTarget::LinkLibraries::const_iterator lib = libs.begin(); - lib != libs.end(); ++lib) - { - // Don't link the library against itself! - if(targetLibrary && (lib->first == targetLibrary)) continue; - // use the correct lib for the current configuration - if (lib->second == cmTarget::DEBUG && buildType != "DEBUG") - { - continue; - } - if (lib->second == cmTarget::OPTIMIZED && buildType == "DEBUG") - { - continue; - } - // skip zero size library entries, this may happen - // if a variable expands to nothing. - if (lib->first.size() == 0) continue; - // if it is a full path break it into -L and -l + for(std::vector<cmStdString>::iterator lib = linkItems.begin(); + lib != linkItems.end(); ++lib) + { + cmStdString& linkItem = *lib; + // check to see if the link item has a -l already cmsys::RegularExpression reg("^([ \t]*\\-[lWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)"); - if(lib->first.find('/') != std::string::npos - && !reg.find(lib->first)) + if(!reg.find(linkItem)) { - std::string dir, file; - cmSystemTools::SplitProgramPath(lib->first.c_str(), - dir, file); - std::string libpath = this->ConvertToOutputForExisting(dir.c_str()); - if(emitted.insert(libpath).second) - { - linkLibs += libPathFlag; - linkLibs += libpath; - linkLibs += " "; - if(outputRuntime) - { - runtimeDirs.push_back( libpath ); - } - } - cmsys::RegularExpression libname("^lib([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*"); - cmsys::RegularExpression libname_noprefix("([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*"); - if(libname.find(file)) - { - // Library had "lib" prefix. - librariesLinked += libLinkFlag; - file = libname.match(1); - // if ignore libprefix is on, - // then add the lib prefix back into the name - if(m_IgnoreLibPrefix) - { - file = "lib" + file; - } - librariesLinked += file; - if(linkSuffix.size() && !hasSuffix.find(file)) - { - librariesLinked += linkSuffix; - } - librariesLinked += " "; - } - else if(libname_noprefix.find(file)) - { - // Library had no "lib" prefix. - librariesLinked += libLinkFlag; - file = libname_noprefix.match(1); - librariesLinked += file; - if(linkSuffix.size() && !hasSuffix.find(file)) - { - librariesLinked += linkSuffix; - } - librariesLinked += " "; - } - else - { - // Error parsing the library name. Just use the full path. - // The linker will give an error if it is invalid. - librariesLinked += lib->first; - librariesLinked += " "; - } + librariesLinked += libLinkFlag; } - // not a full path, so add -l name - else + librariesLinked += linkItem; + + if(linkSuffix.size() && !hasSuffix.find(linkItem)) { - if(!reg.find(lib->first)) - { - librariesLinked += libLinkFlag; - } - librariesLinked += lib->first; - if(linkSuffix.size() && !hasSuffix.find(lib->first)) - { - librariesLinked += linkSuffix; - } - librariesLinked += " "; + librariesLinked += linkSuffix; } + librariesLinked += " "; } linkLibs += librariesLinked; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 8dea2d5..88dba50 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -103,7 +103,9 @@ public: ///! for existing files convert to output path and short path if spaces std::string ConvertToOutputForExisting(const char* p); - + void DetermineLibraryPathOrder(const cmTarget& target, + std::vector<std::string>& linkPaths, + std::vector<std::string>& linkLibs); protected: /** Construct a script from the given list of command lines. */ std::string ConstructScript(const cmCustomCommandLines& commandLines, diff --git a/Source/cmOrderLinkDirectories.cxx b/Source/cmOrderLinkDirectories.cxx new file mode 100644 index 0000000..7697aaa --- /dev/null +++ b/Source/cmOrderLinkDirectories.cxx @@ -0,0 +1,356 @@ +#include "cmOrderLinkDirectories.h" +#include "cmSystemTools.h" +#include "cmsys/RegularExpression.hxx" + + +inline void printv(std::vector<cmStdString>& v) +{ + for(unsigned int i = 0; i < v.size(); ++i) + { + std::cerr << "[" << v[i] << "]" << " "; + } + std::cerr << "\n"; +} + + +//------------------------------------------------------------------- +bool cmOrderLinkDirectories::LibraryInDirectory(const char* dir, + const char* lib) +{ + cmStdString path = dir; + path += "/"; + path += lib; + // first look for the library as given + if(cmSystemTools::FileExists(path.c_str())) + { + return true; + } + // next remove the extension (.a, .so ) and look for the library + // under a different name as the linker can do either + if(m_RemoveLibraryExtension.find(lib)) + { + cmStdString lib = m_RemoveLibraryExtension.match(1); + cmStdString ext = m_RemoveLibraryExtension.match(2); + for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin(); + i != m_LinkExtensions.end(); ++i) + { + if(ext != *i) + { + path = dir; + path += "/"; + path += lib + *i; + if(cmSystemTools::FileExists(path.c_str())) + { + return true; + } + } + } + } + return false; +} + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::FindLibrariesInSeachPaths() +{ + for(std::set<cmStdString>::iterator dir = m_LinkPathSet.begin(); + dir != m_LinkPathSet.end(); ++dir) + { + for(std::map<cmStdString, Library>::iterator lib + = m_FullPathLibraries.begin(); + lib != m_FullPathLibraries.end(); ++lib) + { + if(lib->second.Path != *dir) + { + if(LibraryInDirectory(dir->c_str(), lib->second.File.c_str())) + { + m_LibraryToDirectories[lib->second.FullPath].push_back(*dir); + } + } + } + } +} + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::FindIndividualLibraryOrders() +{ + for(std::vector<Library>::iterator lib = m_MultiDirectoryLibraries.begin(); + lib != m_MultiDirectoryLibraries.end(); ++lib) + { + std::vector<cmStdString>& dirs = m_LibraryToDirectories[lib->FullPath]; + m_DirectoryToAfterList[lib->Path] = dirs; + } +} + + +//------------------------------------------------------------------- +void +cmOrderLinkDirectories::PrintMap(const char* name, + std::map<cmStdString, std::vector<cmStdString> >& m) +{ + std::cerr << name << "\n"; + for(std::map<cmStdString, std::vector<cmStdString> >::iterator i = + m.begin(); i != m.end(); + ++i) + { + std::cerr << i->first << ": "; + for(std::vector<cmStdString>::iterator l = i->second.begin(); + l != i->second.end(); ++l) + { + std::cerr << *l << " "; + } + std::cerr << "\n"; + } +} + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::CreateRegularExpressions() +{ + cmStdString libext = "("; + bool first = true; + for(std::vector<cmStdString>::iterator i = m_LinkExtensions.begin(); + i != m_LinkExtensions.end(); ++i) + { + if(!first) + { + libext += "|"; + } + first = false; + libext += "\\"; + libext += *i; + } + libext += ").*"; + cmStdString reg("(.*)"); + reg += libext; + m_RemoveLibraryExtension.compile(reg.c_str()); + reg = "^lib([^/]*)"; + reg += libext; + m_ExtractBaseLibraryName.compile(reg.c_str()); + reg = "([^/]*)"; + reg += libext; + m_ExtractBaseLibraryNameNoPrefix.compile(reg.c_str()); +} + + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::PrepareLinkTargets() +{ + for(std::vector<cmStdString>::iterator i = m_LinkItems.begin(); + i != m_LinkItems.end(); ++i) + { + // separate the library name from libfoo.a or foo.a + if(m_ExtractBaseLibraryName.find(*i)) + { + *i = m_ExtractBaseLibraryName.match(1); + } + else if(m_ExtractBaseLibraryNameNoPrefix.find(*i)) + { + *i = m_ExtractBaseLibraryNameNoPrefix.match(1); + } + } +} + +//------------------------------------------------------------------- +bool cmOrderLinkDirectories::CanBeBefore(const cmStdString& d1, + const cmStdString& d2) +{ + if(m_DirectoryToAfterList.count(d2) == 0) + { + return true; + } + std::vector<cmStdString>& d2dirs = m_DirectoryToAfterList[d2]; + // is d1 in the d2's list of directories that d2 must be before + // if so, then d1 can not come before d2 + for(std::vector<cmStdString>::iterator i = d2dirs.begin(); + i != d2dirs.end(); ++i) + { + if(*i == d1) + { + return false; + } + } + return true; +} + +// This is a stl function object used to sort +// the vector of library paths. It returns true +// if left directory can be before right directory (no swap). +// It also checks for the impossible case of two libraries and +// two directories that have both libraries. +struct cmOrderLinkDirectoriesCompare + : public std::binary_function <cmStdString, cmStdString, bool> +{ + cmOrderLinkDirectoriesCompare() + { + This = 0; + } + bool operator()( + const cmStdString& left, + const cmStdString& right + ) const + { + bool ret = This->CanBeBefore(left, right); + if(!ret) + { + // check for the case when both libraries have to come + // before each other + if(!This->CanBeBefore(right, left)) + { + This->AddImpossible(right, left); + } + } + return ret; + } + cmOrderLinkDirectories* This; +}; + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::AddImpossible(const cmStdString& d1, + const cmStdString& d2) +{ + m_ImposibleDirectories.insert(d1); + m_ImposibleDirectories.insert(d2); +} + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::OrderPaths(std::vector<cmStdString>& + orderedPaths) +{ + cmOrderLinkDirectoriesCompare comp; + comp.This = this; + std::sort(orderedPaths.begin(), orderedPaths.end(), comp); +} + +//------------------------------------------------------------------- +void cmOrderLinkDirectories::SetLinkInformation(const cmTarget& target, + cmTarget::LinkLibraryType + linktype, + const char* targetLibrary) +{ + // collect the search paths from the target into paths set + const std::vector<std::string>& searchPaths = target.GetLinkDirectories(); + for(std::vector<std::string>::const_iterator p = searchPaths.begin(); + p != searchPaths.end(); ++p) + { + m_LinkPathSet.insert(*p); + } + // collect the link items from the target and put it into libs + const cmTarget::LinkLibraries& tlibs = target.GetLinkLibraries(); + std::vector<cmStdString> libs; + for(cmTarget::LinkLibraries::const_iterator lib = tlibs.begin(); + lib != tlibs.end(); ++lib) + { + // skip zero size library entries, this may happen + // if a variable expands to nothing. + if (lib->first.size() == 0) + { + continue; + } + // Don't link the library against itself! + if(targetLibrary && (lib->first == targetLibrary)) + { + continue; + } + // use the correct lib for the current configuration + if (lib->second == cmTarget::DEBUG && linktype != cmTarget::DEBUG) + { + continue; + } + if (lib->second == cmTarget::OPTIMIZED && + linktype != cmTarget::OPTIMIZED) + { + continue; + } + m_RawLinkItems.push_back(lib->first); + } +} + +//------------------------------------------------------------------- +bool cmOrderLinkDirectories::DetermineLibraryPathOrder() +{ + // set up all the regular expressions + this->CreateRegularExpressions(); + std::vector<cmStdString> finalOrderPaths; + // find all libs that are full paths + Library aLib; + cmStdString dir; + cmStdString file; + for(unsigned int i=0; i < m_RawLinkItems.size(); ++i) + { + if(cmSystemTools::FileIsFullPath(m_RawLinkItems[i].c_str())) + { + cmSystemTools::SplitProgramPath(m_RawLinkItems[i].c_str(), + dir, file); + m_LinkPathSet.insert(dir); + aLib.FullPath = m_RawLinkItems[i]; + aLib.File = file; + aLib.Path = dir; + m_FullPathLibraries[aLib.FullPath] = aLib; + m_LinkItems.push_back(file); + } + else + { + m_LinkItems.push_back(m_RawLinkItems[i]); + } + } + this->FindLibrariesInSeachPaths(); + for(std::map<cmStdString, std::vector<cmStdString> >::iterator lib = + m_LibraryToDirectories.begin(); lib!= m_LibraryToDirectories.end(); + ++lib) + { + if(lib->second.size() > 0) + { + m_MultiDirectoryLibraries.push_back(m_FullPathLibraries[lib->first]); + } + else + { + m_SingleDirectoryLibraries.push_back(m_FullPathLibraries[lib->first]); + } + } + this->FindIndividualLibraryOrders(); + m_SortedSearchPaths.clear(); + for(std::set<cmStdString>::iterator i = m_LinkPathSet.begin(); + i != m_LinkPathSet.end(); ++i) + { + m_SortedSearchPaths.push_back(*i); + } + + this->OrderPaths(m_SortedSearchPaths); + // now turn libfoo.a into foo and foo.a into foo + // This will prepare the link items for -litem + this->PrepareLinkTargets(); + // this->PrintMap("m_DirectoryToAfterList", m_DirectoryToAfterList); + //this->PrintMap("m_LibraryToDirectories", m_LibraryToDirectories); + //std::cerr << "link objects: "; + //printv(m_LinkItems); + if(m_ImposibleDirectories.size()) + { + return false; + } + return true; +} + +std::string cmOrderLinkDirectories::GetWarnings() +{ + std::string warning = "It is impossible to order the linker search path in such a way that libraries specified as full paths will be picked by the linker.\nDirectories and libraries involvied are:\n"; + for(std::set<cmStdString>::iterator i = m_ImposibleDirectories.begin(); + i != m_ImposibleDirectories.end(); ++i) + { + warning += "Directory: "; + warning += *i; + warning += " contains "; + std::map<cmStdString, std::vector<cmStdString> >::iterator j; + for(j = m_LibraryToDirectories.begin(); + j != m_LibraryToDirectories.end(); ++j) + { + if(std::find(j->second.begin(), j->second.end(), *i) + != j->second.end()) + { + warning += "Library: "; + warning += j->first; + warning += "\n"; + } + } + } + warning += "\n"; + return warning; +} diff --git a/Source/cmOrderLinkDirectories.h b/Source/cmOrderLinkDirectories.h new file mode 100644 index 0000000..234a343 --- /dev/null +++ b/Source/cmOrderLinkDirectories.h @@ -0,0 +1,126 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#ifndef cmOrderLinkDirectories_h +#define cmOrderLinkDirectories_h + +#include <cmStandardIncludes.h> +#include <map> +#include <vector> +#include "cmTarget.h" +#include "cmsys/RegularExpression.hxx" + + +/** \class cmOrderLinkDirectories + * \brief Compute the best -L path order + * + * This class computes the best order for -L paths. + * It tries to make sure full path specified libraries are + * used. For example if you have /usr/mylib/libfoo.a on as + * a link library for a target, and you also have /usr/lib/libbar.a + * and you also have /usr/lib/libfoo.a, then you would + * want -L/usr/mylib -L/usr/lib to make sure the correct libfoo.a is + * found by the linker. The algorithm is as follows: + * - foreach library create a vector of directories it exists in. + * - foreach directory create a vector of directories that must come + * after it, put this in a map<dir, vector<dir>> mapping from a directory + * to the vector of directories that it must be before. + * - put all directories into a vector + * - sort the vector with a compare function CanBeBefore + * CanBeBefore returns true if a directory is OK to be before + * another directory. This is determined by looking at the + * map<dir vector<dir>> and seeing if d1 is in the vector for d2. + */ +class cmOrderLinkDirectories +{ +public: + ///! set link information from the target + void SetLinkInformation(const cmTarget&, cmTarget::LinkLibraryType, + const char* targetLibrary); + ///! Compute the best order for -L paths from GetLinkLibraries + bool DetermineLibraryPathOrder(); + ///! Get the results from DetermineLibraryPathOrder + void GetLinkerInformation(std::vector<cmStdString>& searchPaths, + std::vector<cmStdString>& linkItems) + { + linkItems = m_LinkItems; + searchPaths = m_SortedSearchPaths; + } + // should be set from CMAKE_STATIC_LIBRARY_SUFFIX, + // CMAKE_SHARED_LIBRARY_SUFFIX + // CMAKE_LINK_LIBRARY_SUFFIX + void AddLinkExtension(const char* e) + { + m_LinkExtensions.push_back(e); + } + // Return any warnings if the exist + std::string GetWarnings(); + + // structure to hold a full path library link item + struct Library + { + cmStdString FullPath; + cmStdString File; + cmStdString Path; + }; + friend struct cmOrderLinkDirectoriesCompare; +private: + void CreateRegularExpressions(); + void DetermineLibraryPathOrder(std::vector<cmStdString>& searchPaths, + std::vector<cmStdString>& libs, + std::vector<cmStdString>& sortedPaths); + void PrepareLinkTargets(); + bool LibraryInDirectory(const char* dir, const char* lib); + void FindLibrariesInSeachPaths(); + void FindIndividualLibraryOrders(); + void PrintMap(const char* name, + std::map<cmStdString, std::vector<cmStdString> >& m); + void OrderPaths(std::vector<cmStdString>& paths); + bool CanBeBefore(const cmStdString& d1, + const cmStdString& d2); + void AddImpossible(const cmStdString& , + const cmStdString& ); +private: + // map from library to directories that it is in other than its full path + std::map<cmStdString, std::vector<cmStdString> > m_LibraryToDirectories; + // map from directory to vector of directories that must be after it + std::map<cmStdString, std::vector<cmStdString> > m_DirectoryToAfterList; + // map from full path to a Library struct + std::map<cmStdString, Library> m_FullPathLibraries; + // libraries that are found in multiple directories + std::vector<Library> m_MultiDirectoryLibraries; + // libraries that are only found in one directory + std::vector<Library> m_SingleDirectoryLibraries; + // This is a vector of all the link objects -lm or m + std::vector<cmStdString> m_LinkItems; + // Unprocessed link items + std::vector<cmStdString> m_RawLinkItems; + // This vector holds the sorted -L paths + std::vector<cmStdString> m_SortedSearchPaths; + // This is the set of -L paths unsorted, but unique + std::set<cmStdString> m_LinkPathSet; + // the names of link extensions + std::vector<cmStdString> m_LinkExtensions; + // set of directories that can not be put in the correct order + std::set<cmStdString> m_ImposibleDirectories; + // library regular expressions + cmsys::RegularExpression m_RemoveLibraryExtension; + cmsys::RegularExpression m_ExtractBaseLibraryName; + cmsys::RegularExpression m_ExtractBaseLibraryNameNoPrefix; + +}; + +#endif @@ -54,6 +54,7 @@ CMAKE_CXX_SOURCES="\ cmCustomCommand \ cmCacheManager \ cmListFileCache \ + cmOrderLinkDirectories \ cmSourceGroup" CMAKE_C_SOURCES="\ |