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附带的find-module,查找
pkg-config
。这里在find_package
中传递了QUIET
参数。只有在没有找到pkg-config
时,CMake才会报错:找到
pkg-config
时,我们将使用pkg_search_module
函数,以搜索任何附带包配置.pc
文件的库或程序。该示例中,我们查找ZeroMQ库:如果找到ZeroMQ库,则打印状态消息:
然后,添加两个可执行目标,并链接到ZeroMQ。这将自动设置包括目录和链接库:
现在,我们可以配置和构建示例:
在终端中,启动服务器,启动时会输出类似于本例的消息:
然后,在另一个终端启动客户端,它将打印如下内容:
工作
当找到pkg-config
时, CMake需要提供两个函数,来封装这个程序提供的功能:
pkg_check_modules
,查找传递列表中的所有模块(库和/或程序)pkg_search_module
,要在传递的列表中找到第一个工作模块
与find_package
一样,这些函数接受REQUIRED
和QUIET
参数。更详细地说,我们对pkg_search_module
的调用如下:
这里,第一个参数是前缀,它将用于命名存储搜索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
(用于链接库),供后续使用。
Last updated