Boost logo

Boost Interest :

Subject: [Boost-cmake] multiple installed versions, FindBoost.cmake, exported targets, etc.
From: troy d. straszheim (troy_at_[hidden])
Date: 2009-10-30 18:21:30


Here's what I've got. There are several options controlling how things
are built and installed, here are short descriptions:

INSTALL_VERSIONED: mangle boost version into installed dirnames

So with INSTALL_VERSIONED off:

% cmake .. -DCMAKE_INSTALL_PREFIX=/tmp/local

install layout:

Headers:
/tmp/local/include//boost/mpi.hpp
/tmp/local/include//boost/noncopyable.hpp

Installed exported targets:
/tmp/local/lib/boost/cmake/Boost.cmake
/tmp/local/lib/boost/cmake/Boost-release.cmake

Libs:
/tmp/local/lib/libboost_thread-mt.a
/tmp/local/lib/libboost_thread-mt.so.1.41.0
/tmp/local/lib/libboost_thread-mt.so

Standard CMake infrastructure:
/usr/share/boost/cmake/BoostConfigVersion.cmake
/usr/share/boost/cmake/BoostConfig.cmake

Version-specific cmake infrastructure:
/usr/share/boost/cmake/Boost-1.41.0.cmake

So here you have a 'main' unversioned install . It is possible to also
have versioned installs alongside it, but you may have only one
unversioned install.

You may have many installs via INSTALL_VERSIONED=ON:

cmake .. -DINSTALL_VERSIONED=ON
          -DCMAKE_INSTALL_PREFIX=/tmp/local

Install layout:

Headers:
/tmp/local/include/boost-1.41.0/boost/mpi.hpp
/tmp/local/include/boost-1.41.0/boost/noncopyable.hpp

Installed exported targets:
/tmp/local/lib/boost-1.41.0/Boost.cmake
/tmp/local/lib/boost-1.41.0/Boost-release.cmake

Libs:
/tmp/local/lib/boost-1.41.0/libboost_thread-mt.a
/tmp/local/lib/boost-1.41.0/libboost_thread-mt.so.1.41.0
/tmp/local/lib/boost-1.41.0/libboost_thread-mt.so

Standard CMake infrastructure:
/usr/share/boost/cmake/BoostConfigVersion.cmake
/usr/share/boost/cmake/BoostConfig.cmake

Version-specific cmake infrastructure:
/usr/share/boost/cmake/Boost-1.41.0.cmake

So the only files that conflict are BoostConfig.cmake and
BoostConfigVersion.cmake in /usr/share/boost/cmake; but they don't
really conflict, because they are version agnostic.

How it works: When you do

   find_package(Boost 1.41.0 COMPONENTS thread NO_MODULE)

First /usr/share/boost/cmake/BoostConfigVersion.cmake is called.
it looks for Boost-${PACKAGE_FIND_VERSION} alongside it, and if it is
there, it sets PACKAGE_VERSION to ${PACKAGE_FIND_VERSION} and so forth.
  If it doesn't find the exact version it looks for the newest version,
and sets PACKAGE_VERSION to that, etc.

Then /usr/share/boost/cmake/BoostConfig.cmake is run as usual; it
simply does:

   get_filename_component(CWD ${CMAKE_CURRENT_LIST_FILE} PATH)
   include("${CWD}/Boost-${Boost_VERSION}.cmake")

e.g. it includes /usr/share/boost/cmake/Boost-1.41.0.cmake.
This file was generated by Boost.CMake, so it knows all about the
install, most importantly where the installed exported targets file is,
e.g. /tmp/local/lib/boost-1.41.0/Boost.cmake. It then sets up
${Boost_LIBRARIES} and all that good stuff using the imported targets.

So the following works fine, regardless of how many versions are
installed, with or without one of them installed 'unversioned', or how
strangely they are laid out:

set(Boost_USE_MULTITHREADED ON)

find_package(Boost
   1.41.0
   COMPONENTS thread
   NO_MODULE
   )

include_directories(${Boost_INCLUDE_DIR})

add_executable(main main.cpp)

target_link_libraries(main ${Boost_LIBRARIES})

Do I pass a sanity-check? It has become hard to tell. I think I'm
ready to request that Modules/FindBoost.cmake try Config mode first, so
that end users can omit the NO_MODULE in the find_package above when
cmake 2.8 comes out.

-t


Boost-cmake list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk