[CMake] organizing export link libraries

Ruslan Baratov ruslan_baratov at yahoo.com
Tue Aug 26 08:26:21 EDT 2014


On 21-Aug-14 00:50, Nico Schl?mer <nico.schloemer at gmail.com> wrote:
> Hi all,
>
> a general question:
> I have a dependency chain of libraries
>
> A -> B -> C -> ... -> Z
>
> and all of those libraries are built with CMake, using CMake's export
> functionality [1] to let the next in the chain know about its the
> dependencies.
> If all of the libraries are built statically and A needs some symbols
> from a third-party library A1, this information needs to travel to Z.
> Right now, in the export file I'm writing out the link line as
>
> set(a_EXTRA_LIBS -lhdf5 -lhdf5_hl -ldl -lm -lz -lcurl)
You need to use find_package instead of raw `-l<lib>` option since `-l` 
will not work for windows.
In this case it will looks something like this (e.g. curl):

   # CMakeLists.txt
   find_package(CURL REQUIRED)
   target_include_directories(<your_target> PUBLIC ${CURL_INCLUDE_DIRS})
   target_link_libraries(<your_target> PUBLIC ${CURL_LIBRARIES})

See that library's paths are hard-coded in <Project>Targets*.cmake after 
exporting:

   set_target_properties(
       <your-target> PROPERTIES
       INTERFACE_INCLUDE_DIRECTORIES "/usr/include"
   )
   set_target_properties(
       <your-target> PROPERTIES
       IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE 
"/usr/lib/x86_64-linux-gnu/libcurl.so"
   )

If it's not appropriate you can "find" it inside 
<Project>Config.cmake.in file:

   @PACKAGE_INIT@

   find_package(CURL REQUIRED)
   include(".../<Project>Targets.cmake") # import <your_target_name>
   target_include_directories(<your_target> PUBLIC ${CURL_INCLUDE_DIRS}) 
# New curl location
   target_link_libraries(<your_target> PUBLIC ${CURL_LIBRARIES})

but link type need to be PRIVATE:

   # CMakeLists.txt
   find_package(CURL REQUIRED)
   target_include_directories(<your_target> PRIVATE 
${CURL_INCLUDE_DIRS}) # Avoid publishing hard-coded location
   target_link_libraries(<your_target> PRIVATE ${CURL_LIBRARIES})

It's simplier when third-party package is config mode friendly:

   # CMakeLists.txt
   find_package(SomePack CONFIG REQUIRED)
   target_link_libraries(<your_target> PUBLIC SomePack::some_lib)

   # <Project>Config.cmake.in
   @PACKAGE_INIT@
   find_package(SomePack CONFIG REQUIRED) # import SomePack::some_lib
   include(".../<Project>Targets.cmake") # link to SomePack::some_lib 
automatically
   # `target_link_libraries` not needed, already linked

Hope this helps.


More information about the CMake mailing list