| /*========================================================================= |
| |
| 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: |
| cmOrderLinkDirectories(); |
| ///! set link information from the target |
| void SetLinkInformation(const char* targetName, |
| const std::vector<std::string>& linkLibraries, |
| 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 |
| void GetLinkerInformation(std::vector<cmStdString>& searchPaths, |
| std::vector<cmStdString>& linkItems) |
| { |
| linkItems = this->LinkItems; |
| searchPaths = this->SortedSearchPaths; |
| } |
| // should be set from CMAKE_STATIC_LIBRARY_SUFFIX, |
| // CMAKE_SHARED_LIBRARY_SUFFIX |
| // CMAKE_LINK_LIBRARY_SUFFIX |
| void AddLinkExtension(const char* e) |
| { |
| if(e && *e) |
| { |
| this->LinkExtensions.push_back(e); |
| } |
| } |
| // should be set from CMAKE_STATIC_LIBRARY_PREFIX |
| void SetLinkPrefix(const char* s) |
| { |
| if(s) |
| { |
| this->LinkPrefix = s; |
| } |
| } |
| // Return any warnings if the exist |
| std::string GetWarnings(); |
| // return a list of all full path libraries |
| void GetFullPathLibraries(std::vector<cmStdString>& libs); |
| |
| // structure to hold a full path library link item |
| struct Library |
| { |
| cmStdString FullPath; |
| cmStdString File; |
| cmStdString Path; |
| }; |
| friend struct cmOrderLinkDirectoriesCompare; |
| void DebugOn() |
| { |
| this->Debug = true; |
| } |
| |
| private: |
| void CreateRegularExpressions(); |
| void DetermineLibraryPathOrder(std::vector<cmStdString>& searchPaths, |
| std::vector<cmStdString>& libs, |
| std::vector<cmStdString>& sortedPaths); |
| void PrepareLinkTargets(); |
| bool LibraryInDirectory(const char* desiredLib, |
| const char* dir, const char* lib); |
| void FindLibrariesInSearchPaths(); |
| void FindIndividualLibraryOrders(); |
| void PrintMap(const char* name, |
| std::map<cmStdString, std::vector<cmStdString> >& m); |
| void PrintVector(const char* name, |
| std::vector<std::pair<cmStdString, |
| std::vector<cmStdString> > >& m); |
| 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 |
| std::vector<std::pair<cmStdString, std::vector<cmStdString> > > DirectoryToAfterList; |
| std::set<cmStdString> DirectoryToAfterListEmitted; |
| // map from full path to a Library struct |
| std::map<cmStdString, Library> FullPathLibraries; |
| // libraries that are found in multiple directories |
| std::vector<Library> MultiDirectoryLibraries; |
| // libraries that are only found in one directory |
| std::vector<Library> SingleDirectoryLibraries; |
| // This is a vector of all the link objects -lm or m |
| std::vector<cmStdString> LinkItems; |
| // Unprocessed link items |
| std::vector<cmStdString> RawLinkItems; |
| // This vector holds the sorted -L paths |
| std::vector<cmStdString> SortedSearchPaths; |
| // This vector holds the -F paths |
| std::set<cmStdString> EmittedFrameworkPaths; |
| // This is the set of -L paths unsorted, but unique |
| std::set<cmStdString> LinkPathSet; |
| // the names of link extensions |
| std::vector<cmStdString> LinkExtensions; |
| // the names of link prefixes |
| cmStdString LinkPrefix; |
| // set of directories that can not be put in the correct order |
| 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; |
| cmsys::RegularExpression ExtractBaseLibraryNameNoPrefix; |
| cmsys::RegularExpression SplitFramework; |
| bool Debug; |
| }; |
| |
| #endif |