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

问题描述

我正在尝试使用find_package在CMake中包含库。

This question讨论了如何告诉CMake链接到GMP library (external)。我正在尝试按照那里的答案进行操作,但是没有某些评论中提到的<name>Config.cmake<name>-config.cmake文件,这似乎是默认的。当您不知道如何获取/查找这些文件时,答案没有提及任何解决方案。该答案的注释链接到一个旧的website (external),其中包含很多断开的链接,这些链接描述了加载模块列表。我不清楚这些模块来自何处以及如何获得它们。

根据官方CMake documentation (external),如果找不到配置文件,则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负载模块)?

从广义上讲,有以下三个桶:

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

一个人怎么期望另一个用户在他们的系统上拥有这些文件?

安装软件包所需的任何依赖项都是您的工作。使用现代CMake的任何产品(上面列出的项目1)应在安装过程中安装XXXConfig.cmake文件。如果库不是由CMake构建的,则您要么希望项目符号2,要么查找/编写自己的FindXXX.cmake文件(项目符号3)。

对于您的特定情况,使用find_library可能会更好,因为示例编译行看起来只需要链接即可。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...