mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-19 19:43:23 +08:00
find_library: Skip 'lib => lib<arch>' searches if one symlinks the other
The `FIND_LIBRARY_USE_LIB<arch>_PATHS` global properties ask `find_library` to look in `lib<arch>` directories automatically before corresponding `lib` directories. However, if `lib<arch>` is just a symlink to `lib` (or vice-versa) then we should skip adding the `lib<arch>` path. Such symlinks typically only exist to satisfy software that expects the `lib<arch>` path to be available. Fixes: #16687
This commit is contained in:
@@ -72,6 +72,18 @@ void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool cmLibDirsLinked(std::string const& l, std::string const& r)
|
||||||
|
{
|
||||||
|
// Compare the real paths of the two directories.
|
||||||
|
// Since our caller only changed the trailing component of each
|
||||||
|
// directory, the real paths can be the same only if at least one of
|
||||||
|
// the trailing components is a symlink. Use this as an optimization
|
||||||
|
// to avoid excessive realpath calls.
|
||||||
|
return (cmSystemTools::FileIsSymlink(l) ||
|
||||||
|
cmSystemTools::FileIsSymlink(r)) &&
|
||||||
|
cmSystemTools::GetRealPath(l) == cmSystemTools::GetRealPath(r);
|
||||||
|
}
|
||||||
|
|
||||||
void cmFindLibraryCommand::AddArchitecturePath(
|
void cmFindLibraryCommand::AddArchitecturePath(
|
||||||
std::string const& dir, std::string::size_type start_pos, const char* suffix,
|
std::string const& dir, std::string::size_type start_pos, const char* suffix,
|
||||||
bool fresh)
|
bool fresh)
|
||||||
@@ -87,6 +99,11 @@ void cmFindLibraryCommand::AddArchitecturePath(
|
|||||||
std::string libX = lib + suffix;
|
std::string libX = lib + suffix;
|
||||||
bool use_libX = cmSystemTools::FileIsDirectory(libX);
|
bool use_libX = cmSystemTools::FileIsDirectory(libX);
|
||||||
|
|
||||||
|
// Avoid copies of the same directory due to symlinks.
|
||||||
|
if (use_libX && use_lib && cmLibDirsLinked(libX, lib)) {
|
||||||
|
use_libX = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_libX) {
|
if (use_libX) {
|
||||||
libX += dir.substr(pos + 3);
|
libX += dir.substr(pos + 3);
|
||||||
std::string::size_type libX_pos = pos + 3 + strlen(suffix) + 1;
|
std::string::size_type libX_pos = pos + 3 + strlen(suffix) + 1;
|
||||||
@@ -106,6 +123,11 @@ void cmFindLibraryCommand::AddArchitecturePath(
|
|||||||
std::string dirX = dir + suffix;
|
std::string dirX = dir + suffix;
|
||||||
bool use_dirX = cmSystemTools::FileIsDirectory(dirX);
|
bool use_dirX = cmSystemTools::FileIsDirectory(dirX);
|
||||||
|
|
||||||
|
// Avoid copies of the same directory due to symlinks.
|
||||||
|
if (use_dirX && use_dir && cmLibDirsLinked(dirX, dir)) {
|
||||||
|
use_dirX = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_dirX) {
|
if (use_dirX) {
|
||||||
dirX += "/";
|
dirX += "/";
|
||||||
this->SearchPaths.push_back(dirX);
|
this->SearchPaths.push_back(dirX);
|
||||||
|
2
Tests/RunCMake/find_library/LibArchLink-stderr.txt
Normal file
2
Tests/RunCMake/find_library/LibArchLink-stderr.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
TOP_LIBRARY='[^']*/Tests/RunCMake/find_library/LibArchLink-build/lib/libtop.a'
|
||||||
|
SUB_LIBRARY='[^']*/Tests/RunCMake/find_library/LibArchLink-build/lib/sub/libsub.a'
|
24
Tests/RunCMake/find_library/LibArchLink.cmake
Normal file
24
Tests/RunCMake/find_library/LibArchLink.cmake
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
set(CMAKE_SIZEOF_VOID_P 4)
|
||||||
|
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS ON)
|
||||||
|
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
|
||||||
|
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink lib ${CMAKE_CURRENT_BINARY_DIR}/lib32)
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/libtop.a" "top")
|
||||||
|
find_library(TOP_LIBRARY
|
||||||
|
NAMES top
|
||||||
|
PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
message("TOP_LIBRARY='${TOP_LIBRARY}'")
|
||||||
|
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/sub)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink . ${CMAKE_CURRENT_BINARY_DIR}/lib/sub/32)
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib/sub/libsub.a" "sub")
|
||||||
|
find_library(SUB_LIBRARY
|
||||||
|
NAMES sub
|
||||||
|
PATHS ${CMAKE_CURRENT_BINARY_DIR}/lib/sub
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
message("SUB_LIBRARY='${SUB_LIBRARY}'")
|
@@ -1,6 +1,9 @@
|
|||||||
include(RunCMake)
|
include(RunCMake)
|
||||||
|
|
||||||
run_cmake(Created)
|
run_cmake(Created)
|
||||||
|
if(CMAKE_HOST_UNIX)
|
||||||
|
run_cmake(LibArchLink)
|
||||||
|
endif()
|
||||||
if(WIN32 OR CYGWIN)
|
if(WIN32 OR CYGWIN)
|
||||||
run_cmake(PrefixInPATH)
|
run_cmake(PrefixInPATH)
|
||||||
endif()
|
endif()
|
||||||
|
Reference in New Issue
Block a user