尝试在 CMake 项目中使用 Boost Multi precision 时,未定义对 mpfr_*() 函数的引用?

问题描述 投票:0回答:1

我想在我的 C++ 项目中使用 Boost Multi precision,但我无法做到。我怀疑我没有在我的根

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_directories(${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
都安装在我的系统上。 当我包含必要的标头并使用多精度类型时,我的 linter (
Clangd
) 不会产生错误:

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

我做错了什么?

c++ cmake boost undefined-reference boost-multiprecision
1个回答
0
投票

离开不完整的旧问题github搜索我总结如下:

MPFR (https://www.mpfr.org/) 不提供 CMake 支持

所以你需要从其他地方获取FindMPFR。如果您的发行版打包程序没有添加它,您必须将其发送到您自己的存储库中:

(mkdir -pv cmake && cd cmake && wget -c https://raw.githubusercontent.com/quarkslab/NFLlib/refs/heads/master/cmake/FindMPFR.cmake)

下载以下示例

cmake/FindMPFR.cmake

# Copyright (c) 2008-2010 Kent State University
# Copyright (c) 2011-2012 Texas A&M University
#
# This file is distributed under the MIT License. See the accompanying file
# LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
# and conditions.

# FIXME: How do I find the version of MPFR that I want to use?
# What versions are available?

# NOTE: MPFR prefix is understood to be the path to the root of the MPFR
# installation library.
set(MPFR_PREFIX "" CACHE PATH "The path to the previx of an MPFR installation")

find_path(MPFR_INCLUDE_DIR mpfr.h
PATHS ${MPFR_PREFIX}/include /usr/include /usr/local/include)

find_library(MPFR_LIBRARY NAMES mpfr
PATHS ${MPFR_PREFIX}/lib /usr/lib /usr/local/lib)

if(MPFR_INCLUDE_DIR AND MPFR_LIBRARY)
get_filename_component(MPFR_LIBRARY_DIR ${MPFR_LIBRARY} PATH)
set(MPFR_FOUND TRUE)
endif()


if(MPFR_FOUND)
if(NOT MPFR_FIND_QUIETLY)
MESSAGE(STATUS "Found MPFR: ${MPFR_LIBRARY}")
endif()
elseif(MPFR_FOUND)
if(MPFR_FIND_REQUIRED)
message(FATAL_ERROR "Could not find MPFR")
endif()
endif()

现在,您可以将 cmake 目录添加到前缀路径

set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/cmake:${CMAKE_PREFIX_PATH}")

或者,显然您已经使用的模块路径行:

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

现在我这样做是为了 MPFR 和 GMP 更加完整:

  • 文件

    ./main.cpp

     #include <boost/multiprecision/mpfr.hpp>
     #include <boost/multiprecision/gmp.hpp>
    
     #include <iostream>
    
    
     int main()
     {
         using namespace boost::multiprecision;
    
         mpfr_float_100 a = 1.0;
         mpfr_float_100 b = 2.0;
         mpfr_float_100 c = a + b;
    
         std::cout << c << std::endl;
    
         mpz_int d = 1;
         mpz_int e = 1;
         mpz_int f = d + e;
    
         std::cout << f << std::endl;
    
         return 0;
     }
    
  • 空文件

    ./app/CMakeLists.txt

  • 空文件

    ./test/CMakeLists.txt

  • 空文件

    ./SomeFile.cpp

  • 空文件

    ./src/CMakeLists.txt

  • 文件

    ./CMakeLists.txt

     cmake_minimum_required(VERSION 3.29.0)
     project(MyProject VERSION 1.0.0 LANGUAGES C CXX)
     #set(CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/cmake:${CMAKE_PREFIX_PATH}")
     set(CMAKE_CXX_STANDARD 20)
     set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
     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})
    
     find_package(GMP REQUIRED)
     include_directories(${GMP_INCLUDE_DIRS})
    
     add_subdirectory(app)
     add_subdirectory(test)
    
     set(CPACK_PROJECT_NAME ${PROJECT_NAME})
     set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
     include(CPack)
    
     add_executable(main main.cpp)
     target_link_libraries(main PRIVATE myLib)
     target_link_libraries(main PUBLIC ${Boost_LIBRARIES})
     target_link_libraries(main PUBLIC ${MPFR_LIBRARY})
     target_link_libraries(main PUBLIC ${GMP_LIBRARY})
    
     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})
    
  • 文件

    ./cmake/FindMPFR.cmake

     # Copyright (c) 2008-2010 Kent State University
     # Copyright (c) 2011-2012 Texas A&M University
     #
     # This file is distributed under the MIT License. See the accompanying file
     # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
     # and conditions.
    
     # FIXME: How do I find the version of MPFR that I want to use?
     # What versions are available?
    
     # NOTE: MPFR prefix is understood to be the path to the root of the MPFR
     # installation library.
     set(MPFR_PREFIX "" CACHE PATH "The path to the previx of an MPFR installation")
    
     find_path(MPFR_INCLUDE_DIR mpfr.h
     PATHS ${MPFR_PREFIX}/include /usr/include /usr/local/include)
    
     find_library(MPFR_LIBRARY NAMES mpfr
     PATHS ${MPFR_PREFIX}/lib /usr/lib /usr/local/lib)
    
     if(MPFR_INCLUDE_DIR AND MPFR_LIBRARY)
     get_filename_component(MPFR_LIBRARY_DIR ${MPFR_LIBRARY} PATH)
     set(MPFR_FOUND TRUE)
     endif()
    
    
     if(MPFR_FOUND)
     if(NOT MPFR_FIND_QUIETLY)
     MESSAGE(STATUS "Found MPFR: ${MPFR_LIBRARY}")
     endif()
     elseif(MPFR_FOUND)
     if(MPFR_FIND_REQUIRED)
     message(FATAL_ERROR "Could not find MPFR")
     endif()
     endif()
    
  • 文件

    ./cmake/FindGMP.cmake

     # Copyright (c) 2008-2010 Kent State University
     # Copyright (c) 2011-2012 Texas A&M University
     #
     # This file is distributed under the MIT License. See the accompanying file
     # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms
     # and conditions.
    
     # FIXME: How do I find the version of GMP that I want to use?
     # What versions are available?
    
     # NOTE: GMP prefix is understood to be the path to the root of the GMP
     # installation library.
     set(GMP_PREFIX "" CACHE PATH "The path to the prefix of a GMP installation")
    
    
     find_path(GMP_INCLUDE_DIR gmp.h
     PATHS ${GMP_PREFIX}/include /usr/include /usr/local/include)
    
     find_library(GMP_LIBRARY NAMES gmp
     PATHS ${GMP_PREFIX}/lib /usr/lib /usr/local/lib)
    
    
     if(GMP_INCLUDE_DIR AND GMP_LIBRARY)
     get_filename_component(GMP_LIBRARY_DIR ${GMP_LIBRARY} PATH)
     set(GMP_FOUND TRUE)
     endif()
    
     if(GMP_FOUND)
     if(NOT GMP_FIND_QUIETLY)
     MESSAGE(STATUS "Found GMP: ${GMP_LIBRARY}")
     endif()
     elseif(GMP_FOUND)
     if(GMP_FIND_REQUIRED)
     message(FATAL_ERROR "Could not find GMP")
     endif()
     endif()
    

它可以在我的机器(TM)上使用 Nix 软件包用于

mpfr
gmp

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.