[CMake] link_libraries

Rolf Eike Beer eike at sf-mail.de
Sat Apr 21 02:54:59 EDT 2018


Ranjeet Kuruvilla wrote:
> I have read that link_libraries command has gotten deprecated for version
> 3.10 and instead one needs to use link_librariestarget_link_libraries has
> one major disadvantage, in that it is required to put that statement after
> add_executable. I have here a CMake file for many different projects with
> the same folder structure, that scans a subfolder for files ending with
> .cmake. Those .cmake files can contain extra includes, definitions and
> libraries. With link_libraries I can put all statements inside one .cmake
> file. With target_link_libraries statement however I need 2 .cmake files,
> one before add_executable and one after for all the libraries. So I ask you
> to keep link_libraries alive!

tl;dr: no, surely not, it just adds libraries to probably unrelated targets.

> cmake_minimum_required( VERSION 3.10.0 )
> 
> project( ${PROJ_NAME} ${CXX} )enable_language(CXX)
> set( CMAKE_VERBOSE_MAKEFILE ON)
> 
> set( OPTIMIZING_FLAGS -O2)
> 
> set( CUSTOMBUILD "customBuild" )
> ...include_directories( BEFORE "/usr/local/include/x86_64-linux-gnu")

That is a compiler specific include, that should never be needed. The compiler 
adds that anyway, and if you use a different compiler this will probably badly 
screw things up.

> link_directories( BEFORE "/usr/lib")

That is a default link directory and is not needed.

> link_directories( BEFORE
> "/usr/lib/boost" ... 
> IF(EXISTS ${ CUSTOMBUILD})
>   message("Found custom cmake to build")    
>   file( GLOB_RECURSE CMAKE_ITEMS LIST_DIRECTORIES false
>     ${CONST_BASE_PATH_CUSTOMBUILD}*${CMAKE_SUFFIX})
>   foreach(CMAKE_ITEM ${CMAKE_ITEMS})
>     message("Add cmake file " ${CMAKE_ITEM})       
>     include(${CMAKE_ITEM})
>   endforeach(CMAKE_ITEM)
> endif()...

If you like it that way, fine…

> link_libraries(-lqpidclient -lqpidmessaging)
> link_libraries( -ljsoncpp)
> link_libraries( -lpistache)
> link_libraries( -lboost_system -lboost_thread -lboost_regex
> -lboost_filesystem -lboost_random -lboost_date_time -lboost_log
> -lboost_program_options -lboost_signals)link_libraries( -lpulse-simple
> -lpulse)
> link_libraries( -lcrypto -lpthread -lcurl)
> link_libraries(-lgstreamer-1.0 -lgstrtp-1.0 -lgstrtsp-1.0 -lgstsdp-1.0 -
lgstbase-1.0)
> link_libraries( -lgobject-2.0 -lsigc-2.0)
> link_libraries( -lssl -levent_openssl)
> link_libraries( -lcassandra)
> link_libraries( -lwebsockets)
> link_libraries( -levent -levent_pthreads -lcrypto -lcrypto++)
> link_libraries( -lm -lrt -lz -ldl -lva -lX11 -lm)
> link_libraries(${SEASTAR_DIR_LIBS})

but this is just broken. This will break
-when you update one of those libraries and it needs new dependencies
-when the libraries have different names e.g. because of a custom build
-probably just when you leave your own Linux distro
-for sure if you ever go to any other system (*BSD, Mac, Windows)

> add_executable( ${PROJ_NAME} ${SOURCES} )

When you use the modern version with (imported) targets you can even skip the 
include_directories things. I will reduce my example to 2 libraries for 
clarity, but it will work with the whole bunch also:

find_library(OpenSSL REQUIRED)
find_library(Boost REQUIRED regex)

add_library(foo ...)
target_link_libraries(foo
   # the usage of SSL is buried inside the lib and just an implementation
   # detail
    PRIVATE OpenSSL::SSL 
   # a Boost Regex is part of the API, so everyone using this library needs
   # to get the headers and link to Boost
   PUBLIC Boost:regex
)

add_executable(bar ...)
target_link_libraries(bar foo)

So bar also links to Boost, it get's all the headers and more needed to use 
Boost.

For the very same reason people started using include-what-you-use one should 
not use link_libraries: explicitely specify what you need, otherwise you very 
likely break your build system if any of your dependencies changes and 
suddenly does not drag in one of your needed pieces anymore.

Eike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: This is a digitally signed message part.
URL: <https://cmake.org/pipermail/cmake/attachments/20180421/22231c1f/attachment.sig>


More information about the CMake mailing list