[CMake] Package installation conundrum

Alexander Neundorf a.neundorf-work at gmx.net
Wed May 9 15:03:10 EDT 2012


On Wednesday 09 May 2012, Michael Wild wrote:
> On 05/08/2012 11:13 PM, Dave Abrahams wrote:
> > on Tue May 08 2012, Alexander Neundorf <a.neundorf-work-hi6Y0CQ0nG0-AT-
public.gmane.org> wrote:
> >> On Tuesday 08 May 2012, Dave Abrahams wrote:
> >>> Here's another one!
> >>> 
> >>> Scenario:
> >>> 
> >>> * I am running CMake under 0install to build and install libraries
> >>> 
> >>> * Each library builds a package SomePackage for the library binaries
> >>> and another package SomePackage-dev for the library headers (and
> >>> import libraries on Windows)
> >>> 
> >>> * The FindSomePackage.cmake file is part of the -dev package
> >>> 
> >>> * After building, 0install moves each package's build products into a
> >>> mostly-unpredictable subdirectory of its otherwise-read-only "cache"
> >>> (~/.cache/0install.net/). The subdirectory's name is determined by a
> >>> hash of the files.
> >>> 
> >>> * To get this working, I followed the scheme discussed here:
> >>> 
> >>> http://news.gmane.org/find-root.php?message_id=%3cm2lil6s8jq.fsf%40plut
> >>> o.l uannocracy.com%3e
> >>> 
> >>> Summary:
> >>> 
> >>> 1. Create a 0install "SomePackage-preinstall" package. Building this
> >>> package involves CMake building and installing both SomePackage and
> >>> SomePackage-dev into separate subdirectories (main/ and dev/) of
> >>> some prefix. 0install thereafter moves the whole directory tree
> >>> into its cache in a directory called sha1=someuglyhash
> >>> 
> >>> 2. SomePackage's 0installation procedure is to copy
> >>> sha1=someuglyhash/main/ into its distribution directory (which then
> >>> ends up in
> >>> ~/.cache/0install.net/sha1=otheruglyhash)
> >>> 
> >>> 3. SomePackage-dev's 0installation procedure is to copy
> >>> sha1=someuglyhash/dev/ into its distribution directory
> >>> 
> >>> Problem: FindSomePackageConfig.cmake now has the wrong path to the
> >>> library binaries.
> >>> 
> >>> Any help most appreciated.
> >> 
> >> Can you please summarize what you actually want to achieve ?
> > 
> > Well, I tried to, above.
> > 
> > In short, I want to create separate main and -dev packages without
> > building twice, under the constraints imposed by 0install.
> > 
> >> Do you say that libFoo installs a FindFoo.cmake as part of libFoo-devel
> >> ?
> >> 
> >> If that's the case, then this is wrong.
> > 
> > I'm sorry, that *is* wrong.  It installs a FooConfig.cmake as part of
> > libFoo.devel
> > 
> >> FindFoo.cmake must be part of the using software, not of the software to
> >> be searched.
> >> 
> >> Why do you have to find the installed library in this cache directory
> >> ?
> > 
> > Because, in a 0install world, that's where things go when you "install"
> > them.
> 
> Ok, how you do it along these lines:
> 
> CMakeLists.txt:
> #-------------- BOF
> 
> cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
> project(Foo)
> 
> set(FOO_VERSION 1.2.3)
> 
> # initialize (absolute) installation directory variables
> set(INSTALL_BIN_DIR bin CACHE PATH "Install path for binaries")
> set(INSTALL_LIB_DIR lib CACHE PATH "Install path for libraries")
> set(INSTALL_INCLUDE_DIR include CACHE PATH "Install path for headers")
> # this is for UNIX systems, see docs of find_package() for the search
> # paths on APPLE and WIN32
> set(INSTALL_CMAKE_DIR lib/foo-${FOO_VERSION}/cmake CACHE PATH
>   "Install path for CMake files")
> foreach(t BIN LIB INCLUDE CMAKE)
>   if(NOT IS_ABSOLUTE ${INSTALL_${t}_DIR})
>     set(INSTALL_${t}_DIR ${CMAKE_INSTALL_PREFIX}/${INSTALL_${t}_DIR})
>   endif()
>   mark_as_advanced(INSTALL_${t}_DIR)
> endforeach()
> 
> # configure FooConfig.cmake and friends. FooConfig.cmake must be able
> # to locate FooExports.cmake and FOO_INCLUDE_DIR relative to its own
> # directory without using absolute paths.
> configure_file(cmake/FooConfig.cmake.in
>   ${PROJECT_BINARY_DIR}/FooConfig.cmake @ONLY)

Please have a lokok at the new macro configure_package_config_file() which is 
in cmake 2.8.8.
This helps a lot with writing config files which are relocatable.

The Config.cmake.in file has to contains a few special variables/macros:

@PACKAGE_INIT@

set(FOO_INCLUDE_DIR "@PACKAGE_INSTALL_INCLUDE_DIR@" )
set(FOO_BIN_DIR "@PACKAGE_INSTALL_BIN_DIR@" )

i.e. for every FOO_XYZ variable use a @PACKAGE_FOO_XYZ@ variable, and the 
configure_package_config_file() will replace this with the help of the 
@PACKAGE_INIT@ macro with a relocatable version.
http://www.cmake.org/cmake/help/v2.8.8/cmake.html#module:CMakePackageConfigHelpers

> configure_file(cmake/FooConfigVersion.cmake.in
>   ${PROJECT_BINARY_DIR}/FooConfigVersion.cmake @ONLY)
> 
> # configure the headers into the build tree so the package can be used
> # without installing it and not hard-coding the source/build directory
> # information into FooConfig.cmake
> configure_file(include/foo.h
>   ${PROJECT_BINARY_DIR}/include/foo.h COPYONLY)

The input file should have a suffix which indicates it is a file which is 
intended to be configured, usually foo.h.in.

Alex
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20120509/f565d0ba/attachment-0001.htm>


More information about the CMake mailing list