On Tuesday 15 May 2012, Matthew LeRoy wrote:
Hi again,
I'm working on setting up install(...) commands for a shared library
project (call it libA), and I'm using the install(EXPORT ...) signature as
has been recommended to me previously to export the shared library target
so I can import it in another CMake-based project (call it libB). So far
things have been pretty straightforward, but I'm now trying to determine
how to deal with the public header files for the project. So, two
questions:
1. What's the preferred method for installing public headers? I've seen
sparse documentation about a PUBLIC_HEADER target property, but the lack
of information I can find about it via Google makes me wonder if it's not
considered 'best practice'. Taking a look at the CMake list files for the
LLVM project, they seem to be using multiple install(DIRECTORY ...)
commands. I'm sure there are multiple ways to do this, so what's
recommended?
set(INCLUDE_INSTALL_DIR include)
install(FILES a.h b.h. c.h. DESTINATION ${INCLUDE_INSTALL_DIR} )
or using GNUInstallDirs.cmake:
include(GNUInstallDirs)
...
install(FILES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
2. How should libB find the location of the installed headers for libA?
With Find* modules (of which I'm using a few, FindBoost being one), there
is generally a LibName_INCLUDE_DIRs variable that gets set with the
include path that I would add in libB's list file via
include_directories(${LibName_INCLUDE_DIRS}). But, since I'm using
exported/imported targets instead of a Find* module, there doesn't seem to
be any built-in support for 'importing' the headers. I saw something in
the release notes for a recent CMake version (2.8, I think?) about
something called 'per-target INCLUDE_DIRECTORIES', which sounds promising,
but couldn't find much more info about it.
This is related, but not yet ready for this purpose.
This is just that you can set per-target include dirs instead of using
include_directories()
which works per directory.
Alright, I lied... a third somewhat-related question:
3) What's the general practice as far as where to install the .cmake file
generated by the install(EXPORT ...) command? Should it go in the install
location along with the built targets? It seems that the generated .cmake
file is intended to replace Find* modules and prevent other projects from
having to know the installed location of the exported library... but
wouldn't putting the generated .cmake import file in the install location
require dependent projects to know where the install location is in order
to include the .cmake import file?
This is described in detail in the documentation to find_package().
Short version: put it into lib/cmake/$YourProject/
optionally with a version number:
lib/cmake/$YourProject-1.2.3/
CMake will look there for FooConfig.cmake.
I recommend to export the targets into a file named e.g. FooTargets.cmake, and
write FooConfig.cmake yourself, something like:
...
set(FOO_INCLUDE_DIRS ... )
include(${CMAKE_CURRENT_LIST_DIR}/FooTargets.cmake)
(CMAKE_CURRENT_LIST_DIR exists since cmake 2.8.3 I think)
Setting the include dirs here properly is not trivial.
The user expects it to be an absolute path.
Configuring an absolute path into this file at build time means the install
location of that package is fixed and cannot be changed later on.
To make this package relocatable, i.e. so that the later user can decide
about the install location, I recommend to use CMakePackageConfigHelpers.cmake
coming with cmake 2.8.8, use the function configure_package_config_file().
If the documentation is unclear, let me know.
Alex
--
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Please keep messages on-topic and check the CMake FAQ at:
http://www.cmake.org/Wiki/CMake_FAQ
Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake