[CMake] Mixing optional and required libraries with find_package

Michael Hertling mhertling at online.de
Wed Aug 18 13:32:35 EDT 2010


On 08/09/2010 02:55 PM, storri wrote:
> I don't think it is possible to find both required and optional
> libraries with the same find_package command. Is that true?

At <http://www.mail-archive.com/cmake@cmake.org/msg28536.html>, you
will find some considerations w.r.t. requesting required and optional
components from a multi-component package like Boost. As far as I can
see, FindBoost.cmake does not behave well if a requested component is
not found: With REQUIRED, it bails out - which is good - but without,
it returns with Boost_FOUND=FALSE - which is bad. Thus, you may not
request an optional component via FIND_PACKAGE(Boost ...) as such a
component's absence will mark Boost as entirely unavailable, so you
probably have to call FIND_PACKAGE(Boost ...) twice or more. IMO, a
multi-component package's find module should not behave in this way.

> I have a installation of Boost which has a proposed library added into
> it called Boost.Log ('log' for short). I require the
> boost_program_options library but optionally can use 'log' and
> 'boost_thread' (if Boost.Log is compiled with threads).
> 
> My idea was to do the following:
> 
>         find_package(Boost REQUIRED program_options)
>         find_library(Boost.Log NAMES boost_log PATHS
>         ${BOOST_LIBRARYDIR})
> 
> I am not sure if I can use the BOOST_LIBRARYDIR in the find_library
> command. My initial test says that the answer is no. If I use the above
> script in my CMakeLists.txt I get:
> 
>         //Path to a library.
>         Boost_LOG_LIBRARY_DEBUG:FILEPATH=Boost_LOG_LIBRARY_DEBUG-NOTFOUND
>         
>         //Path to a library.
>         Boost_LOG_LIBRARY_RELEASE:FILEPATH=Boost_LOG_LIBRARY_RELEASE-NOTFOUND

As BOOST_LIBRARYDIR is read but not set by FindBoost.cmake, you can't
use it for your purpose in that manner. Instead, try the following:

FIND_PACKAGE(Boost COMPONENTS log)
FIND_PACKAGE(Boost COMPONENTS thread)
FIND_PACKAGE(Boost REQUIRED program_options)

I.e. one FIND_PACKAGE() for each possibly absent optional component, and
the optional components before the required ones. As Boost_LIBRARIES is
apparently cumulative, this should end up with usable Boost_{LOG_FOUND,
THREAD_FOUND,FOUND,LIBRARIES,LIBRARY_DIRS,INCLUDE_DIRS}. Nevertheless,
you'll see "Could NOT find Boost" in CMake's output for each optional
component not being found.

> I would like to have it so I can declare a variable to be added to the
> compiler flags to enable the preprocessor to use the library or compile
> out the instructions wrapped with #ifdef BOOST_LOG.

IF(Boost_LOG_FOUND)
    ADD_DEFINITIONS(-DBOOST_LOG)
ENDIF()

Hope that helps.

Regards,

Michael


More information about the CMake mailing list