为什么要使用pkg-config

编译/链接时库的搜索

一般来说, 在编译链接时:

  • 如果库的头文件不在标准目录下, 需要用-I选项指定头文件的包含路径;
  • 如果库文件不在标准目录下, 需要使用-L选项指定库文件的链接路径.

由于同一个库在不同系统上可能位于不同的路径, 用户在安装库的时候也可以安装在不同的路径; 所以即便使用同一个库, 由于库的路径不同, 用于指定头文件路径的-I选项也不同, 其结果就是造成了编译命令的不统一. 使用-L选项指定库的链接路径时, 也会有同样的问题. 此外我们使用的这个库, 可能还会依赖其他的库, 在手动编译链接时, 还需要在参数中列出这些间接依赖的库, 这样就增加了使用的复杂度.

为了解决编译/链接时的这个问题, 人们找到了一个解决办法, 其基本思想就是:

事先把库的位置信息等保存起来, 需要使用时通过特定的工具将其中有用的信息提取出来供编译和链接使用, 这样就可以做到编译和链接时参数的一致性. 目前最常用的库信息提取工具就是pkg-config; pkg-config通过库提供的一个.pc文件获得该库的各种必要信息, 包括版本信息, 编译和链接参数等, 这些信息可以通过pkg-config提供的参数单独提取出来直接供编译器和链接器使用.

使用 pkg-config 工具提取库的编译/链接参数有两个基本前提:

  • 库本身在安装时必须提供一个相应的 .pc 文件(必须以 .pc 作为文件名后缀);
  • pkg-config 必须知道到哪里去寻找此 .pc 文件, 将 .pc 文件安装到 pkg-config 的标准搜索路径(/usr/lib/pkgconfig, /usr/share/pkgconfig, /usr/local/lib/pkgconfig and /usr/local/shared/pkgconfig)下, 或将路径添加到环境变量 PKG_CONFIG_PATH 中去;

运行时动态链接库的搜索

程序在编译/链接时需要链接库(静态或动态库); 如果程序中使用的是动态链接库, 程序运行时需要加载/链接动态库.

如果动态库在默认搜索路径下, 则不需要显式的指定其链接路径; 如果动态链接库不在默认的搜索路径下, 则需要显式的指定其路径.

有两种方式可用于在程序运行时指定动态链接库的搜索路径:

  • 在环境变量LD_LIBRARY_PATH中添加动态库的搜索路径;
  • /etc/ld.so.conf中添加库的搜索路径(需要重启或执行/sbin/ldconfig命令以更新/etc/ld.so.cache文件).

将可能存放库文件的路径添加到 /etc/ld.so.conf 中是明智的选择, 添加的方法也很简单, 将库文件所在目录的绝对路径直接写进去就ok了, 一行一个; 但有时这种方式会有问题, 例如安装了某个库的最新版本并将库所在的路径添加到 /etc/ld.so.conf 文件中, 这时系统中的所有程序使用的都是该库的最新版本; 而因为兼容性问题, 可能有的程序使用该库的最新版本会有问题, 这时可以使用环境变量LD_LIBRARY_PATH来指定要链接的指定版本的库的路径.