[CMake] Creating relocatable export files

Roger Leigh rleigh at codelibre.net
Sat Nov 14 06:53:11 EST 2015


Hi,

I'm wanting to create -config scripts for my libraries so that dependent 
projects can find them with find_package and use them transparently.  I 
have a number of header-only and shared/static libs, and I'd like to 
retain their relationships, plus any additional libraries they are 
linked with.

I was previously using hand-crafted templates, e.g. with this type of 
generated structure:

---------------------------------------------------------------------------
set(OME_COMMON_FOUND TRUE)

set(OME_COMMON_VERSION "5.2.0-pre0-7-gfc53ca3")
set(OME_COMMON_VERSION_MAJOR "5")
set(OME_COMMON_VERSION_MINOR "2")
set(OME_COMMON_VERSION_PATCH "0")
set(OME_COMMON_VERSION_EXTRA "-pre0-7-gfc53ca3")

find_path(OME_COMMON_INCLUDE_DIR ome/common/module.h HINTS 
"/tmp/split/include")
find_library(OME_COMMON_LIBRARY NAMES ome-common libome-common HINTS 
"/tmp/split/lib")
---------------------------------------------------------------------------

They unfortuately did not handle interface targets or public library 
dependencies required by use in the headers.  I've switched to using 
install(EXPORT):

https://github.com/rleigh-dundee/ome-common-cpp/blob/develop/lib/ome/common/CMakeLists.txt#L123
---------------------------------------------------------------------------
target_link_libraries(ome-common ome-compat
                       ${Boost_LOG_SETUP_LIBRARY_RELEASE}
                       ${Boost_LOG_LIBRARY_RELEASE}
                       ${Boost_FILESYSTEM_LIBRARY_RELEASE}
                       ${Boost_SYSTEM_LIBRARY_RELEASE}
                       ${LibDl_LIBRARIES}
                       ${XercesC_LIBRARIES})

set_target_properties(ome-common PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(ome-common PROPERTIES VERSION ${OME_VERSION_SHORT})

install(TARGETS ome-common
         EXPORT ome-common-config
         RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
         LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
         ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
install(EXPORT ome-common-config
         DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/ome-common)
---------------------------------------------------------------------------

This does a much better job of the dependencies.  It's preserving the 
dependencies for the internal targets, plus the external libraries. 
However, it's lacking:

- any setting of the include path via FOO_INCLUDE_DIR, unless it's just 
not done in an obvious manner
- it's hardcoded the absolute paths of the various boost and xerces 
libs; I'd like it to be relocatable so it can work in a superbuild and 
continue to work after moving elsewhere
- it doesn't appear to recursively find needed import targets, e.g. I 
need to find_package(ome-compat) before find_package(ome-common); it 
would be nice if this was transparent so the user doesn't need to do this

I'd be interested to know if anyone else has run into these issues, and 
if so what your solutions were?  I'm quite new to this part of cmake, so 
it may well just be I'm not doing things exactly as expected.

Would it be easier to construct the template myself and then call 
find_package for the external libs to avoid hardcoding the paths?  Is it 
safe to recursively call find_package inside find_package?


Thanks all,
Roger


More information about the CMake mailing list