[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