DimanNe
DimanNe

Reputation: 1941

CMake's find_library cannot find library without version, extension and lib prefix

I am trying to link against a system library: /usr/lib/x86_64-linux-gnu/libtcmalloc.so.4, when I have this CMakeLists.txt

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(all)

find_library(TCMALLOC_LIB NAMES tcmalloc)
if(TCMALLOC_LIB)
   message("Found TCMALLOC_LIB: ${TCMALLOC_LIB}")
else()
   message(FATAL_ERROR "TCMALLOC_LIB library not found")
endif()

(also tried find_library(TCMALLOC_LIB tcmalloc))

I get

CMake Error at CMakeLists.txt:13 (message):
  TCMALLOC_LIB library not found

While, if I have

find_library(TCMALLOC_LIB NAMES libtcmalloc.so.4)

everything is fine: Found TCMALLOC_LIB: /usr/lib/x86_64-linux-gnu/libtcmalloc.so.4

Am I doing something wrong? Why do I need to specify filename precisely? How can I debug find_library?

Upvotes: 3

Views: 2621

Answers (1)

DimanNe
DimanNe

Reputation: 1941

Update - Real cause

As @Tsyvarev mentioned in the comment, it turns out that cmake could not find the library because I installed it only "partially", the -dev version (libgoogle-perftools-dev) should have been installed.


TL;DR

Well, it turns out that tcmalloc is not a regular/conventional library, namely, it does not have libtcmalloc.so symlink pointing to .so.4, that is why cmake cannot find it.

How can I debug find_library?

I found a way of debugging find_library via strace:

$ rm -rf ./* && strace cmake ../scripts/ 2>&1 | grep tcmalloc
access("/usr/local/nvidia/bin/libtcmalloc.so", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/local/cuda/bin/libtcmalloc.so", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/local/sbin/libtcmalloc.so", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/local/bin/libtcmalloc.so", R_OK) = -1 ENOENT (No such file or directory)
...
<many lines skipped>
...

From this strace output we see that cmake, indeed tries to prepend lib and append .so, but it does not try to prepend any version.

Now, if we look at another "normal" library:

# locate protobuf | grep "\.so"
/usr/lib/x86_64-linux-gnu/libprotobuf.so
/usr/lib/x86_64-linux-gnu/libprotobuf.so.17
/usr/lib/x86_64-linux-gnu/libprotobuf.so.17.0.0

we will see that it DOES install .so symlink, while tcmalloc does not:

# locate tcmalloc | grep "\.so"
/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4
/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4.3.0

Upvotes: 4

Related Questions