BUG: Move decision to switch library paths found in implicit link directories to use -l options from cmFindLibraryCommand to cmComputeLinkInformation. Existing projects may depend on find_library returning a full path. This slightly weakens cmComputeLinkInformation but is necessary for compatibility.
This commit is contained in:
parent
73a5f0846f
commit
3a05425309
|
@ -31,3 +31,12 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
|
|||
"mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
|
||||
)
|
||||
ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# Initialize C link type selection flags. These flags are used when
|
||||
# building a shared library, shared module, or executable that links
|
||||
# to other libraries to select whether to use the static or shared
|
||||
# versions of the libraries.
|
||||
FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
|
||||
SET(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Wl,-Bstatic")
|
||||
SET(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic")
|
||||
ENDFOREACH(type)
|
||||
|
|
|
@ -60,3 +60,13 @@ IF(NOT CMAKE_COMPILER_IS_GNUCXX)
|
|||
"mv `basename \"<SOURCE>\" | sed 's/\\.[^./]*$$//'`.s <ASSEMBLY_SOURCE>"
|
||||
)
|
||||
ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# Initialize C link type selection flags. These flags are used when
|
||||
# building a shared library, shared module, or executable that links
|
||||
# to other libraries to select whether to use the static or shared
|
||||
# versions of the libraries.
|
||||
FOREACH(type SHARED_LIBRARY SHARED_MODULE EXE)
|
||||
SET(CMAKE_${type}_LINK_STATIC_C_FLAGS "-Wl,-Bstatic")
|
||||
SET(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic")
|
||||
ENDFOREACH(type)
|
||||
|
||||
|
|
|
@ -234,6 +234,21 @@ cmComputeLinkInformation
|
|||
// Setup framework support.
|
||||
this->ComputeFrameworkInfo();
|
||||
|
||||
// Get the implicit link directories for this platform.
|
||||
if(const char* implicitLinks =
|
||||
(this->Makefile->GetDefinition
|
||||
("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
|
||||
{
|
||||
std::vector<std::string> implicitLinkVec;
|
||||
cmSystemTools::ExpandListArgument(implicitLinks, implicitLinkVec);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
i = implicitLinkVec.begin();
|
||||
i != implicitLinkVec.end(); ++i)
|
||||
{
|
||||
this->ImplicitLinkDirs.insert(*i);
|
||||
}
|
||||
}
|
||||
|
||||
// Initial state.
|
||||
this->RuntimeSearchPathComputed = false;
|
||||
this->HaveUserFlagItem = false;
|
||||
|
@ -689,6 +704,12 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item,
|
|||
//----------------------------------------------------------------------------
|
||||
void cmComputeLinkInformation::AddFullItem(std::string const& item)
|
||||
{
|
||||
// Check for the implicit link directory special case.
|
||||
if(this->CheckImplicitDirItem(item))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// This is called to handle a link item that is a full path.
|
||||
// If the target is not a static library make sure the link type is
|
||||
// shared. This is because dynamic-mode linking can handle both
|
||||
|
@ -727,6 +748,37 @@ void cmComputeLinkInformation::AddFullItem(std::string const& item)
|
|||
this->Items.push_back(Item(item, true));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
|
||||
{
|
||||
// We only switch to a pathless item if the link type may be
|
||||
// enforced. Fortunately only platforms that support link types
|
||||
// seem to have magic per-architecture implicit link directories.
|
||||
if(!this->LinkTypeEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if this item is in an implicit link directory.
|
||||
std::string dir = cmSystemTools::GetFilenamePath(item);
|
||||
if(this->ImplicitLinkDirs.find(dir) == this->ImplicitLinkDirs.end())
|
||||
{
|
||||
// Only libraries in implicit link directories are converted to
|
||||
// pathless items.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Many system linkers support multiple architectures by
|
||||
// automatically selecting the implicit linker search path for the
|
||||
// current architecture. If the library appears in an implicit link
|
||||
// directory then just report the file name without the directory
|
||||
// portion. This will allow the system linker to locate the proper
|
||||
// library for the architecture at link time.
|
||||
std::string file = cmSystemTools::GetFilenameName(item);
|
||||
this->AddUserItem(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmComputeLinkInformation::AddUserItem(std::string const& item)
|
||||
{
|
||||
|
@ -907,20 +959,8 @@ void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
|
|||
void cmComputeLinkInformation::ComputeLinkerSearchDirectories()
|
||||
{
|
||||
// Some search paths should never be emitted.
|
||||
this->DirectoriesEmmitted = this->ImplicitLinkDirs;
|
||||
this->DirectoriesEmmitted.insert("");
|
||||
if(const char* implicitLinks =
|
||||
(this->Makefile->GetDefinition
|
||||
("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
|
||||
{
|
||||
std::vector<std::string> implicitLinkVec;
|
||||
cmSystemTools::ExpandListArgument(implicitLinks, implicitLinkVec);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
i = implicitLinkVec.begin();
|
||||
i != implicitLinkVec.end(); ++i)
|
||||
{
|
||||
this->DirectoriesEmmitted.insert(*i);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we need to include the runtime search path at link time.
|
||||
std::string var = "CMAKE_SHARED_LIBRARY_LINK_";
|
||||
|
|
|
@ -117,6 +117,7 @@ private:
|
|||
// Handling of link items that are not targets or full file paths.
|
||||
void AddTargetItem(std::string const& item, cmTarget* target);
|
||||
void AddFullItem(std::string const& item);
|
||||
bool CheckImplicitDirItem(std::string const& item);
|
||||
void AddUserItem(std::string const& item);
|
||||
void AddDirectoryItem(std::string const& item);
|
||||
void AddFrameworkItem(std::string const& item);
|
||||
|
@ -132,6 +133,7 @@ private:
|
|||
void ComputeLinkerSearchDirectories();
|
||||
void AddLinkerSearchDirectories(std::vector<std::string> const& dirs);
|
||||
std::set<cmStdString> DirectoriesEmmitted;
|
||||
std::set<cmStdString> ImplicitLinkDirs;
|
||||
|
||||
// Linker search path compatibility mode.
|
||||
std::vector<std::string> OldLinkDirs;
|
||||
|
|
|
@ -52,17 +52,6 @@ cmFindLibraryCommand::cmFindLibraryCommand()
|
|||
"When a full path to a framework is used as a library, "
|
||||
"CMake will use a -framework A, and a -F<fullPath> to "
|
||||
"link the framework to the target. ";
|
||||
this->GenericDocumentation +=
|
||||
"\n"
|
||||
"Some platforms define implicit library directories such as "
|
||||
"/lib and /usr/lib that are automatically searched by the linker. "
|
||||
"If this command finds a library in one of these directories "
|
||||
"it will report only the name of the library file and not the path. "
|
||||
"When the name is used to link the library CMake will generate a "
|
||||
"link line that asks the linker to search for it. This allows "
|
||||
"the system linker to automatically adjust the implicit directory "
|
||||
"set based on the current architecture."
|
||||
;
|
||||
}
|
||||
|
||||
// cmFindLibraryCommand
|
||||
|
@ -86,26 +75,6 @@ bool cmFindLibraryCommand
|
|||
this->VariableDocumentation.c_str(),
|
||||
cmCacheManager::FILEPATH);
|
||||
}
|
||||
|
||||
// If the existing value was loaded from a cache written by CMake
|
||||
// 2.4 or below then force the implicit link directory fix on the
|
||||
// value.
|
||||
if(this->Makefile->NeedCacheCompatibility(2, 4))
|
||||
{
|
||||
if(const char* v =
|
||||
this->Makefile->GetDefinition(this->VariableName.c_str()))
|
||||
{
|
||||
std::string nv = this->FixForImplicitLocations(v);
|
||||
if(nv != v)
|
||||
{
|
||||
this->Makefile
|
||||
->AddCacheDefinition(this->VariableName.c_str(),
|
||||
nv.c_str(),
|
||||
this->VariableDocumentation.c_str(),
|
||||
cmCacheManager::FILEPATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -134,7 +103,6 @@ bool cmFindLibraryCommand
|
|||
library = this->FindLibrary(i->c_str());
|
||||
if(library != "")
|
||||
{
|
||||
library = this->FixForImplicitLocations(library);
|
||||
this->Makefile->AddCacheDefinition(this->VariableName.c_str(),
|
||||
library.c_str(),
|
||||
this->VariableDocumentation.c_str(),
|
||||
|
@ -320,43 +288,3 @@ std::string cmFindLibraryCommand::FindLibrary(const char* name)
|
|||
// Couldn't find the library.
|
||||
return "";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmFindLibraryCommand::FixForImplicitLocations(std::string const& lib)
|
||||
{
|
||||
// Get implicit link directories for the platform.
|
||||
const char* implicitLinks =
|
||||
(this->Makefile->GetDefinition
|
||||
("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES"));
|
||||
if(!implicitLinks)
|
||||
{
|
||||
// There are no implicit link directories. No fix is needed.
|
||||
return lib;
|
||||
}
|
||||
std::vector<std::string> implicitLinkVec;
|
||||
cmSystemTools::ExpandListArgument(implicitLinks, implicitLinkVec);
|
||||
|
||||
// Get the path containing the library.
|
||||
std::string libDir = cmSystemTools::GetFilenamePath(lib);
|
||||
|
||||
// Many system linkers support multiple architectures by
|
||||
// automatically selecting the implicit linker search path for the
|
||||
// current architecture. If the library appears in an implicit link
|
||||
// directory then just report the file name without the directory
|
||||
// portion. This will allow the system linker to locate the proper
|
||||
// library for the architecture at link time.
|
||||
for(std::vector<std::string>::const_iterator i = implicitLinkVec.begin();
|
||||
i != implicitLinkVec.end(); ++i)
|
||||
{
|
||||
if(*i == libDir)
|
||||
{
|
||||
// The library appears in an implicit link directory. Report
|
||||
// only the file name.
|
||||
return cmSystemTools::GetFilenameName(lib);
|
||||
}
|
||||
}
|
||||
|
||||
// No implicit link directory matched. No fix is needed.
|
||||
return lib;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,6 @@ protected:
|
|||
void AddArchitecturePaths(const char* suffix);
|
||||
void AddLib64Paths();
|
||||
std::string FindLibrary(const char* name);
|
||||
std::string FixForImplicitLocations(std::string const& lib);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue