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:
Brad King 2008-01-31 07:50:40 -05:00
parent 73a5f0846f
commit 3a05425309
6 changed files with 74 additions and 86 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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_";

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
};