Boost logo

Boost Interest :

Subject: Re: [Boost-cmake] multiple installed versions, FindBoost.cmake, exported targets, etc.
From: Brad King (brad.king_at_[hidden])
Date: 2009-11-02 10:51:54


troy d. straszheim wrote:
> 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.
[snip]
> Do I pass a sanity-check? It has become hard to tell.

It is an interesting approach to try to define a version preference.
However, there may be problems with having only one BoostConfig.cmake:

- If it changes in future versions it will be hard to ensure the latest
  one is always available.

- The find_package() command Config mode creates a cache entry Boost_DIR
  that saves the location of BoostConfig.cmake. It was in part intended
  to allow the user to have the final say of which package to use by
  setting Boost_DIR to point at the exact version-specific config file.
  Currently your design has no way to let the user force things, and
  a <Pkg>ConfigVersion should *never* set any PARENT_SCOPE or CACHE
  variables, so there is no good way to add it.

The latter of these problems is the more severe. This reveals the need
for help from find_package() on this problem, but for now I propose the
following. Start with a generic always-versioned approach:

  Installed exported targets:
  <prefix>/lib/boost-1.41.0/Boost.cmake
  <prefix>/lib/boost-1.41.0/Boost-release.cmake

  Version-specific cmake infrastructure:
  <prefix>/share/boost-1.41.0/cmake/BoostConfig.cmake
  <prefix>/share/boost-1.41.0/cmake/BoostConfigVersion.cmake

This allows CMake to find Boost versions without the help of the version
selection module. It also allows users to point Boost_DIR at a specific
version. If an auto-version-selection approach is needed, add this:

  Version-agnostic CMake infrastructure:
  <prefix>/share/cmake/boost/BoostConfigVersion.cmake
  <prefix>/share/cmake/boost/BoostConfig.cmake

  Version-specific cmake infrastructure:
  <prefix>/share/cmake/boost/Boost-1.41.0.cmake
    (loads ../../boost-1.41.0/cmake/BoostConfig.cmake)

Note that <prefix>/share/cmake/boost/Boost-1.41.0.cmake can probably be
avoided. Since <prefix>/share/cmake/boost/BoostConfigVersion.cmake is
Boost-aware (unlike generic find_package), it knows the version scheme and
install paths, and can glob <prefix>/share/boost-*/cmake/BoostConfig.cmake
to look for available versions.

Although undocumented, I happen to know that the find_package implementation
will look in "share/cmake/boost*" before "share/boost*/cmake", so in a given
prefix the version-agnostic one will be tried first. This can be formalized
with documented support from find_package() later.

Perhaps a reasonable search order within one <prefix>/share directory is:

  boost
  boost-1.41.0
  boost-1.40.0

In other words, take the unversioned one first in case it has a version
selector. Then traverse the rest in reverse order by component-wise version
tests. We just need to document how the version components are extracted
in general, and perhaps add a way to set an expression (not every project
uses the same version-naming pattern).

> 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.

I can do this, but we need to decide exactly what change to make.
Previously I said that the new code would have this form:

  find_package(Boost QUIET NO_MODULE) # auto-forwards version request
  if(Boost_FOUND)
    # ...perhaps set things for compatibility with old approach...
    return()
  endif()
  # ...old approach...

In the case that the Config-mode call succeeds, we need to ensure that
the available interface after return() is compatible with that returned
by the old approach. This will be up to a combination of the FindBoost
maintainer and/or the new BoostConfig.cmake files to provide.

Another problem is the Boost_ADDITIONAL_VERSIONS interface currently
defined by FindBoost to support unknown future versions. Here are
some snippets:

------------------------------------------------------------------
# NOTE: Take note of the Boost_ADDITIONAL_VERSIONS variable below.
# Due to Boost naming conventions and limitations in CMake this find
# module is NOT future safe with respect to Boost version numbers,
# and may break.
...
# OK, so the Boost_ADDITIONAL_VERSIONS variable can be used to specify a list of
# boost version numbers that should be taken into account when searching
# for Boost.
...
  set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
      "1.40.0" "1.40" "1.39.0" "1.39" ...)
------------------------------------------------------------------

The new approach we're discussing solves this problem, but we need
to decide how to deal with the above interface. Primarily, we need
to know exactly what version of boost will officially start providing
Config-mode find support. Then we can list the last versions that
do not support it in the _Boost_KNOWN_VERSIONS variable and start
ignoring Boost_ADDITIONAL_VERSIONS (or at un-document it).

Boosters need to decide whether to provide BoostConfig.cmake with
bjam-built Boosts too so that all Boosts can be found reliably.

-Brad


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