3.9 检测外部库:Ⅰ. 使用 pkg-config
NOTE : 此示例代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe-09 中找到,包含一个 C 的示例。该示例在 CMake 3.6 版(或更高版本) 中是有效的,并且已经在 GNU/Linux、macOS 和 Windows 上进行过测试。 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-03/recipe-09 中也有一个适用于 CMake 3.5 的示例。
目前为止,我们已经讨论了两种检测外部依赖关系的方法:
- 使用 CMake 自带的
find-module
,但并不是所有的包在 CMake 的find
模块都找得到。 - 使用
<package>Config.cmake
,<package>ConfigVersion.cmake
和<package>Targets.cmake
,这些文件由软件包供应商提供,并与软件包一起安装在标准位置的 cmake 文件夹下。
如果某个依赖项既不提供查找模块,也不提供供应商打包的 CMake 文件,该怎么办?在这种情况下,我们只有两个选择:
- 依赖
pkg-config
程序,来找到系统上的包。这依赖于包供应商在.pc
配置文件中,其中有关于发行包的元数据。 - 为依赖项编写自己的
find-package
模块。
本示例中,将展示如何利用 CMake 中的 pkg-config
来定位 ZeroMQ 消息库。下一个示例中,将编写一个 find 模块,展示如何为 ZeroMQ 编写属于自己 find
模块。
准备工作
我们构建的代码来自 ZeroMQ 手册 http://zguide.zeromq.org/page:all 的示例。由两个源文件 hwserver.c
和 hwclient.c
组成,这两个源文件将构建为两个独立的可执行文件。执行时,它们将打印“Hello, World”。
具体实施
这是一个 C 项目,我们将使用 C99 标准,逐步构建 CMakeLists.txt
文件:
- 声明一个 C 项目,并要求符合 C99 标准:
cmake_minimum_required(VERSION 3.6 FATAL_ERROR) project(recipe-09 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_C_STANDARD_REQUIRED ON)
- 使用 CMake 附带的 find-module,查找
pkg-config
。这里在find_package
中传递了QUIET
参数。只有在没有找到pkg-config
时,CMake 才会报错:find_package(PkgConfig REQUIRED QUIET)
- 找到
pkg-config
时,我们将使用pkg_search_module
函数,以搜索任何附带包配置.pc
文件的库或程序。该示例中,我们查找 ZeroMQ 库:pkg_search_module( ZeroMQ REQUIRED libzeromq libzmq lib0mq IMPORTED_TARGET )
- 如果找到 ZeroMQ 库,则打印状态消息:
if(TARGET PkgConfig::ZeroMQ) message(STATUS "Found ZeroMQ") endif()
- 然后,添加两个可执行目标,并链接到 ZeroMQ。这将自动设置包括目录和链接库:
add_executable(hwserver hwserver.c) target_link_libraries(hwserver PkgConfig::ZeroMQ) add_executable(hwclient hwclient.c) target_link_libraries(hwclient PkgConfig::ZeroMQ)
- 现在,我们可以配置和构建示例:
$ mkdir -p build $ cd build $ cmake .. $ cmake --build .
- 在终端中,启动服务器,启动时会输出类似于本例的消息:
Current 0MQ version is 4.2.2
- 然后,在另一个终端启动客户端,它将打印如下内容:
Connecting to hello world server… Sending Hello 0… Received World 0 Sending Hello 1… Received World 1 Sending Hello 2… ...
工作
当找到 pkg-config
时, CMake 需要提供两个函数,来封装这个程序提供的功能:
pkg_check_modules
,查找传递列表中的所有模块(库和/或程序)pkg_search_module
,要在传递的列表中找到第一个工作模块
与 find_package
一样,这些函数接受 REQUIRED
和 QUIET
参数。更详细地说,我们对 pkg_search_module
的调用如下:
pkg_search_module( ZeroMQ REQUIRED libzeromq libzmq lib0mq IMPORTED_TARGET )
这里,第一个参数是前缀,它将用于命名存储搜索 ZeroMQ 库结果的目标: PkgConfig::ZeroMQ
。注意,我们需要为系统上的库名传递不同的选项: libzeromq
、 libzmq
和 lib0mq
。这是因为不同的操作系统和包管理器,可为同一个包选择不同的名称。
NOTE : pkg_check_modules
和 pkg_search_module
函数添加了 IMPORTED_TARGET
选项,并在 CMake 3.6 中定义导入目标的功能。3.6 之前的版本,只定义了变量 ZeroMQ_INCLUDE_DIRS
(用于 include 目录) 和 ZeroMQ_LIBRARIES
(用于链接库),供后续使用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论