返回介绍

3.9 检测外部库:Ⅰ. 使用 pkg-config

发布于 2025-05-06 21:45:55 字数 3889 浏览 0 评论 0 收藏 0

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.chwclient.c 组成,这两个源文件将构建为两个独立的可执行文件。执行时,它们将打印“Hello, World”。

具体实施

这是一个 C 项目,我们将使用 C99 标准,逐步构建 CMakeLists.txt 文件:

  1. 声明一个 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)
  2. 使用 CMake 附带的 find-module,查找 pkg-config 。这里在 find_package 中传递了 QUIET 参数。只有在没有找到 pkg-config 时,CMake 才会报错:
    find_package(PkgConfig REQUIRED QUIET)
  3. 找到 pkg-config 时,我们将使用 pkg_search_module 函数,以搜索任何附带包配置 .pc 文件的库或程序。该示例中,我们查找 ZeroMQ 库:
    pkg_search_module(
      ZeroMQ
      REQUIRED
          libzeromq libzmq lib0mq
      IMPORTED_TARGET
      )
  4. 如果找到 ZeroMQ 库,则打印状态消息:
    if(TARGET PkgConfig::ZeroMQ)
        message(STATUS "Found ZeroMQ")
    endif()
  5. 然后,添加两个可执行目标,并链接到 ZeroMQ。这将自动设置包括目录和链接库:
    add_executable(hwserver hwserver.c)
    target_link_libraries(hwserver PkgConfig::ZeroMQ)
    add_executable(hwclient hwclient.c)
    target_link_libraries(hwclient PkgConfig::ZeroMQ)
  6. 现在,我们可以配置和构建示例:
    $ mkdir -p build
    $ cd build
    $ cmake ..
    $ cmake --build .
  7. 在终端中,启动服务器,启动时会输出类似于本例的消息:
    Current 0MQ version is 4.2.2
  8. 然后,在另一个终端启动客户端,它将打印如下内容:
    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 一样,这些函数接受 REQUIREDQUIET 参数。更详细地说,我们对 pkg_search_module 的调用如下:

pkg_search_module(
  ZeroMQ
  REQUIRED
      libzeromq libzmq lib0mq
  IMPORTED_TARGET
  )

这里,第一个参数是前缀,它将用于命名存储搜索 ZeroMQ 库结果的目标: PkgConfig::ZeroMQ 。注意,我们需要为系统上的库名传递不同的选项: libzeromqlibzmqlib0mq 。这是因为不同的操作系统和包管理器,可为同一个包选择不同的名称。

NOTE : pkg_check_modulespkg_search_module 函数添加了 IMPORTED_TARGET 选项,并在 CMake 3.6 中定义导入目标的功能。3.6 之前的版本,只定义了变量 ZeroMQ_INCLUDE_DIRS (用于 include 目录) 和 ZeroMQ_LIBRARIES (用于链接库),供后续使用。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。