I want to use Boost Multiprecision in my C++ project, but I am unable to. I suspect I haven't added the correct dependencies in my root CMakeLists.txt
configuration, the relevant part of which look like this:
cmake_minimum_required(VERSION 3.30.0)
project(MyProject VERSION 1.0.0 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(src)
add_subdirectory(app)
add_subdirectory(test)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(MPFR REQUIRED)
include_directories(${MPFR_INCLUDE_DIRS})
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
I made sure to link the libraries for my executable in app/CMakeLists.txt
:
add_executable(main main.cpp)
target_link_libraries(main PRIVATE myLib)
target_link_libraries(main ${Boost_LIBRARIES})
target_link_libraries(main ${MPFR_LIBRARIES})
and for my library at src/CMakeLists.txt
:
file(GLOB HEADER_LIST CONFIGURE_DEPENDS "${MyProject_SOURCE_DIR}/include/*.h")
add_library(myLib SomeFile.cpp ${HEADER_LIST})
target_include_directories(myLib PUBLIC ../include)
target_link_libraries(myLib ${Boost_LIBRARIES})
target_link_libraries(myLib ${MPFR_LIBRARIES})
I have verified that both Boost
and MPFR
are installed on my system through the package manager.
My linter (Clangd
) produces no errors when I include the necessary headers and use a multiprecision type:
#include <boost/multiprecision/mpfr.hpp>
// ...
int main() {
IOParser<boost::multiprecision::mpfr_float_100> parser;
// ...
}
But when I compile my program, I get several undefined references to various MPFR functions such as:
[build] /usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: in function `boost::multiprecision::backends::detail::mpfr_float_imp<100u, (boost::multiprecision::mpfr_allocation_type)1>::operator=(boost::multiprecision::backends::detail::mpfr_float_imp<100u, (boost::multiprecision::mpfr_allocation_type)1>&&) [clone .isra.0]':
[build] main.cpp:(.text+0x2dc): undefined reference to `mpfr_swap'
[build] /usr/bin/ld: main.cpp:(.text+0x30c): undefined reference to `mpfr_set4'
[build] /usr/bin/ld: main.cpp:(.text+0x386): undefined reference to `mpfr_init2'
What am I doing wrong?
Since both GMP and MPFR offer pkg-config files, you can use the built-in PkgConfig module to generate a nice modern target that will resolve both include and linker dependencies for you:
find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED IMPORTED_TARGET gmp mpfr)
Now, in app/CMakeLists.txt
you can just do:
target_link_libraries(main PkgConfig::deps)
As a bonus, the PkgConfig approach allows you to specify version bounds.