From 96fd5909d9dd1ffe740230ce652d574cd01c62d5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 22 Jan 2008 09:13:04 -0500 Subject: ENH: Implement linking with paths to library files instead of -L and -l separation. See bug #3832 - This is purely an implementation improvement. No interface has changed. - Create cmComputeLinkInformation class - Move and re-implement logic from: cmLocalGenerator::ComputeLinkInformation cmOrderLinkDirectories - Link libraries to targets with their full path (if it is known) - Dirs specified with link_directories command still added with -L - Make link type specific to library names without paths (name libfoo.a without path becomes -Wl,-Bstatic -lfoo) - Make directory ordering specific to a runtime path computation feature (look for conflicting SONAMEs instead of library names) - Implement proper rpath support on HP-UX and AIX. --- Source/cmComputeLinkInformation.h | 165 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 Source/cmComputeLinkInformation.h (limited to 'Source/cmComputeLinkInformation.h') diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h new file mode 100644 index 0000000000..d8a1374a6d --- /dev/null +++ b/Source/cmComputeLinkInformation.h @@ -0,0 +1,165 @@ +/*========================================================================= + + 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 cmComputeLinkInformation_h +#define cmComputeLinkInformation_h + +#include "cmStandardIncludes.h" + +#include + +class cmGlobalGenerator; +class cmLocalGenerator; +class cmMakefile; +class cmTarget; + +/** \class cmComputeLinkInformation + * \brief Compute link information for a target in one configuration. + */ +class cmComputeLinkInformation +{ +public: + cmComputeLinkInformation(cmTarget* target, const char* config); + bool Compute(); + + struct Item + { + Item(): Value(), IsPath(true) {} + Item(Item const& item): Value(item.Value), IsPath(item.IsPath) {} + Item(std::string const& v, bool p): Value(v), IsPath(p) {} + std::string Value; + bool IsPath; + }; + typedef std::vector ItemVector; + ItemVector const& GetItems(); + std::vector const& GetDirectories(); + std::vector const& GetDepends(); + std::vector const& GetFrameworkPaths(); + const char* GetLinkLanguage() const { return this->LinkLanguage; } + std::vector const& GetRuntimeSearchPath(); +private: + void AddItem(std::string const& item); + + // Output information. + ItemVector Items; + std::vector Directories; + std::vector Depends; + std::vector FrameworkPaths; + std::vector RuntimeSearchPath; + + // Context information. + cmTarget* Target; + cmMakefile* Makefile; + cmLocalGenerator* LocalGenerator; + cmGlobalGenerator* GlobalGenerator; + + // Configuration information. + const char* Config; + const char* LinkLanguage; + + // System info. + bool UseImportLibrary; + const char* LoaderFlag; + std::string LibLinkFlag; + std::string LibLinkSuffix; + + // Link type adjustment. + void ComputeLinkTypeInfo(); + enum LinkType { LinkUnknown, LinkStatic, LinkShared }; + LinkType StartLinkType; + LinkType CurrentLinkType; + std::string StaticLinkTypeFlag; + std::string SharedLinkTypeFlag; + bool LinkTypeEnabled; + void SetCurrentLinkType(LinkType lt); + + // Link item parsing. + void ComputeItemParserInfo(); + std::vector StaticLinkExtensions; + std::vector SharedLinkExtensions; + std::vector LinkExtensions; + std::set LinkPrefixes; + cmsys::RegularExpression RemoveLibraryExtension; + cmsys::RegularExpression ExtractStaticLibraryName; + cmsys::RegularExpression ExtractSharedLibraryName; + cmsys::RegularExpression ExtractAnyLibraryName; + void AddLinkPrefix(const char* p); + void AddLinkExtension(const char* e, LinkType type); + std::string CreateExtensionRegex(std::vector const& exts); + std::string NoCaseExpression(const char* str); + + // Handling of link items that are not targets or full file paths. + void AddUserItem(std::string const& item); + void AddDirectoryItem(std::string const& item); + void AddFrameworkItem(std::string const& item); + void DropDirectoryItem(std::string const& item); + + // Framework info. + void ComputeFrameworkInfo(); + void AddFrameworkPath(std::string const& p); + std::set FrameworkPathsEmmitted; + cmsys::RegularExpression SplitFramework; + + // Linker search path computation. + void ComputeLinkerSearchDirectories(); + void AddLinkerSearchDirectories(std::vector const& dirs); + std::set DirectoriesEmmitted; + + // Runtime path computation. + struct LibraryRuntimeEntry + { + // The file name of the library. + std::string FileName; + + // The soname of the shared library if it is known. + std::string SOName; + + // The directory in which the library is supposed to be found. + std::string Directory; + + // The index assigned to the directory. + int DirectoryIndex; + }; + bool RuntimeSearchPathComputed; + std::vector LibraryRuntimeInfo; + std::set LibraryRuntimeInfoEmmitted; + std::vector RuntimeDirectories; + std::map RuntimeDirectoryIndex; + std::vector RuntimeDirectoryVisited; + void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target); + void AddLibraryRuntimeInfo(std::string const& fullPath, + const char* soname = 0); + void CollectRuntimeDirectories(); + int AddRuntimeDirectory(std::string const& dir); + void FindConflictingLibraries(); + void FindDirectoriesForLib(unsigned int lri); + void OrderRuntimeSearchPath(); + void VisitRuntimeDirectory(unsigned int i, bool top); + void DiagnoseCycle(); + bool CycleDiagnosed; + + // Adjacency-list representation of runtime path ordering graph. + // This maps from directory to those that must come *before* it. + // Each entry that must come before is a pair. The first element is + // the index of the directory that must come first. The second + // element is the index of the runtime library that added the + // constraint. + typedef std::pair RuntimeConflictPair; + struct RuntimeConflictList: public std::vector {}; + std::vector RuntimeConflictGraph; +}; + +#endif -- cgit v1.2.1