Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cmake: target_link_libraries use static library not shared

Tags:

Is it possible to tell cmake to link against a static library instead of shared?

At the top of my CMakeLists.txt I have the following configured:

set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 

Later, I add a binary, and tell it to link against tcmalloc in release mode:

target_link_libraries(${BIN_NAME} optimized tcmalloc_minimal) 

The resulting makefile links aginst the shared version of tcmalloc:

$ make VERBOSE=1 | grep tcmalloc /usr/bin/c++ ... -Wl,-Bdynamic ltcmalloc_minimal  

Further proof:

$ ldd app      ...     libtcmalloc_minimal.so.4 => /usr/local/lib/libtcmalloc_minimal.so.4 (0x00007eff89733000)     ... 

Both static and shared versions of tcmalloc exist:

$ ls -1 /usr/local/lib/libtcmalloc_minimal* /usr/local/lib/libtcmalloc_minimal.a /usr/local/lib/libtcmalloc_minimal_debug.a /usr/local/lib/libtcmalloc_minimal_debug.la /usr/local/lib/libtcmalloc_minimal_debug.so /usr/local/lib/libtcmalloc_minimal_debug.so.4 /usr/local/lib/libtcmalloc_minimal_debug.so.4.2.6 /usr/local/lib/libtcmalloc_minimal.la /usr/local/lib/libtcmalloc_minimal.so /usr/local/lib/libtcmalloc_minimal.so.4 /usr/local/lib/libtcmalloc_minimal.so.4.2.6 

Question:

How can I configure cmake to link against the static version of tcmalloc?

like image 271
Steve Lorimer Avatar asked Apr 20 '16 20:04

Steve Lorimer


People also ask

What is static and shared library?

Static libraries take longer to execute, because loading into the memory happens every time while executing. While Shared libraries are faster because shared library code is already in the memory.


1 Answers

You can create a helper function which sets CMAKE_FIND_LIBRARY_SUFFIXES at function scope (so therefore doesn't affect the parent scope) which searches for the library in question and sets an output variable with the result

function(find_static_library LIB_NAME OUT)      if (WIN32 OR MSVC)         set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")     elseif (UNIX)         set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")     endif()            find_library(         FOUND_${LIB_NAME}_STATIC         ${LIB_NAME}         )      if (FOUND_${LIB_NAME}_STATIC)         get_filename_component(ABS_FILE ${FOUND_${LIB_NAME}_STATIC} ABSOLUTE)     else()         message(SEND_ERROR "Unable to find library ${LIB_NAME}")     endif()      set(${OUT} ${ABS_FILE} PARENT_SCOPE)  endfunction() 

You can then call this function from somewhere in your CMakeLists.txt to populate a variable with the location of the library.

Failure to find it results in a hard failure

find_static_library(tcmalloc_minimal TCMALLOC) 

You can then use this variable in your call to target_link_libraries and be sure you're linking against the static version

target_link_libraries(${BIN_NAME} optimized ${TCMALLOC}) 

Here you can see the result:

$ make VERBOSE=1 | grep tcmalloc 
/usr/bin/c++ ... /usr/local/lib/libtcmalloc_minimal.a ... 
like image 139
Steve Lorimer Avatar answered Sep 29 '22 06:09

Steve Lorimer