find_file() not resolving relative paths with symlinks correctly
Summary
find_file()
resolves relative path components before it resolves symlinks, which is inconsistent with normal Linux path resolution.
See the following CMake 3.18.4 output which searches using find_file() with both direct and symlink path; then cat just to prove normal Linux shell works.
Steps to reproduce
- Create the following
CMakeLists.txt
file:
cmake_minimum_required(VERSION 3.13)
project(FindPathSymlink LANGUAGES)
set(CMAKE_FIND_DEBUG_MODE TRUE)
find_file(var_direct file.so PATHS "${CMAKE_SOURCE_DIR}/usr/local/lib64" NO_DEFAULT_PATH)
find_file(var_symlink file.so PATHS "${CMAKE_SOURCE_DIR}/usr/7.3.0/../lib64/file.so" NO_DEFAULT_PATH)
execute_process(COMMAND cat ${CMAKE_SOURCE_DIR}/usr/7.3.0/../lib64/file.so
OUTPUT_VARIABLE var_cat)
message(STATUS "find_file(usr/local/lib64): ${var_direct}")
message(STATUS "find_file(usr/7.3.0/../lib64): ${var_symlink}")
message(STATUS "cat 'usr/7.3.0/../lib64/file.so': ${var_cat}")
- Create the following directory / file layout:
mkdir -p usr/local/lib64
echo "Found you!" > usr/local/lib64/file.so
mkdir -p usr/local/7.3.0
cd usr/
ln -s local/7.3.0 7.3.0
You should end up with the following layout:
$ find . -ls
3571714 4 drwxr-xr-x 3 couchbase couchbase 4096 Oct 12 09:11 .
3571715 4 drwxr-xr-x 3 couchbase couchbase 4096 Oct 12 09:03 ./usr
3553162 0 lrwxrwxrwx 1 couchbase couchbase 11 Oct 12 09:03 ./usr/7.3.0 -> local/7.3.0
3571716 4 drwxr-xr-x 4 couchbase couchbase 4096 Oct 12 09:02 ./usr/local
3571717 4 drwxr-xr-x 2 couchbase couchbase 4096 Oct 12 09:01 ./usr/local/lib64
3553107 4 -rw-r--r-- 1 couchbase couchbase 11 Oct 12 09:09 ./usr/local/lib64/file.so
3571718 4 drwxr-xr-x 2 couchbase couchbase 4096 Oct 12 09:02 ./usr/local/7.3.0
3553900 4 -rw-r--r-- 1 couchbase couchbase 589 Oct 12 09:09 ./CMakeLists.txt
- Running this gives:
CMake Debug Log at CMakeLists.txt:5 (find_file):
find_file called with the following settings:
VAR: var_direct
NAMES: "file.so"
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:
The item was found at
/home/couchbase/find_file_symlinks2/usr/local/lib64/file.so
CMake Debug Log at CMakeLists.txt:6 (find_file):
find_file called with the following settings:
VAR: var_symlink
NAMES: "file.so"
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:
/home/couchbase/find_file_symlinks2/usr/lib64/file.so/file.so
The item was not found.
-- find_file(usr/local/lib64): /home/couchbase/find_file_symlinks2/usr/local/lib64/file.so
-- find_file(usr/7.3.0/../lib64): var_symlink-NOTFOUND
-- cat 'usr/7.3.0/../lib64/file.so': Found you!
-- Configuring done
-- Generating done
-- Build files have been written to: /home/couchbase/find_file_symlinks2/build
Note the differences in find_file()
output vs cat
for the relative path containing symlinks.
Initially reported via forum: https://discourse.cmake.org/t/find-file-not-resolving-relative-paths-correctly/1984/4