1

Is there a way to check if specific Boost headers are available using CMake? I'm particularly interested in boost/multiprecision/mpfr.hpp and boost/multiprecision/mpc.hpp.

find_package(boost REQUIRED) can tell if I have boost installed or not, but it doesn't tell if one of those headers is missing.

I'm also aware of the check_include_file_cxx macro, but it seems to be taking absolute paths.

Javier Garcia
  • 539
  • 1
  • 4
  • 15
  • You may be able to use the COMPONENTS option to make sure `multiprecision` exists [https://cmake.org/cmake/help/latest/module/FindBoost.html?highlight=boost](https://cmake.org/cmake/help/latest/module/FindBoost.html?highlight=boost) – drescherjm Dec 11 '20 at 19:58
  • 1
    Thanks, edited the comma. `COMPONENTS` only works for compiled libraries, as explained in an answer [here](https://stackoverflow.com/questions/26749461/how-to-determine-the-boost-library-names-for-cmake). If I add `COMPONENTS multiprecision` the build fails even though on my computer I have it properly installed. – Javier Garcia Dec 11 '20 at 20:04
  • 1
    "I'm also aware of the `check_include_file_cxx` macro, but it seems to be taking absolute paths." - No, [check_include_file_cxx](https://cmake.org/cmake/help/latest/module/CheckIncludeFileCXX.html) macro perfectly works (and intended to work) with relative path, essentially with a path you use in `#include <>` directive. See e.g. [that question](https://stackoverflow.com/questions/3043675/in-cmake-how-does-check-include-file-cxx-work) as example. You may use value of `Boost_INCLUDE_DIRS` variable for `CMAKE_REQUIRED_INCLUDES`, used by this macro. – Tsyvarev Dec 12 '20 at 09:04

1 Answers1

1

I think I was complicating things unnecessarily. The reason I wanted to check for specific headers is because in Ubuntu 18.04 I had the mpfr.hpp header but not the mpc.hpp one. Later I found out that this is because the latter is included since version 1.69 of Boost, so adding VERSION 1.69 to find_package(...) would've been enough for me.

Nevertheless, a solution using check_include_file_cxx is possible, as @Tsyvarev pointed out. The macro check_include_file_cxx not only checks if the required header is available, but also tries to compile a small test program. For that, it also needs to link to libraries (-lmpfr for boost/multiprecision/mpfr.hpp and -lmpfr -lmpc for boost/multiprecision/mpc.hpp).

This did the trick for me.

find_package(Boost REQUIRED
    VERSION 1.69)

if ( Boost_FOUND )
    include_directories(${Boost_INCLUDE_DIRS})
endif()

include(CheckIncludeFileCXX)
cmake_policy(SET CMP0075 NEW) # Required for specifying CMAKE_REQUIRED_LIBRARIES

set(CMAKE_REQUIRED_INCLUDES "${Boost_INCLUDE_DIRS}")
set(CMAKE_REQUIRED_LIBRARIES "mpfr" "mpc" "gmp")

set(REQUIRED_BOOST_HEADERS
    "boost/multiprecision/mpfr.hpp;boost/multiprecision/mpc.hpp"
    )
foreach(HEADER ${REQUIRED_BOOST_HEADERS})
    check_include_file_cxx("${HEADER}" ${HEADER}_FOUND)
    if (NOT ${HEADER}_FOUND)
        message(FATAL_ERROR "HEADER ${HEADER} NOT FOUND")
    endif()
endforeach()

Javier Garcia
  • 539
  • 1
  • 4
  • 15