Hi,
I’m using find_file
to try to locate where builtin compiler library (in this case tsan.so) is located. I’m doing this by first parsing the output of try_compile(... -print-search-dirs)
to extract the list of paths, and then calling find_file
with that list to locate the given library:
function(try_search_sanitizer_library variable _name)
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-search-dirs
OUTPUT_VARIABLE cc_search_dirs)
# Extract the line listing the library paths
string(REGEX MATCH "libraries: =(.*)\n" _ ${cc_search_dirs})
# CMAKE expects lists to be semicolon-separated instead of colon.
string(REPLACE ":" ";" cc_library_dirs ${CMAKE_MATCH_1})
message(STATUS "cc_library_dirs: ${cc_library_dirs}")
find_file(${variable} ${_name} PATHS ${cc_library_dirs} NO_DEFAULT_PATH)
endfunction()
This is called as try_search_sanitizer_library(TSan_path libtsan.so.0)
.
However, it’s failing to find the correct libtsan, picking up another one on my machine.
If I enable CMAKE_FIND_DEBUG_MODE
, and simplify to hardcode the “correct” path libtsan is in, find_file()
seems to be getting the relative path resolution wrong (!):
function(try_search_sanitizer_library variable _name)
# TEST: Just hardcode the correct path:
set(CMAKE_FIND_DEBUG_MODE TRUE)
find_file(${variable} ${_name} PATHS "/usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../lib64" NO_DEFAULT_PATH)
set(CMAKE_FIND_DEBUG_MODE FALSE)
endfunction()
This gives the following output:
CMake Debug Log at tlm/cmake/Modules/CouchbaseSanitizers.cmake:14 (find_file):
find_file called with the following settings:
VAR: TSan_path
NAMES: "libtsan.so.0"
Documentation: Path to a file.
Framework
Only Search Frameworks: 0
Search Frameworks Last: 0
Search Frameworks First: 0
AppBundle
Only Search AppBundle: 0
Search AppBundle Last: 0
Search AppBundle First: 0
NO_DEFAULT_PATH Enabled
find_file considered the following locations:
/usr/lib64/libtsan.so.0
The item was not found.
Note that CMake appears to have resolved that relative path to /usr/lib64
. However, if I actually check with realpath
I see:
$ realpath /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../lib64
/usr/local/lib64
And indeed if I list that it exists:
$ ls -l /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../lib64/libtsan.so
lrwxrwxrwx 1 root root 16 Mar 9 2018 /usr/bin/../lib/gcc/x86_64-linux-gnu/7.3.0/../../../../lib64/libtsan.so -> libtsan.so.0.0.0
So - does find_file()
not handle relative paths correctly?