You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在CMake项目中使用Boost Multiprecision时出现mpfr_*函数未定义引用

问题:Boost Multiprecision 编译时出现MPFR函数未定义引用

我想在C++项目中使用Boost Multiprecision,但编译报错,怀疑是根目录CMakeLists.txt的依赖配置有误。相关配置如下:

根目录CMakeLists.txt 相关代码

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(MPFR_INCLUDE_DIRS})

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

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})

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})

我已通过包管理器确认系统中已安装Boost和MPFR,用Clangd检查代码时,包含必要头文件并使用boost::multiprecision::mpfr_float_100类型未报错:

#include <boost/multiprecision/mpfr.hpp>
// ...

int main() {
    IOParser<boost::multiprecision::mpfr_float_100> parser;
    // ...
}

但编译程序时,出现多个MPFR函数的未定义引用错误,例如:

[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'

请问哪里出错了?


解决方案

问题出在CMake配置顺序和依赖传递方式上,具体原因和修复步骤如下:

1. 依赖查找顺序颠倒

你在执行add_subdirectory(src)、add_subdirectory(app)之后才运行find_package(Boost)和find_package(MPFR),导致子目录的CMake配置在读取Boost/MPFR的变量前就已执行,此时子目录里的${Boost_LIBRARIES}、${MPFR_LIBRARIES}是空值,根本没链接到实际库文件。

修复: 将find_package相关代码移到add_subdirectory之前:

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)

# 先查找依赖,确保子目录能获取到有效变量
find_package(Boost REQUIRED)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(MPFR REQUIRED)

add_subdirectory(src)
add_subdirectory(app)
add_subdirectory(test)

# 不推荐全局include_directories,改用目标级别的头文件配置
# include_directories(${Boost_INCLUDE_DIRS})
# include_directories(${MPFR_INCLUDE_DIRS})

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

2. 改用目标级别的依赖配置,替代全局污染

全局include_directories会影响所有目标,CMake推荐用target_include_directories和target_link_libraries配合PUBLIC/PRIVATE/INTERFACE控制依赖传递:

修改src/CMakeLists.txt:

file(GLOB HEADER_LIST CONFIGURE_DEPENDS "${MyProject_SOURCE_DIR}/include/*.h")
add_library(myLib SomeFile.cpp ${HEADER_LIST})

# 配置头文件路径,PUBLIC确保依赖myLib的目标能继承Boost/MPFR的头文件
target_include_directories(myLib 
    PUBLIC 
        ../include
        ${Boost_INCLUDE_DIRS}
        ${MPFR_INCLUDE_DIRS}
)

# 链接依赖,PUBLIC确保依赖myLib的目标能自动链接Boost/MPFR
target_link_libraries(myLib 
    PUBLIC 
        ${Boost_LIBRARIES}
        ${MPFR_LIBRARIES}
)

修改app/CMakeLists.txt:

由于myLib已通过PUBLIC传递了所有依赖,这里只需链接myLib即可:

add_executable(main main.cpp)
target_link_libraries(main PRIVATE myLib)

3. 额外检查:确认MPFR的CMake模块有效性

如果cmake目录下的FindMPFR.cmake脚本存在问题,可能导致${MPFR_LIBRARIES}未指向正确的库文件。可以:

  • 在根CMakeLists中添加message(STATUS "MPFR Libraries: ${MPFR_LIBRARIES}"),查看输出是否为实际的MPFR库路径(如/usr/lib/libmpfr.so)。
  • 如果输出异常,改用pkg_check_modules查找MPFR:
find_package(PkgConfig REQUIRED)
pkg_check_modules(MPFR REQUIRED mpfr)

总结

核心问题是依赖查找顺序颠倒导致子目录无法获取有效库变量,同时依赖配置不够规范。调整顺序并改用目标级别的依赖传递后,链接错误即可解决。


内容的提问来源于stack exchange,提问作者Kotaka Danski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:09:53