如何在CMake中使用find_package? (例如:GMP 库)

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

我正在尝试使用

find_package
将库包含在 CMake 中。

这个问题讨论如何告诉CMake链接到GMP库(外部)。我正在尝试按照那里的答案步骤进行操作,但没有任何

<name>Config.cmake
<name>-config.cmake
文件,正如一些评论所提到的,这似乎是默认的。当您不知道如何获取/查找这些文件时,答案没有提及任何解决方案。该答案的评论链接到一个旧的网站(外部),其中有很多损坏的链接,该链接描述了加载模块的列表。我不清楚这些模块从哪里来以及如何获取它们。

根据官方 CMake 文档(外部),如果找不到配置文件,

find_package
会从“模块模式”回退到“配置模式”。我不明白这意味着什么以及在什么情况下这会相关,特别是因为文档不鼓励阅读有关“配置模式”的内容。

文档是这么说的

首先在 CMAKE_MODULE_PATH 中搜索该文件,然后在 CMake 安装提供的查找模块中搜索。

我仍然对这些配置文件是否应该与 CMake 一起提供还是与相关库一起提供以及它们应该位于何处感到困惑。也许两者都有可能,但在特定情况下如何知道?

示例代码,尝试遵循现代最佳实践:

# CMakeLists.txt (not working)
cmake_minimum_required(VERSION 3.2)  # I have no idea what version I actually need

project (GMP_demo_project)

# Enable C++17 standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(GMP REQUIRED)

# Create the executable from sources
add_executable(GMP_demo GMP_demo.cpp)
target_link_libraries(GMP_demo gmp gmpxx)

代码输出一条错误消息,类似于

 CMake Error at CMakeLists.txt:10 (find_package):
  By not providing "FindGMP.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "GMP", but
  CMake did not find one.
  Could not find a package configuration file provided by "GMP" with any of
  the following names:
    GMPConfig.cmake
    gmp-config.cmake
  Add the installation prefix of "GMP" to CMAKE_PREFIX_PATH or set "GMP_DIR"
  to a directory containing one of the above files.  If "GMP" provides a
  separate development package or SDK, be sure it has been installed.

问题:一般来说,如何获取和组织这些配置文件(CMake 加载模块)?如何期望另一用户在他的系统上拥有这些文件? 我的问题是一般性的,仅使用 GMP 作为示例(尽管我实际上对能够使用它感兴趣)。

顺便说一句,在按照库文档的建议安装 GMP 后,我可以使用

gcc GMP_demo.cpp -lstdc++ -lgmp
编译、链接和执行我的演示代码。问题只是让 CMake 来做这件事。我也可以只给 CMake 库的绝对路径,这当然会更容易,但不可移植(假设可以让 find_package 实际工作并通过合理的工作量进行移植)。

cmake gmp
2个回答
4
投票

一般来说,如何获取和组织这些配置文件(CMake 加载模块)?

从广义上讲,这些可分为三类:

  1. 包直接提供的文件。这是理想的解决方案,也是 CMake 所说的配置模式。将会有一个名为
    GMPConfig.cmake
    的文件,cmake 可以通过搜索预先配置的路径或在配置时提供特定路径来找到该文件 (
    cmake -DGMP_Dir=/path/to/GMP/install/root
    )。这种方法的优点是 GMPConfig.cmake 的生成大部分是自动的,并且库可以包含安装路径和编译标志等内容。缺点是库的开发实际上必须努力利用现代 CMake,但并不是每个人都会这样做。
  2. CMake直接提供的文件。对于常见的软件包(例如 boost),CMake 提供 FindXXX.cmake 文件,该文件搜索众所周知的路径并为您处理此问题。从最终用户的角度来看,它们的工作方式与上述相同,但可用的 Find 模块取决于您安装的 CMake 版本。
  3. 由随机人员提供的文件,这些文件被复制/粘贴到项目中。这些如何工作取决于编写它的人,因此您必须阅读他们的文档。使用您最喜欢的搜索引擎并尝试找到 FindGMP.cmake,然后将其放入某个模块文件夹中并适当更新
    CMAKE_MODULE_PATH

如何期望另一用户在他的系统上拥有这些文件?

安装包所需的任何依赖项是您的工作。任何使用现代 CMake(上面列出的第 1 条)的内容都应在安装过程中安装 XXXConfig.cmake 文件。如果库是由 CMake 以外的其他东西构建的,您必须希望得到第 2 条子弹,或者找到/编写您自己的 FindXXX.cmake 文件(第 3 条子弹)。

对于您的具体情况,您可能最好使用

find_library
,因为您的示例编译行看起来只需要链接。


0
投票

假设您已经编译了 GMP 库并且您知道在哪里可以找到

gmpxx.h
libgmpxx.a

add_library(GMP::STATIC STATIC IMPORTED)
target_include_directories(GMP::STATIC INTERFACE <PATH_TO_FOLDER_CONTAINING_gmpxx.h>)
target_link_libraries(GMP::STATIC INTERFACE <PATH_TO_libgmpxx.a>)
set_target_properties(
  GMP::STATIC
  PROPERTIES
  IMPORTED_LOCATION <PATH_TO_libgmpxx.a>
)

第一行告诉 CMAKE 你有一个名为

GMP::STATIC
的静态库,它不是由 CMAKE 构建的,而是你导入的。

第二行告诉 CMAKE,任何调用

target_link_libraries(TARGET GMP::STATIC)
的人都想查看可用的标头
gmpxx.h

第三行指向静态库文件。

最后一行是 CMAKE 所需的一些管道。

target_link_libraries(主 GMP::STATIC)

如果你想写一个FindGMP.cmake,我建议阅读这篇文章 写完后我会用

FindGMP.cmake
更新这个答案。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.