本文介绍 CMake 中两种查找库的方式:find_package 以及 pkg_check_modules 的用法与区别。
find_package
- 如果编译软件使用了外部库,事先并不知道它的头文件和链接库的位置,得在编译和链接命令中加上包含它们的查找路径,CMake 使用
find_package
命令来解决这个问题。 -
1
FIND_PACKAGE( <name> [version] [EXACT] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets... ] ] )
- 这条命令执行后,CMake 会到变量
CMAKE_MODULE_PATH
指示的目录下查找文件 Findname.cmake 并执行; - 只要找到包,就会定义下面这些变量(都在 Findname.cmake 文件中设置):
- 这条命令执行后,CMake 会到变量
-
1
2
3
4<NAME>_FOUND
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
<NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
<NAME>_DEFINITIONS- 要使用库
name
,我们在顶层目录中的 CMakeLists.txt 文件中,检查变量NAME_FOUND
来确定包是否被找到(大部分包的这些变量中的包名是全大写的,有些包则使用包的实际大小写) - 如果找到这个包,我们用
NAME_INCLUDE_DIRS
调用 include_directories() 命令,用NAME_LIBRARIES
调用 target_link_libraries() 命令。
- 要使用库
pkg_check_modules
- what is the difference between find_package and pkg_search_module
find_package is CMake’s very own mechanism for solving the same problem. For this to work you either need a CMake find script for the requested library (CMake already ships with a couple of those, but you can easily write your own) or alternatively a package config script provided by the requested library itself. In either case you might have to adjust your
CMAKE_MODULE_PATH
for CMake to be able to find the respective script.
pkg_search_module uses the pkg-config tool to determine the location of the requested library. This is mostly useful on systems where pkg-config is already in use, so you do not need to replicate all the information for CMake. Note that this approach has potential portability issues, since it requires pkg-config to be setup correctly on the build machine. - pkg_check_modules 是 CMake 自己的 pkg-config 模块 的一个用来简化的封装:你不用再检查 CMake 的版本,加载合适的模块,检查是否被加载,等等,参数和传给 find_package 的一样:先是待返回变量的前缀,然后是包名(pkg-config 的)。这样就定义了
<prefix>_INCLUDE_DIRS
和其他的这类变量,后续的用法就与 find_package 一致。 - pkg_check_modules 实质上是检测系统中的 pkg-config 是否存在指定的 .pc 文件。
pkg-config
pkg-config is a helper tool used when compiling applications and libraries. It helps you insert the correct compiler options on the command line so an application can use gcc -o test test.c `pkg-config –libs –cflags glib-2.0` for instance, rather than hard-coding values on where to find glib (or other libraries).
It is language-agnostic, so it can be used for defining the location of documentation tools, for instance. 输出已安装的库的相关信息,包括:- C/C++编译器需要的输入参数
- 链接器需要的输入参数
- 已安装软件包的版本信息
pkg-config works on multiple platforms: Linux and other UNIX-like operating systems, Mac OS X and Windows. It does not require anything but a reasonably well working C compiler and a C library, but can use an installed glib if that is present. (A copy of recent glib2 is shipped together with pkg-config versions since 0.27, and this is sufficient for pkg-config to compile and work properly.)
工作原理:当安装一个库时(例如从 RPM,deb 或其他二进制包管理系统),会包括一个后缀名为 pc 的文件,它会放入某个文件夹下 (依赖于你的系统设置,例如,Linux 为 该库文件所在文件夹/lib/pkgconfig)。并把该子文件夹加入 pkg-config 的环境变量PKG_CONFIG_PATH
作为搜索路径。