pkg-config 命令详解
一、命令概述
pkg-config 是 Linux/Unix 系统中用于获取已安装库的元信息 (如编译选项、链接选项、版本号等)的工具,核心用途是简化库的编译与链接流程。它通过读取库对应的 .pc 元数据文件,自动生成编译时所需的 -I(头文件路径)、-L(库路径)、-l(库名)等参数,避免手动指定复杂路径,尤其适合在 Makefile 或自动化构建脚本(如 Autoconf)中使用。
核心依赖:.pc 元数据文件
- 作用 :存储库的关键信息(版本、头文件路径、链接选项、依赖关系等),文件名格式为
库名.pc(如gtk+-3.0.pc)。 - 默认搜索路径 :
/usr/lib/pkgconfig、/usr/share/pkgconfig、/usr/local/lib/pkgconfig、/usr/local/share/pkgconfig。 - 自定义路径 :通过环境变量
PKG_CONFIG_PATH指定(冒号分隔,Windows 用分号)。
二、命令语法
pkg-config 选项繁多,按功能可分为多组,语法格式如下(方括号表示可选):
bash
pkg-config [--modversion] [--version] [--help] [--atleast-pkgconfig-version=VERSION]
[--print-errors] [--short-errors] [--silence-errors] [--errors-to-stdout] [--debug]
[--cflags] [--libs] [--libs-only-L] [--libs-only-l] [--cflags-only-I] [--libs-only-other] [--cflags-only-other]
[--variable=VARIABLENAME] [--define-variable=VARIABLENAME=VARIABLEVALUE] [--print-variables]
[--uninstalled] [--exists] [--atleast-version=VERSION] [--exact-version=VERSION] [--max-version=VERSION]
[--list-all] [--print-provides] [--print-requires] [--print-requires-private]
[--static] [--msvc-syntax] [--dont-define-prefix] [--prefix-variable=PREFIX]
LIBRARIES...
LIBRARIES:必填(部分选项如--list-all除外),指定要查询的库名(即.pc文件去掉.pc后的名称,如glib-2.0)。
三、选项详解
按功能分类整理选项,标注作用、描述及示例,核心选项优先说明:
3.1 基础信息选项(版本/帮助/错误控制)
| 选项 | 功能描述 | 示例 |
|---|---|---|
--version |
输出版本信息并退出(显示 pkg-config 自身版本)。 |
pkg-config --version |
--help |
显示帮助信息(含所有选项说明)并退出。 | pkg-config --help |
--modversion |
输出指定库的版本号(需配合 LIBRARIES)。 |
pkg-config --modversion glib-2.0 |
--atleast-pkgconfig-version=VERSION |
检查 pkg-config 版本是否不低于 VERSION,满足则退出码 0。 |
pkg-config --atleast-pkgconfig-version=0.29 |
--print-errors |
打印库查找或 .pc 文件解析错误(默认"断言类"选项如 --exists 不打印错误)。 |
pkg-config --print-errors --exists gtk+-3.0 |
--silence-errors |
抑制错误输出(与 --print-errors 相反)。 |
pkg-config --silence-errors --cflags nonexistent-lib |
--debug |
输出调试信息(如 .pc 文件搜索路径、变量解析过程)。 |
pkg-config --debug --libs glib-2.0 |
3.2 编译与链接选项(核心功能)
用于生成编译(CFLAGS)和链接(LDFLAGS)所需的参数,是 pkg-config 最常用的选项组。
| 选项 | 功能描述 | 示例(以 glib-2.0 为例) |
|---|---|---|
--cflags |
输出编译所需的所有参数(含头文件路径 -I、宏定义等,包含依赖库的参数)。 |
pkg-config --cflags glib-2.0 → -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include |
--cflags-only-I |
仅输出 --cflags 中的 -I 部分(头文件路径)。 |
pkg-config --cflags-only-I glib-2.0 → 同上 |
--cflags-only-other |
仅输出 --cflags 中除 -I 外的其他参数(如宏定义 -D)。 |
pkg-config --cflags-only-other gtk+-3.0 → -pthread -DGDK_DISABLE_DEPRECATED |
--libs |
输出链接所需的所有参数(含库路径 -L、库名 -l、其他链接标志,包含依赖库的参数)。 |
pkg-config --libs glib-2.0 → -lglib-2.0 |
--libs-only-L |
仅输出 --libs 中的 -L 部分(库路径)。 |
pkg-config --libs-only-L gtk+-3.0 → -L/usr/lib/x86_64-linux-gnu |
--libs-only-l |
仅输出 --libs 中的 -l 部分(库名)。 |
pkg-config --libs-only-l glib-2.0 → -lglib-2.0 |
--libs-only-other |
仅输出 --libs 中除 -L/-l 外的其他参数(如 -pthread、-rdynamic)。 |
pkg-config --libs-only-other gtk+-3.0 → -pthread |
--static |
输出静态链接 所需的参数(含私有依赖库 Libs.private 中的选项)。 |
pkg-config --static --libs glib-2.0 → -lglib-2.0 -lm -pthread |
3.3 变量操作选项(查询/定义 .pc 文件变量)
.pc 文件中定义了如 prefix、libdir、includedir 等变量,可通过以下选项查询或覆盖。
| 选项 | 功能描述 | 示例 |
|---|---|---|
--variable=VARIABLENAME |
输出指定库 .pc 文件中 VARIABLENAME 变量的值。 |
pkg-config --variable=prefix glib-2.0 → /usr |
--define-variable=VARIABLENAME=VALUE |
覆盖 .pc 文件中的变量值(全局生效,优先于文件内定义)。 |
pkg-config --define-variable=prefix=/opt --variable=prefix glib-2.0 → /opt |
--print-variables |
列出指定库 .pc 文件中所有定义的变量。 |
pkg-config --print-variables glib-2.0 → prefix、exec_prefix、libdir 等 |
3.4 版本与存在性检查选项(脚本中常用)
用于检查库是否存在或版本是否满足要求,退出码反映结果(0 为满足,非 0 为不满足),适合在 shell 脚本或 Makefile 中判断。
| 选项 | 功能描述 | 示例 |
|---|---|---|
--exists |
检查指定库是否存在(.pc 文件可找到),存在则退出码 0。 |
pkg-config --exists glib-2.0 → 退出码 0(存在) |
--atleast-version=VERSION |
检查库版本是否不低于 VERSION(需配合 --exists 或直接跟库名)。 |
pkg-config --exists 'glib-2.0 >= 2.64' → 检查 glib 版本是否≥2.64 |
--exact-version=VERSION |
检查库版本是否等于 VERSION。 |
pkg-config --exists 'gtk+-3.0 = 3.24.0' |
--max-version=VERSION |
检查库版本是否不高于 VERSION。 |
pkg-config --exists 'libxml2 <= 2.9.10' |
--uninstalled |
检查是否使用"未安装"版本的库(即 .pc 文件名为 库名-uninstalled.pc)。 |
pkg-config --uninstalled glib-2.0 → 存在则退出码 0 |
3.5 其他实用选项
| 选项 | 功能描述 | 示例 |
|---|---|---|
--list-all |
列出所有可找到的库(.pc 文件对应的库名及简要描述)。 |
`pkg-config --list-all |
--print-provides |
列出指定库"提供"的模块(.pc 文件中 Name 或 Provides 字段)。 |
pkg-config --print-provides glib-2.0 → glib-2.0 = 2.64.6 |
--print-requires |
列出指定库的公开依赖 (.pc 文件中 Requires 字段)。 |
pkg-config --print-requires gtk+-3.0 → gdk-3.0、pango-1.0 等 |
--print-requires-private |
列出指定库的私有依赖 (.pc 文件中 Requires.private 字段,静态链接需包含)。 |
pkg-config --print-requires-private glib-2.0 → libpcre >= 8.31 |
--msvc-syntax |
Windows 特有,输出 MSVC 编译器识别的语法(如 /libpath: 替代 -L,.lib 替代 -l)。 |
pkg-config --msvc-syntax --libs glib-2.0 → /libpath:C:\gtk\lib glib-2.0.lib |
四、环境变量
pkg-config 行为可通过环境变量调整,常用变量如下:
| 环境变量 | 功能描述 | 示例 |
|---|---|---|
PKG_CONFIG_PATH |
自定义 .pc 文件搜索路径(冒号分隔,优先级高于默认路径)。 |
export PKG_CONFIG_PATH=/opt/lib/pkgconfig:$PKG_CONFIG_PATH |
PKG_CONFIG_SYSROOT_DIR |
交叉编译时指定"系统根目录",自动将 .pc 文件中的 -I/-L 路径前缀替换为该目录。 |
export PKG_CONFIG_SYSROOT_DIR=/arm-linux-gnueabihf/sysroot |
PKG_CONFIG_LIBDIR |
替换默认的 .pc 文件搜索目录(覆盖 /usr/lib/pkgconfig 等)。 |
export PKG_CONFIG_LIBDIR=/opt/lib/pkgconfig |
PKG_CONFIG_DEBUG_SPEW |
启用调试模式(等价于 --debug,且强制 --print-errors)。 |
export PKG_CONFIG_DEBUG_SPEW=1 → 执行 pkg-config --libs glib-2.0 输出调试信息 |
PKG_CONFIG_DISABLE_UNINSTALLED |
禁用"未安装"版本的库(即不优先选择 库名-uninstalled.pc)。 |
export PKG_CONFIG_DISABLE_UNINSTALLED=1 |
五、.pc 元数据文件语法
pkg-config 的核心是 .pc 文件,其语法简洁,包含变量定义 和关键字字段 两类内容,以下是典型示例(glib-2.0.pc):
ini
# 注释:以 # 开头
prefix=/usr # 变量定义:安装前缀
exec_prefix=${prefix} # 变量引用:${变量名}
libdir=${exec_prefix}/lib/x86_64-linux-gnu
includedir=${prefix}/include
includedir_glib=${includedir}/glib-2.0
includedir_lib=${libdir}/glib-2.0/include
Name: GLib # 库的可读名称
Description: C utility library (core functions) # 库的简要描述
Version: 2.64.6 # 库版本号
URL: https://developer.gnome.org/glib/ # 库的官方URL
Requires: libpcre >= 8.31 # 公开依赖(编译/链接时需包含)
Requires.private: m, pthread # 私有依赖(仅静态链接需包含)
Conflicts: glib-1.2 <= 1.2.10 # 冲突的库版本(避免同时使用)
Libs: -L${libdir} -lglib-2.0 # 动态链接选项
Libs.private: -lm -lpthread # 静态链接私有选项
Cflags: -I${includedir_glib} -I${includedir_lib} # 编译选项
关键关键字字段说明
| 字段 | 作用 |
|---|---|
Name |
库的人类可读名称(非命令行查询的库名)。 |
Version |
库的精确版本号(支持 --modversion 和版本检查)。 |
Requires |
依赖的其他库(公开,--cflags/--libs 会自动包含这些库的参数)。 |
Requires.private |
依赖的其他库(私有,仅 --static 时包含,动态链接无需)。 |
Libs |
动态链接所需的选项(-L 路径、-l 库名等)。 |
Libs.private |
静态链接所需的私有选项(如系统库 -lm、-pthread)。 |
Cflags |
编译所需的选项(-I 头文件路径、-D 宏定义等)。 |
Conflicts |
冲突的库版本(若存在冲突版本,pkg-config 会报错)。 |
六、Autoconf 宏(自动化构建集成)
在 configure.ac 中可通过 Autoconf 宏集成 pkg-config,常用宏如下:
6.1 PKG_PROG_PKG_CONFIG([MIN-VERSION])
-
作用 :检查系统是否安装
pkg-config,并确保版本不低于MIN-VERSION(可选)。 -
示例 :
autoconfPKG_PROG_PKG_CONFIG(0.29) # 要求 pkg-config 版本≥0.29
6.2 PKG_CHECK_MODULES(VAR-PREFIX, MODULES [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
-
作用 :检查指定库是否存在及版本是否满足,生成
VAR-PREFIX_CFLAGS和VAR-PREFIX_LIBS变量供后续使用。 -
参数 :
VAR-PREFIX:变量前缀(如GLIB会生成GLIB_CFLAGS/GLIB_LIBS);MODULES:库名及版本约束(如glib-2.0 >= 2.64 gtk+-3.0);ACTION-IF-FOUND:找到库时执行的操作(可选);ACTION-IF-NOT-FOUND:未找到库时执行的操作(可选,默认终止 configure)。
-
示例 :
autoconfPKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.64], [AC_MSG_OK([Found GLIB: $GLIB_VERSION])], [AC_MSG_ERROR([GLIB >= 2.64 is required])] )生成的
GLIB_CFLAGS和GLIB_LIBS可在 Makefile.in 中引用:makefileprogram_CFLAGS = $(GLIB_CFLAGS) program_LDADD = $(GLIB_LIBS)
6.3 PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-
作用:仅检查库是否存在,不生成变量(适合简单判断)。
-
示例 :
autoconfPKG_CHECK_EXISTS([gtk+-3.0], [AC_DEFINE(HAVE_GTK, 1, [GTK+ 3.0 is available])], [AC_MSG_WARN([GTK+ 3.0 not found, disabling GUI support])] )
七、使用示例
示例 1:在 Makefile 中编译链接程序
假设编译一个依赖 glib-2.0 的程序 hello.c,Makefile 可写为:
makefile
CC = gcc
CFLAGS = -Wall $(pkg-config --cflags glib-2.0) # 自动获取编译选项
LDFLAGS = $(pkg-config --libs glib-2.0) # 自动获取链接选项
hello: hello.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
clean:
rm -f hello
示例 2:检查库是否存在及版本
在 shell 脚本中判断 gtk+-3.0 是否存在且版本≥3.24:
bash
if pkg-config --exists 'gtk+-3.0 >= 3.24'; then
echo "GTK+ 3.24+ is available"
else
echo "GTK+ 3.24+ is required"
exit 1
fi
示例 3:交叉编译时指定系统根目录
为 ARM 架构交叉编译,指定 sysroot 并获取 glib-2.0 的选项:
bash
export PKG_CONFIG_SYSROOT_DIR=/opt/arm-linux-gnueabihf/sysroot
export PKG_CONFIG_LIBDIR=$PKG_CONFIG_SYSROOT_DIR/usr/lib/pkgconfig
# 获取交叉编译的编译/链接选项
ARM_CFLAGS=$(pkg-config --cflags glib-2.0)
ARM_LIBS=$(pkg-config --libs glib-2.0)
# 用 ARM 编译器编译
arm-linux-gnueabihf-gcc -o hello_arm hello.c $ARM_CFLAGS $ARM_LIBS
示例 4:查询 .pc 文件变量
获取 gtk+-3.0 的安装前缀和头文件路径:
bash
pkg-config --variable=prefix gtk+-3.0 # 输出:/usr
pkg-config --variable=includedir gtk+-3.0 # 输出:/usr/include/gtk-3.0
八、注意事项与 BUGS
- .pc 文件路径问题 :若
pkg-config找不到库,首先检查PKG_CONFIG_PATH是否包含.pc文件所在目录,或手动指定路径(如export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig)。 - 版本约束语法 :版本约束需用引号包裹(如
'glib-2.0 >= 2.64'),避免 shell 解析空格。 - 静态链接依赖 :静态链接时必须加
--static选项,否则可能遗漏Libs.private中的私有依赖库(如-lm)。 - Windows 语法差异 :Windows 下
PKG_CONFIG_PATH用分号分隔,--msvc-syntax选项可适配 MSVC 编译器。 - 已知 BUG :混合使用"带
="和"不带="的版本约束(如glib-2.0 >=2.64 libxml2=2.9.10)可能出错,建议统一格式。