Debug CMake find_library
I know this isn't a complete answer, but I had the same problem and found that it was necessary to add debug logging to find_library in the CMake source code. I submitted a pull request (work in progress) to add this to mainstream CMake.
I eliminated some possible sources of errors by logging an error message with some relevant details if find_library
fails, like this:
set(libssl_names
ssl${_OPENSSL_MSVC_ARCH_SUFFIX}${_OPENSSL_MSVC_RT_MODE}
ssl${_OPENSSL_MSVC_RT_MODE}
ssl
ssleay32${_OPENSSL_MSVC_RT_MODE}
ssleay32
)
find_library(SSL_EAY_DEBUG
NAMES ${libssl_names}
NAMES_PER_DIR
PATHS ${OPENSSL_ROOT_DIR}
PATH_SUFFIXES ${_OPENSSL_PATH_SUFFIXES}
NO_DEFAULT_PATH
)
if(NOT SSL_EAY_DEBUG)
message(FATAL_ERROR "OPENSSL_ROOT_DIR is set to '${OPENSSL_ROOT_DIR}', but did not find any file matching ${OPENSSL_ROOT_DIR}/{${_OPENSSL_PATH_SUFFIXES}}/${CMAKE_FIND_LIBRARY_PREFIXES}{${libssl_names}}${CMAKE_FIND_LIBRARY_SUFFIXES}")
endif()
Which outputs something like:
CMake Error at CMakeLists.txt:526 (message):
OPENSSL_ROOT_DIR is set to '../../Install/openssl/', but did not find any
file matching
../../Install/openssl//{lib/VC/static;VC/static;lib}/lib{ssl64MT;sslMT;ssl;ssleay32MT;ssleay32}.a
Apart from semicolons (instead of commas) in the {braced} portions of the above pattern, and regexes if multiple CMAKE_FIND_LIBRARY_SUFFIXES are configured (e.g. .lib .a
on Windows), this is the correct form for shell expansion to a list of paths, which you can pass to ls
to check for their existence:
$ ls ../../Install/openssl//{lib/VC/static,VC/static,lib}/lib{ssl64MT,sslMT,ssl,ssleay32MT,ssleay32}.a
ls: ../../Install/openssl//VC/static/libssl.a: No such file or directory
ls: ../../Install/openssl//VC/static/libssl64MT.a: No such file or directory
ls: ../../Install/openssl//VC/static/libsslMT.a: No such file or directory
ls: ../../Install/openssl//VC/static/libssleay32.a: No such file or directory
ls: ../../Install/openssl//VC/static/libssleay32MT.a: No such file or directory
ls: ../../Install/openssl//lib/VC/static/libssl.a: No such file or directory
ls: ../../Install/openssl//lib/VC/static/libssl64MT.a: No such file or directory
ls: ../../Install/openssl//lib/VC/static/libsslMT.a: No such file or directory
ls: ../../Install/openssl//lib/VC/static/libssleay32.a: No such file or directory
ls: ../../Install/openssl//lib/VC/static/libssleay32MT.a: No such file or directory
ls: ../../Install/openssl//lib/libssl64MT.a: No such file or directory
ls: ../../Install/openssl//lib/libsslMT.a: No such file or directory
ls: ../../Install/openssl//lib/libssleay32.a: No such file or directory
ls: ../../Install/openssl//lib/libssleay32MT.a: No such file or directory
../../Install/openssl//lib/libssl.a
It's not obvious (at least to me) that:
relative paths (like
../../Install
above) are actually relative to the original source directory (not the current project build directory, which CMake calls CMAKE_BINARY_DIR. (So you should runls
from there, not your build directory).FIND_LIBRARY_USE_LIB64_PATHS, which is often ON by default, results in your original paths being replaced by mangled ones (lib -> lib64) (not just supplemented by additional search paths, but completely replaced).
Other, even less well-known properties such as FIND_LIBRARY_USE_LIB32_PATHS result in similar mangling (lib -> lib32).
This mangling can be disabled with
set(CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX "")
.
With CMake 3.17 this got added:
The “CMAKE_FIND_DEBUG_MODE” variable was introduced to print extra find call information during the cmake run to standard error. Output is designed for human consumption and not for parsing.
So you pass either -DCMAKE_FIND_DEBUG_MODE=ON
or --debug-find
to your CMake command.
Here is an example output when searching for libFOO:
find_library considered the following locations:
/usr/local/lib64/(lib)FOO(\.so|\.a)
/usr/local/lib/(lib)FOO(\.so|\.a)
/usr/local/lib64/(lib)FOO(\.so|\.a)
/usr/local/lib/(lib)FOO(\.so|\.a)
/usr/local/lib64/(lib)FOO(\.so|\.a)
/usr/local/(lib)FOO(\.so|\.a)
/usr/lib64/(lib)FOO(\.so|\.a)
/usr/lib/(lib)FOO(\.so|\.a)
/usr/lib64/(lib)FOO(\.so|\.a)
/usr/lib/(lib)FOO(\.so|\.a)
/usr/lib64/(lib)FOO(\.so|\.a)
/usr/(lib)FOO(\.so|\.a)
/lib64/(lib)FOO(\.so|\.a)
/lib/(lib)FOO(\.so|\.a)
/opt/(lib)FOO(\.so|\.a)
The item was not found.