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 run ls 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.

Tags:

Cmake