pkg-config指南

原文:

Guideforpkg-config

~dbn/pkg-config-guide.html

DanNicholson

—————————————————–

概述

为什么?

一些概念

写pkg-config文件

使用pkg-config文件

常见问题

———————————————–

概述

这个文档的目的是从用户和开发者的角度给一个pkg-config工具的使用概述。本文复习一些pkg-config背后的概念,怎样写pkg-config文件来支持你的项目,以及怎样用pkg-config集成第三方项目。

关于pkg-config的更多信息可以在web站点和pkg-config的man手册中找到。

本文档假的pkg-config在类UNIX操作系统中使用,例如Linux。其他平台可能在一些细节上的存在差别。

为什么?

现代计算机系统使用了很多分层组件为用户提供应用。其中一个困难就是如何正确的整合这些组件。pkg-config会收集系统中安装的库的数据,然后提供给用户。

如果没有pkg-config这样的数据系统,定位计算机提供的服务和获取它们的细节会很困难。对于开发者,安装软件包的pkg-config文件极大的简化了对API的获取。

一些概念

使用pkg-config的初级阶段是为编译和链接程序时提供必要的细节。数据存储在pkg-config文件中。这些文件有一个.pc的后缀,放在一个特定的、pkg-config工具所知道的位置。我们会在后面描述更多的细节。

这个文件的格式包括预定义的关键字和自由形式的变量。例如:

[plain]

以预定义关键字Name:为例,以关键字开头,后面跟一个冒号和一个值。变量是一个字符串和一个值,例如prefix=,用等号分开。关键字是由pkg-config定义和输出的。变量不是必须的,但可以被关键字用来定位和存储pkg-config没有覆盖的数据。

这里只是简单的描述一下关键字。更深入的描述和怎样有效的使用它们将在“写pkg-config文件”段中给出。

Name:一个人们可读的链接库或软件包的名称,这不影响pkg-config的使用,它用的是.pc文件的名称。

Description:关于软件包的简单描述。

URL:一个URL,可以在那里获得更多的信息,并且下载这个软件包。

Version:软件包的版本。

Requires:这个软件包所需的包的列表。这些包的版本可能用一写运算符来指定:=、>、<、>=、<=。

Requires.private:这个软件包所需的私有包的列表,不会暴露给应用。版本的指定规则与Requires相同。

Conflicts:可选,描述了会与这个软件包产生冲突的包。版本的指定规则与Requires相同。这个域会提供同一个包的多个实例,例如:Conflicts:bar<1.2.3,bar>=1.3.0。

Cflags:为这个软件包指定编译器选项,以及pkg-config不支持的必要的库。如果所需的库支持pkg-config,应该将它们添加到Requires和Requires.private。

Libs:为这个软件包指定的链接选项,以及pkg-config不支持的必要的库。与Cflags的规则相同。

Libs.private:这个软件包所需的私有库的链接选项,不会暴露给应用。规则与Cflags相同。

写pkg-config文件

为一个软件包创建pkg-config时,首先要确定怎样描述它。一个文件最好只用于描述一个库,所以,每个软件包至少需要像它所需的链接库那么多的pkg-config文件。

软件包的名字是由pkg-config数据文件的名字确定的。就是文件名去掉.pc后缀的那一部分。通常都用库的名字命名.pc文件。例如,一个安装libfoo.so的包会有一个相应的libfoo.c文件来包含pkg-config数据。这不是必须的,.pc文件仅仅是一个对你的库的唯一标识符。所以,foo.pc或foolib.pc也能正常工作。

Name、Description和URL的值是纯粹的信息,容易填写。Version比较棘手,它要确保这个包可以被用户使用。pkg-config使用RPM算法来进行版本比较。Version最好是用点分开的十进制数字,例如1.2.3,因为字母可能引起意外的结果。数字应该是单调递增的,并且要竟可能具体的描述这个库。通常使用包的版本号即可,这样可以方便使用者跟踪。

在描述更多的有用的关键字之前,有必要展示一下变量的定义。最常见的用法是定义安装路径,这样就不会使其他字段显得杂乱。因为变量是扩大递归的,在结合autoconf派生路径时,这会很有用。

[plain]

最重要的pkg-config数据字段是Requires,Requires.private,Cflags,Libs和Libs.private。它们定义的数据被外部项目用来编译和链接库。

Requires和Requires.private定义了库所需的其他模块。通常首选Requires.private,以便避免程序链接到一些不必要的库。如果一个程序不使用所需库的符号,它就不应该直接链接到这个库。可以在overlinking的讨论中看到更多详细的解释。

由于pkg-config通常会公开Requires库的链接标识,这些模块会变成程序的直接依赖。另外,Requires.private中的库只有在静态链接是才会被包含。正因如此,pkg-config通常只会适当的从Requires中的同一个包中添加模块。

Libs包含了使用库是所必须的链接标识。此外,Libs和Libs.private还包含了pkg-config不支持的库的链接标识。与Requires类似,首选将外部库的链接标识添加到Libs.private,这样,程序就不会获得额外的直接依赖。

最后,Cflags包含了所用的库的编译标识。与Libs不同,Cflags没有私有变种。这是因为,数据类型和宏定义在任何链接情况下都是需要的。

使用pkg-config文件

假设系统中已经安装了.pc文件,pkg-config工具就被用来提取其中的数据。执行pkg-config–help命令可以看到一些关于命令选项的简单描述。深入的描述可以在pkg-config(1)的man手册页中找到。本地将对一些常见的用法进行简单的描述。

假设系统中已经有了两个模块:foo和bar。它们的.pc文件可能像下面这样:

[plain]

模块的版本可以用–modversion选项获得。

[python]

要打印模块的链接标识,就用–libs选项。

比天才难得,许多天赋差的人经过过勤学苦练也取得了很大的成功。

pkg-config指南

相关文章:

你感兴趣的文章:

标签云: