我正在尝试使用
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 加载模块)?
从广义上讲,这些可分为三类:
GMPConfig.cmake
的文件,cmake 可以通过搜索预先配置的路径或在配置时提供特定路径来找到该文件 (cmake -DGMP_Dir=/path/to/GMP/install/root
)。这种方法的优点是 GMPConfig.cmake 的生成大部分是自动的,并且库可以包含安装路径和编译标志等内容。缺点是库的开发实际上必须努力利用现代 CMake,但并不是每个人都会这样做。CMAKE_MODULE_PATH
。如何期望另一用户在他的系统上拥有这些文件?
安装包所需的任何依赖项是您的工作。任何使用现代 CMake(上面列出的第 1 条)的内容都应在安装过程中安装 XXXConfig.cmake 文件。如果库是由 CMake 以外的其他东西构建的,您必须希望得到第 2 条子弹,或者找到/编写您自己的 FindXXX.cmake 文件(第 3 条子弹)。
对于您的具体情况,您可能最好使用
find_library
,因为您的示例编译行看起来只需要链接。
假设您已经编译了 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
更新这个答案。