Available Languages: | Deutsch | English | Français | 日本語 (Nihongo) | 中文 (简) (Simplified Chinese) |

创建 Fink 软件包

本手册记录如何创建 Fink 软件包管理的软件包描述文件。 它还提供关于 Fink 发布的一些规则和指引。 描述文件格式和发布规则都在不断完善中,所以请查看"最后修改"信息和 CVS 标记来检查是否更新。 你现在阅读的是用于 fink 0.9.0 开发版软件包管理器之后的描述文件和规则。

如果你打算为 Fink 创建软件包,你可以订阅 fink-devel 邮件列表。 如果你希望帮助 Fink 项目,而你在这方面又有专长,你可以考虑选择接受一个 尚未有维护人员的软件包。

Contents

1 介绍

1.1 什么是软件包?

软件包是一个以原子状态(也就是说,它不可以被分割成更细小的可独立存在软件)存在的一个软件。 典型的软件包包括一个可执行的程序,必须的数据文件,供国际化和文档使用的消息目录。 在 Fink 中,软件包有两种形式:软件包描述文件和可安装二进制软件包文件。

软件包描述文件是一个可阅读的纯文本文件,它包括了构建一个软件包(即,创建二进制软件包文件)所需要的全部信息。 信息包括:元数据(比如软件包的名字,它的作用等),源代码的下载网址和应该如果配置,编译,封装软件包的指引。 描述文件可以还会附有一个补丁文件。

二进制软件包文件是一个构成软件包的实际文件的压缩档。这些实际文件包括可执行程序,数据文件,信息目录,函数库,头文件等等。 这种软件包问题还会包括软件包的一些元数据。 安装一个二进制软件包的过程主要就是解压缩而已,因为它实际上已经出于立刻可以使用的状态了。 由于 Fink 构建在 dpkg 软件包管理器上,二进制软件包文件采用 dpkg 的文件格式并具有 .deb 的扩展名。

1.2 识别一个软件包

一个软件包由三个字串来标识:软件包名,版本号和修订版号。 他们均由小写字母(a-z),数字(0-9),减号(-; note: not allowed in the revision),加号(+)以及句点(.)组成。不允许使用其它的字符。 特别地,不能使用大写字母和下划线。

软件包名就是软件的名称,例如:openssh。 版本号,也称为上游版本号,是原始软件包的版本标识号。 在版本号中可以使用字母,例如:2.9p1。 fink 和 dpkg 都知道如何正确地给它们排序。 修订版号是一个递增的反映软件包描述被修改的计数。 它从 1 开始递增,让上游版本号发生改变以后,又回到 1 重新开始。 修订版号不可以包括减号。 完整的软件包名称是它们三项的连接,中间用减号分隔,例如:openssh-2.9p1-2。

2 软件包描述文件

2.1 文件树结构

软件包描述文件保存在 /opt/sw/fink/dists 目录树内的 finkinfo 目录中。 /opt/sw/etc/fink.conf 中的 "Trees" 设置控制会控制应该读取那个目录。 软件包描述文件的名字必须要软件包全名加上 ".info" 扩展名组成。 从 fink 0.13.0 开始,为了简化软件包的升级,也可以允许简单地使用软件包加 ".info" 来组成。 As of fink 0.26.0, there are several different ways to specify the filename: it is recommended to use the shortest version which is consistent with other needed package files. The filename takes the form: the invariant packagename, optionally followed by the architecture, optionally followed by the distribution, optionally followed by either version or version-revision, each delimited by hyphens, concluding with ".info". The "architecture" and "distribution" components are only allowed if the corresponding field is present in the package, and if it specifies exactly one value.

到软件包描述文件的目录树由几层目录组成。 自上而下顺序为:

2.2 文件格式

描述文件只是键-值对的简单列表,一个键-值对有时也称为一个“字段”。 每一行由一个以冒号(:)为结束的键开始,然后跟着是相对应的值,就象这样:

Key: Value

当你需要把一个分成几行书写的时候,可以有两种标记办法。

推荐的方式是通常用于在 shell 脚本 here-document 语法。这种方法第一行是键,然后跟着以 << 为它的取值。 在这之后,在下一个 << 之前的所有行会被视作实际的取值。 下面是一个例子:

InstallScript: <<
mkdir -p %i/share/man
make install prefix=%i mandir=%i/share/man
mkdir -p %i/share/doc/%n
install -m 644 COPYING %i/share/doc/%n
<<

在这种格式下,缩进是可选的,但它可以改进可阅读性。

这种 here-document 语法格式可以嵌套使用。这通常使用于 SplitOffSplitOffN 字段。 这些字段包含其它字段(多行),因此通过这种语法可以使得子字段也可以具有多行。在子的 here-document 块中同样使用的 << 作为终结符。 下面是一个例子:

SplitOff: <<
  Package: %N-shlibs
  InstallScript: <<
    ln -s %p/lib/libfoo.2.dylib %i/lib/libfoo.%v.dylib
  <<
<<

另外一种旧的,已经过时的标记方法是参照 RFC 822 数据包头的分行方式。 以空白字符开始的行会被当作上一行的继续。 例子:

InstallScript: mkdir -p %i/share/man
 make install prefix=%i mandir=%i/share/man
 mkdir -p %i/share/doc/%n
 install -m 644 COPYING %i/share/doc/%n

注意上面续行中强制要求的缩进格式。

在两种格式中,空行或以井号(#)打头的行都会被忽略。 键(字段名)在 Fink 中是区分大小写的,你可以随便使用 InstallScriptinstallscriptINSTALLSCRIPT。 不过,建议使用首字母大写的方式以方便阅读。 对于那些使用布尔值的字段-"true","yes","on","1"(不区分大小写),都会被认为是真值,而其它的值则会被认为是假值。

2.3 百分号展开

为了简化一些书写,Fink 在一些字段中支持一套展开(替换)规则。 为了避免含混,你可以使用大括号来指明确切是那些字母需要作为百分号展开。 例如,%{n}%n 的含义是一样的。 目前支持的展开包括:

%n

当前软件包的名字(name)

%N

父软件包的名字(Name),除非在 SplitOff 中,否则应该和 %n 相同

注意:如果父 Package 字段包含 %type_*[],那些百分号扩展的值被包括在 SplitOff 块的 %N 中(因为它们被包括在父字段的 %n 中)。

%e

软件包的额外版本标识(epoch)。它主要用于强行替代版本号的顺序,比方说你现在已经有一个 2.0Beta1 版,然后现在 2.0 版出来了,显然 2.0 版应该是一个更新的版本。但是 字符串比较的结果却是 2.0Beta1 < 2.0。所以,要么你只能把 2.0 命名为 2.0Final,要么你使用 epoch 来强行制定版本的先后顺序。比方说:epcho 1, version 1.0 是一个比 epcho 0, version 2.0 更新的版本。

%v

软件包的版本号(version)

%V

the full package Version, which automatically includes the Epoch if present. Note that this percent expansion is only available for packages whose InfoN level is at least 4.

%r

软件包的修订版号(revision)

%f

完整的(full)软件包名,即 %n-%v-%r. Note that the Epoch is not part of %f.

%p, %P

the prefix where Fink is installed, e.g. /opt/sw. You must not assume all users have Fink installed in /opt/sw; use %p to ge the correct path.

%d

要打包的全套文件将被构建于的目标(destination)目录,例如: /opt/sw/src/fink.build/root-gimp-1.2.1-1。 这个临时目录在编译过程的安装阶段将作为根目录位置。 你不应该假设 root-%f 会在 %p/src 中,因为用户可以通过 /opt/sw/etc/fink.conf 文件中的 Buildpath 字段来改变它的位置。

%D

父文件包的目标(Destination)目录(除非是在 SplitOff 中,否则和 %d 相同)

%i

安装态(install-phase)的完整路径前缀,等于 %d%p。安装态是指从源代码编译安装到临时位置后的状态,然后我们需要把它封装成 .deb 包。

%I

父软件包的安装(Install)态路径前缀,等于 %D%P(除非是 SplitOff 中,否则应该和 %i 相等)

%a

补丁(patches)程序所在的路径

%b

构建(build)过程所在的目录,例如:/opt/sw/src/fink.build/gimp-1.2.1-1/gimp-1.2.1。 你不应该假设 %f 一定在 %p/src 中,因为用户可以通过 /opt/sw/etc/fink.conf 文件中的 Buildpath 字段来改变它。 最内部的目录根据 Source 文件名来命名,或是 SourceDirectory 字段(如果存在的话)的值,或在 NoSourceDirectorytrue 的时候不使用它。

注意:仅在没有其它选择的情况下才使用它。构建目录是脚本运行的当前目录;在命令中你应该使用相对路径。

%c

configure 命令将使用的参数:--prefix=%p 加上 ConfigureParams 指定的其它参数。 (The behavior is different when the package has Type: perl; in that case, the default flags for building a perl package are used instead of --prefix=%p in the definition of %c.)

%m

机器(machine)体系架构类型字符串,这和 uname -p 的输出一致。目前 'powerpc' 代表 ppc 类的计算机,'i386' 代表 x86 类(在 0.12.1 之后的一个 CVS 版本开始引入)

%%

百分号字符(它部分展开后面跟着它的东西)。展开严格按照从左到右的顺序进行,所以 %%n 和软件包名没有关系,而只是字符串 %n。(从 fink-0.18.0 开始引入)

%type_raw[类型], %type_pkg[类型], %type_num[类型]

对给定类型返回的代表子类型的伪哈希值。 查阅本文档后面关于 Type 字段的内容。 _raw 形式表明使用子类型字符串的精确形式, _pkg 形式表明使用去除句点之后的形式(就好象 Fink 的语言版本软件包的命名约定一样)。(在 fink 的 CVS 0.19.2 后版本中引入)。 The _num form was introduced in fink-0.26.0 and removes all non-digits from the Type field.

%{ni}, %{Ni}

软件包的固定名称(name invariant)部分。 它们和 %n 和 %N 类似,除了所有 %type_pkg[] 和 %type_raw[] 被去掉。 (在 fink 的 CVS 0.19.2 后版本中引入)。 你应该使用 %{ni} 和 %{Ni} 以避免与 %n 和 %N 扩展相混淆。

%{default_script}

Valid only in PatchScript, CompileScript, and InstallScript fields, the default contents of that type of field. The value is often dependent on the Type field, and is always defined (though it may be blank). When used in the InstallScript of a SplitOff (or SplitOffN), this expansion will yield the parent's default, even though the default for InstallScript in a SplitOff package is blank. (Introduced in fink-0.20.6)

%{PatchFile}

The full path to the file given in the PatchFile field. (Introduced in fink-0.24.12)

%lib

If Type: -64bit is defined to be -64bit, this expands to lib/ppc64 on powerpc machines, and to lib/x86_64 on intel machines (the proper storage locations for 64-bit libraries); otherwise, this expands to lib. (Introduced in fink-0.26.0)

Note that %lib is not permitted in the ConfigureParams field unless the InfoN level is at least 4.

3 打包相关规则

3.1 软件包授权协议

Fink 中包括的软件包包括很广范围的授权协议种类。 多数都对重新发布全部源代码有限制,尤其对发布二进制版本有限制。 有些软件包因为这些授权协议而不能提供二进制发行版。因此,很重要的一点是软件包的维护者需要仔细地检查他们维护的软件包的授权协议限制。

每个以二进制包形式发布的软件都必须包含一些授权协议。 它必须被安装在 doc 目录, 也就是说:%p/share/doc/%n。 (当然,在 InstallScript 中,应该用 %i 代替 %p。DocFiles 字段会自动处理这些细节。) 如果在原始的程序中没有明确的授权协议声明,那个包含一小段文字来说明这个软件包的状态。 多数的授权协议要求在发布版中包括一份授权协议。 Fink 的规则要求总是这么做,即使软件本身没有明确要求。

为了使得二进制发行版的维护可以自动化,所有准备发布的软件包都必须有一个 License 字段。 这个字段表明授权协议的性质,并被用于决定是否为它制作二进制发行版。 按照前面解释的原因,只有在实际的授权协议条文被放进二进制包中,这个字段才会起作用。

要使得 License 字段有用,必须使用下面之一的预定义值。 如果你在打包的程序并不适合下面中的一种,请在开发者邮件列表中要求帮助。

3.2 The GPL and OpenSSL

(Policy change effective April, 2005.)

Due to the apparent incompatibilty of the OpenSSL license with the GPL and LGPL licenses, fink packages which link to openssl but are licensed under the GPL or LGPL are marked as "Restrictive." As a consequence, the Fink project will not distribute binaries of such packages, although users are free to compile them from source at their discretion.

Package maintainers are encouraged to record the original package license in the DescPackaging field.

3.3 避免干扰基本系统

Fink 是一个安装在基本系统之外的独立目录里面的外加的软件系统。 保证不要把文件安装到 Fink 的目录之外对一个软件包来说是非常重要的。

唯一的例外是没有其它的选择的情况下,比如:XFree86。 这种情况下,软件包必须在安装前检查现有的文件,如果发现可能要覆盖现有的文件,它应该拒绝安装。 软件包必须要保证它安装在 Fink 目录之外的文件要能够在删除软件包的时候同时被删除。或者留在那里保证不会造成危害(就是说,他们需要在调用它之前检查它是否在那里)。

3.4 共享函数库

Fink 对于共享库有了新的规则,它从 2002 年 2 月开始生效。 本段内容讨论的是规则的第四版,它是与 Fink's 0.5.0 一同发布的 as modified in December, 2006 to handle 64bit libraries and from January, 2008 to handle private shared libraries. (In addition, the discussion was updated in June, 2008 to eliminate obsolete references to a transitional period for implementing the shared libraries policy.) We begin with a quick summary, and then discuss things in more detail. 我们首先以一个简要的概括开始,然后讨论更多的细节问题。

任何会产生共享库的软件包,都应该使得他们的库满足 Fink 的规则。即:

Note that a package may also install private shared libraries, which are not intended to be linked from any other package. In this case, the libraries need not go into a separate package, but a Shlibs field must still be part of the package containing shared libraries. Also, maintainers should try to avoid storing a final link from libfoo.dylib in the main library directory %i/lib (or its 64-bit equivalent), to prevent other programs from accidentally linking to this library.

如果某个维护者因为某个原因而不能遵循这个规则,没有分离软件包的话,应该在 DescPackaging 字段中说明原因。

对于一些软件,可以通过一个主软件包和一个 -shlibs 软件包来组成;另外的一些情况下,你还需要第三个软件包。新的 SplitOff 字段正是为了简化这种情况。

当需要第三个软件包的时候,有两种不同的命名办法,取决于共享库是软件包的主要功能(情况一),还是可执行程序是主要功能(情况二)。对于第一种情况,使用下面的命名模式:

PackageContents
foo-shlibs

共享库

foo

头文件

foo-bin

二进制执行文件,等等

对于第二种情况,使用下面的命名模式:

PackageContents
foo-shlibs

共享库

foo-dev

头文件

foo

二进制执行文件,等等

规则细节

我们现在讨论更多的细节。我们使用 libpng,libjpeg 和 libtiff 软件包作为规则的实际例子。

已经移植到 Darwin 的软件应该尽可能编译共享库(当然,根据软件包的实际需要,维护者也可以选择编译静态库;如果他们愿意的话,也可以只提交包含静态库的版本)。 当编译共享库的时候 ,应该创建两个密切相关的 fink 软件包,分别名为 foo 和 foo-shlibs。共享库放到 foo-shlibs 中,而头文件在放到 foo 中。这两个软件包可以用同一个 .info 文件产生,象下面描述的那样,使用 SplitOff 字段(事实上,通常需要从源程序中编译出不止两个软件包,这时可以使用 SplitOff2SplitOff3…,等等)

Each software package for which public shared libraries are built must have a major version number N, which is included in the shared library's filename (for example, libbar.N.dylib). 当共享库的 API 不再后向兼容以后,才会去改变主版本号。Fink 使用下面的命名约定:如果上游的软件包叫做 bar,那么 fink 软件称为 barN 和 barN-shlibs(只有在新软件包或主版本号发生改变的软件包上,才会严格应用这个规则)。例如,现存的 libpng 软件包的主版本号是 3,但当前版本的库的主版本号是 3。所以现在有四个软件包:libpng, libpng-shlibs, libpng3, libpng3-shlibs。 在 libpng 和 libpng3 之间只能同时安装一个,但 libpng-shlibs 和 libpng3-shlibs 则可以同时安装。 (注意创建这四个软件包只需要两个 .info 文件)

共享库本身和一些相关文件会被放到 barN-shlibs 软件包中;头文件和一些其它文件会被放到 barN 的软件包。两个软件包中间没有相同的文件,放在 barN-shlibs 的文件的路径应该包含主版本号 N。多数情况下,你的软件包在运行时需要的文件原本时安装到 %i/lib/bar/%i/share/bar/ 目录中;你应该把安装路径调整到 %i/lib/bar/N/%i/share/bar/N/

所有依赖于主版本号为 N 的 bar 软件包的其它软件,需要使用依赖关系

  Depends: barN-shlibs
  BuildDepends: barN

It is not be permitted for another package to depend on barN itself. (Although there may still be a few such dependencies involving packages which were in place prior to February, 2002.) This is signaled to other developers by a boolean field

  BuildDependsOnly: True

来告诉其它开发者。

如果你的软件包包括共享库和二进制文件,而且二进制文件需要在运行时使用(而不仅仅时编译时),那么这些二进制文件应该被分离到第三个软件包中,这个软件包命名为 barN-bin。其它软件包可以依赖于 barN-shlibs 及 barN-bin。

当编译主版本号为 N 的共享库时,很重要的是要使 %p/lib/libbar.N.dylib 来作为 "install_name"。(你可以用 otool -L 或 otool64 -L for 64bit libraries 来查看你的库的 install_name)。实际的库文件应该被安装在

  %i/lib/bar.N.x.y.dylib

而你的软件包应该创建符号链接

  %i/lib/libbar.N.dylib -> %p/lib/libbar.N.x.y.dylib
  %i/lib/libbar.dylib -> %p/lib/libbar.N.x.y.dylib

from the install_name path and from the linking path to the actual library. (The first will not be needed if the library is in fact installed at the install_name path, which is becoming more common.)

如果还构建了静态库,那么它应该被安装在

  %i/lib/libbar.a

如果软件包使用 libtool,这些事情通常会被自动处理, 但无论任何情况下,你都应该检查结果时候正确。你还应该检查你的共享库是否已经定义了正确的 current_version 和 compatibility_version 值( otool -Lotool64 -L for 64bit libraries 应该也可以查询得到这些设置值)。

文件应该象下面一样分到两个文件包中

注意两个文件包都需要一些关于授权协议的文档,但包括文档文件的目录是不同的。

在实践中使用它是很容易的,这可以使用 SplitOff 字段。下面是关于如何实现上面情况的例子(部分):

Package: barN
Version: N.x.y
Revision: 1
License: GPL
Depends: barN-shlibs (= %v-%r)
BuildDependsOnly: True
DocFiles: COPYING
SplitOff: <<
  Package: barN-shlibs
  Files: lib/libbar.N.x.y.dylib lib/libbar.N.dylib lib/bar/N
  DocFiles: COPYING
<<

SplitOff 字段执行的时候,有关的文件和目录会被从主文件包的 %I 安装目录移动到剥离的文件包的 %i 目录(对于名字同样有类似的约定:%N 是主软件包的名字,%n 是当前软件包的名字)。 DocFiles 命令然后会把一份文档放到 %i/share/doc/barN-shlibs 中。

注意我们已经把当前版本的 barN-shlibs 包含为主软件包 barN( %N-shlibs (= %v-%r) 的缩写)的依赖关系。 这可以确保版本会匹配,而且保证 barN 自动继承 "inherits" barN-shlibs 的所有依赖关系。

The BuildDependsOnly field

When libraries are being upgraded over time, it is often necessary to have two versions of the header files available during a transition period, with one version used for compiling some things and the other version used for compiling others. For this reason, the packages containing header files must be constructed with some care. If both foo-dev and bar-dev contain overlapping headers, then foo-dev should declare

  Conflicts: bar-dev
  Replaces: bar-dev

and similarly bar-dev declares Conflicts/Replaces on foo-dev.

In addition, both packages should declare

  BuildDependsOnly: True

This inhibits others from writing packages which depend on foo-dev or bar-dev, since any such dependency will prevent the smooth operation of the Conflicts/Replaces method.

There are some packages containing header files for which it's not appropriate to declare BuildDependsOnly to be true. In that case, the package should declare

  BuildDependsOnly: False

and the reason must be given in the DescPackaging field.

The BuildDependsOnly field should only be mentioned in the package's .info file if the package contains header files, installed into /opt/sw/include.

As of fink 0.20.5, "fink validate" will issue a warning for any .deb which contains header files and at least one dylib, and does not declare BuildDependsOnly to be either true or false. (It is possible that in future versions of fink, this warning will be expanded to cover the case of a .deb with header files and a static library as well.)

The goal of the Shared Library Policy is to allow assure compatibility between libraries supplied by one package and libraries or programs that use them in a different package. Some packages may have shared libraries that are not designed to be used by other packages. Common situations include a suite of programs that come with a back-end library of utility functions or a program that comes with plugins to handle various features. Because these libraries are "private" to the package that has them, they do not require being packaged with separate -shlibs or BuildDependsOnly SplitOffs.

Shlibs 字段:

除了把共享库放到合适的软件包中外,作为规则版本 4,你还需要用 Shlibs 字段声明全部共享库。 This field has one line for each shared library, which contains the -install_name of the library. If the library is public, its Shlibs entry also lists the -compatibility_version, versioned dependency information specifying the Fink package which provides this library at this compatibility version, and the library architecture. (The library architecture may either be "32", "64", or "32-64", and may be absent; the value defaults to "32" if it is absent.) 依赖关系应该用 foo (>= version-revision) 的形式指明。其中 version-revision 指提供这个与(本版本兼容)的共享库的 Fink 软件包的第一个版本。例如,这样

  Shlibs: <<
    %p/lib/libbar.1.dylib 2.1.0 bar1 (>= 1.1-2) 32
  <<

一个声明表示从 bar1 软件包的版本 1.1-2 开始,已经开始安装一个 -install_name 为 %p/lib/libbar.1.dylib,-compatibiliary_version 为 2.1.0 的函数库。另外,这个声明还表示维护者承诺这个名字及 compatibility-version 至少为 2.1.0 以上的 (32bit) 函数库可以在 bar1 软件包的以后版本中找到。

注意在库的名字中使用 %p,这使得无论他们选择什么安装路径前缀,Fink 的所有用户都可以找到正确的 -install_name 代表的函数库。

当一个软件包被更新的时候,通常 Shlibs 字段会被简单地拷贝到软件包的下一个版本/修订版中。例外的情况是如果 -compatibility_version 增加了:那种情况下,依赖信息的版本号应该改变到当前的版本号/修订版号(这是使用新兼容版本号的第一个函数库)。

The Shlibs entry for a private library uses a different syntax:

  Shlibs: <<
    !%p/lib/%N/libbar.1.dylib
  <<

The leading exclamation point indicates that this is a private library, and since the other information is not relevant in this case, it is not included.

Note that in this example, the private shared library has been placed in its own subdirectory %N of the %i/lib directory (which was named after the package). This is a recommended procedure for private libraries, as an additional safety measure, to prevent other packages from accidentally linking to this library.

当主版本号发生变化的时候应该做什么:

如果主版本号从 N 改到了 M,你需要创建两个新的软件包 barM 和 barM-shlibs。 软件包 barM-shlibs 可以不覆盖 barN-shlibs,因为许多用户会同时安装这两个版本。在软件包 barM 中,你应该使用依赖关系

  Conflicts: barN
  Replaces: barN

类似地,你应该修改 barN 来包括依赖关系

  Conflicts: barM
  Replaces: barM

用户会看到在构建其它软件包的时候,根据不同的软件的设置,会选择连接 barN 或 barM 作为共享库。这样,我们实现 barN-shlibs 和 barM-shlibs 在系统里面的共存。

Packages containing both binary files and libraries:

如果上游软件包包含二进制文件和库,那么在构建 fink 软件包的时候有些事情需要特别注意。有些情况下,那些二进制文件仅仅是一些类似 foo-config 的程序 ,它们只需要在构建的时候使用,而不需要在运行时使用。这种情况下,二进制文件可以和头文件一样包括在 foo 软件包中。

其它情况下,这些二进制文件可能需要在运行时被其它软件包使用,这时,它们需要被剥离到一个单独的文件包中,这个软件包的名字大约是 foo-binfoo-bin 软件包应该依赖于 foo-shlibs 软件包,其它软件包的维护者最好能够使用:

  Depends: foo-bin
  BuildDepends: foo

来隐式地处理 foo-shlibs。

在升级的时候会有一个问题,因为用户不会被提示安装 foo-bin。要避免这个问题,在全部其它软件包维护者象上面所说的一样修改它们的软件包之前,你的 foo 软件包可以这样声明:

  Depends: foo-shlibs (= exact.version), foo-bin

这可以强制安装 foo-bin 在多数用户的系统里面,只要有一天其它软件包维护者也升级了依赖于 foo 的软件包。

As of fink-0.28.0 (released in January 2008), the format of the Shlibs entry for a "private" shared library has changed (see earlier discussion of the difference between a public and a private shared library). Note that the Shared Library Policy has always required all shared libraries to be listed; the change here is only in the syntax of the Shlibs field. Because this type of shared library is not designed to be used by external packages, there is no need to document its compatilibity or other versioning. Instead, an exclamation-mark is used. For example, if libquux.3.dylib is the install_name of a private shared library, it would be listed as follows:

  Shlibs: <<
    !%p/lib/libquux.3.dylib
  <<

3.5 Perl 模块

Fink 从 2003 年 5 月开始实施的对 perl 模块的规则,在 2004 年 4 月进行了修改。

传统上,关于 perl 模块的 Fink 软件包具有 -pm 后缀,并使用 Type: perl 指令来构建,它把 perl 模块的文件保存在 /opt/sw/lib/perl5 和/或 /opt/sw/lib/perl5/darwin中。按照现行规则,这个存储位置仅允许用于那些与编译它们的 perl 程序版本无关的 perl 模块(同时也不应该依赖于那些不具备版本无关性的其它模块)。

那些版本相关的 perl 模块称为 XS 模块, 通常除了纯粹的 perl 子程序外,还包括编译好的 C 代码。有很多办法可以识别这个情况,包括存在带有 .bundle 后缀的文件等。

版本相关的 perl 模块必须使用标明版本号的 perl 程序来编译,比方说 perl5.6.0,而且必须把它的文件标准 perl 目录下面的一个标明版本号的子目录中,例如 /opt/sw/lib/perl5/5.6.0/opt/sw/lib/perl5/5.6.0/darwin。习惯上,使用后缀 -pm560 的命名约定来代表针对 5.6.0 的 perl 模块。类似的存储和命名约定也会用于其它版本的 perl,包括 perl 5.6.1 (仅用于 10.2 代码树), perl 5.8.0 (仅用于 10.3 代码树), perl 5.8.1, perl 5.8.4, 和 perl 5.8.6。

Type: perl 5.6.0 指令会自动使用相应标定版本的 perl 程序,并把文件存储在正确的子目录中。 (这个指令从 fink 0.13.0 版本开始提供)。

按照 2003 年 5 月的规则,可以允创建一个 -pm 软件包,它实际是去加载 -pm560 或其它存在的相应版本的"束"软件包。按照 2004 年 4 月的规则,不再鼓励这样做,而且经过一个过渡期后,将会完全放弃这种做法。(唯一的例外是 storable-pm 软件包因为自举的需要仍然需要保持这种形式)。

As of fink 0.20.2, the system-perl virtual package automatically "Provides" certain perl modules when the version of Perl present on the system is at least 5.8.0. In the case of system-perl-5.8.1-1, these are: attribute-handlers-pm581, cgi-pm581, digest-md5-pm581, file-spec-pm581, file-temp-pm581, filter-simple-pm581, filter-util-pm581, getopt-long-pm581, i18n-langtags-pm581, libnet-pm581, locale-maketext-pm581, memoize-pm581, mime-base64-pm581, scalar-list-utils-pm581, test-harness-pm581, test-simple-pm581, time-hires-pm581. (This list was slightly different in fink 0.20.1: package maintainers are encouraged to check to be sure that they are assuming the correct list.)

Users may have more than one version of perl installed at a time, so any perl-versioned module packages must be written to allow more than one version of themselves to be installed concurrently. One must use care when installing manpages and binary or other script executables in these packages in order to prevent installation conflicts due to filename collisions. You are not allowed to have any files in a package whose name ends with -pmXYZ that would have an identical pathname across different XYZ. Using Replaces to allow the same-named files to overwrite each other in different perl-versions of these perl-module packages is no longer acceptable. As a simple solution for manpages, starting in March 2005, Fink has defined alternate locations in MANPATH: %p/lib/perl5/X.Y.Z/man for each perl-X.Y.Z. You no longer need to create mutually-exclusive -man or -doc SplitOff packages. For example, to avoid conflicts between uri-pm581 and uri-pm586, the same-named URI.3pm manpage is installed as %p/lib/perl5/5.8.1/man/man3/URI.3pm and %p/lib/perl5/5.8.6/man/man3/URI.3pm, respectively. Note that the default scripts provided by Type: perl X.Y.Z have not changed, so you will have to locate the manpages here manually in your InstallScript. If you don't have a highly customized script, you can still use the default one, and then simply move the files manually:

%{default_script}
mv %i/share/man %i/lib/perl5/5.8.1

That will move all manpages. If you wish to move only one section of manpages (for example, only section 3, the module manpages, not script manpages in section 1), a similar approach works:

%{default_script}
mkdir -p %i/lib/perl5/5.8.1/man
mv %i/share/man/man3 %i/lib/perl5/5.8.1/man

If you have executables, for example, demo or utility scripts in %p/bin, you have several options. One example is to put these files (and their associated manpages and/or other related files) in a %N-bin splitoff package. Use of Conflicts and Replaces fields ensures that installation of different perl-version forms of these packages, which contain files of the same name, is mutually excluve. The user can install many different perl-versions of the runtime modules, and then choose whichever one perl-version of the scripts he wants at a given time. For example, Tk.pm comes with an executable ptksh, so the set of tk-pm* packages could be constructed as follows:

Info2: <<
Package: tk-pm%type_pkg[perl]
Type: perl (5.8.1 5.8.4 5.8.6)
InstallScript: <<
  %{default_script}
  mkdir -p %i/lib/perl5/%type_raw[perl]/man
  mv %i/share/man/man3 %i/lib/perl5/%type_raw[perl]/man
<<
SplitOff: <<
  Package: %N-bin
  Depends: %N
  Conflicts: %{Ni}5.8.1, %{Ni}5.8.4, %{Ni}5.8.6
  Replaces: %{Ni}5.8.1, %{Ni}5.8.4, %{Ni}5.8.6
  Files: bin share/man/man1
<<
<<

An alternative arrangement is to rename the scripts and their manpages to include perl-version information. This method means there is no naming conflict at all, so one does not need the mutually-exclusive %N-bin splitoffs:

Info2: <<
Package: tk-pm%type_pkg[perl]
Type: perl (5.8.1 5.8.4 5.8.6)
InstallScript: <<
  %{default_script}
  mkdir -p %i/lib/perl5/%type_raw[perl]/man
  mv %i/share/man/man3 %i/lib/perl5/%type_raw[perl]/man
  mv %i/bin/ptksh %i/bin/ptksh%type_raw[perl]
  mv %i/share/man/man1/ptksh.1 %i/share/man/man1/ptksh%type_raw[perl].1
<<
<<

The user accesses ptksh for whichever perl she wants. For convenience, one could use update-alternatives to allow users to be able to access these by their generic (no perl-version) names as well.

Also as of March 2005, the location of manpages and modules installed by fink packages for perl itself (packages perlXYZ and perlXYZ-core other than the perl-version provided by Apple) has changed. As a result of this relocation, other fink packages that supply updated versions of core perl modules should not list any perlXYZ or perlXYZ-core packages in the Replaces field.

3.6 Emacs 规则

Fink 项目选择遵循 Debian 项目针对 emacs 的规则,但稍微有些差别。 (Debian 规则文档可以在 http://www.debian.org/doc/packaging-manuals/debian-emacs-policy 找到)。 在 Fink 的规则中有两点区别。 首先,在 fink 中这个规则目前仅应用于 emacs21, emacs22emacs23 软件包,而不应用于 xemacs。(这在将来可能会有改变)。 第二,不象 Debian 的规则,Fink 软件包允许安装东西到 /opt/sw/share/emacs/site-lisp 目录中。

3.7 Source Policy

Sources should normally be downloaded from the location(s) that the upstream developer(s) use, and any modifications for Fink should be done through the use of a PatchFile and/or a PatchScript. Do not make changes manually and use a changed source archive as a Source in your Fink packaging.

If a VCS checkout (e.g. from git or svn) is to be used, e.g. because a project doesn't do formal releases, or a fix for a particular issue has been added between releases of a package, an acceptable source can be generated via the following method:

  1. Check out the package, preferably at a definite revision of the VCS.
  2. Make an archive from the VCS checkout (e.g. zip, tar, tar.gz, or tar.bz2).

    Give the tarball a unique version. For example, you can include the VCS revision in the archive name, e.g. foo-0svn1234.tar.gz for a package that doesn't make releases, or bar-1.2.3+svn4567.tar.bz2 for a Fink package which is between upstream releases.

  3. Use the same Version in your .info file.
  4. It is also useful to put the commands that you ran to generate the source tarball in the DescPackaging field.
  5. Upload the tarball to a public download site where users can use fink to download it. If you don't have ready access to one, ask on the Fink developers mailing list or the #fink IRC channel, and someone should be able to help.

3.8 File Download Policy

Packages are not to download any files during the unpack, patch, compile, install, or build phases of the build process. Any large patches (i.e. larger than can be accommodated conveniently in a PatchFile) that need to be applied should set up as additional Sources in accordance with the Source Policy.

Packages may download data in a PostInstScript after they have been installed on the system, under some limited circumstances:

If you are unsure, contact the Fink Core Team.

4 文件系统布局

下述的文件系统布局指南是 Fink 打包规则的一部分。

4.1 文件系统层次结构标准

Fink 遵循《文件系统层次结构标准》(Filesystem Hierarchy Standard),简称 FHS 的精神。 我们只能说遵循它的精神,是因为 FHS 是为操作系统提供者所涉及的,因此它是在 //usr 层次级别上来控制。而 Fink 只是一个附加的系统,它指控制它自己的安装目录(或安装前缀指定的目录)。 本章的例子使用默认的前缀 /opt/sw

4.2 目录

文件应该分类存放在层次结构中下列子目录中:

FieldValue
/opt/sw/bin

这个目录存放通常的可执行程序。里面没有子目录。

/opt/sw/sbin

这个目录存放那些应该只由系统管理员使用的命令。 后台守护进程程序会放在这里。 里面没有子目录。

/opt/sw/include

这个目录存放 C 和 C++ 头文件。 如果需要的话,可以创建子目录。 如果软件包安装的头文件可能与标准的 C 头文件发生混淆的话,这些头文件必须放到子目录中。

/opt/sw/lib

这个目录存放那些系统架构相关的数据文件和函数库。 除非有特别的理由,否则静态和动态连接库应该直接保存在 /opt/sw/lib。 这里通常还保存那些不应该由用户直接运行的可执行程序(否则的话,应该放在 libexec)。

软件包可以创建子目录来存放私有数据或可加载模块。 请确定使用那些对保持兼容性有利的目录名。 在目录名或目录层次中使用主版本号是个好办法,例如:/opt/sw/lib/perl5/opt/sw/lib/apache/1.3。 Care should be taken when the host type is used to create directories. powerpc-apple-darwin1.3.3 这样的目录对兼容性是不利的,powerpc-apple-darwin1.3 或仅仅是 powerpc-apple-darwin 是个好些的选择。

/opt/sw/lib/ppc64 /opt/sw/lib/x86_64

This directory is for 64-bit libraries, with /opt/sw/lib/ppc64 being used under powerpc architecture, and /opt/sw/lib/x86_64 being used under i386 architecture. Libraries which have been built 'fat' should be stored in /opt/sw/lib instead.

/opt/sw/share

这个目录是存放那些系统体系架构无关的数据文件。 那些 /opt/sw/lib 中的规则也适用于这里。 下面描述一些通常的子目录。

/opt/sw/share/man

这些目录中包括帮助页。它按照通常的分类方法进行组织。 在 /opt/sw/bin/opt/sw/sbin 中的每个程序都应该有一个对应的帮助页。

/opt/sw/share/info

这个目录包含 Info 格式(从 Texinfo 源文件产生)的文档。 dir 文件的维护是通过 Debian 版本的 install-info (dpkg 软件包的一部分) 来自动进行的。 适用 InfoDocs 描述字段来自动生成 postinstprerm 软件包脚本的合适代码。 Fink 确保不会有软件包会安装它自己的 dir 文件。 这里不会有子目录。

/opt/sw/share/doc

这个目录包括那些既不是帮助页,也不是 Info 的文档。 例如 README,LICENSE 和 COPYING 文件等。 每个软件包必须在这里创建一个子目录,以软件包的名字命名。 目录名不能包括版本号(除非它正好是软件包名的一部分)。 提示:使用 %n 就好了。

/opt/sw/share/locale

这个目录包含国际化所需要的信息目录。

/opt/sw/var

var 目录保存可变数据。 它包括队列目录,访问锁文件,状态数据库,游戏最高分和日志文件。

/opt/sw/etc

这个目录保存配置文件。 对于那些需要在这里保存比较多文件(比方超过一两个的数目)的软件包,应该建立一个子目录。 子目录应该和软件包或者里面的程序同名,以方便识别。

/opt/sw/src

这个目录用于保存和构建源代码。 软件包不应该在这个目录里面安装任何东西。

/opt/sw/Applications

This directory is for storing OS X-style applications which are launched by double-clicking rather than from the command line.

/opt/sw/Library/Frameworks

This directory is for storing OS X-style frameworks, sometimes used by OS X-style applications.

4.3 应该避免的事情

除了上面提到的以外,在 /opt/sw 中不应该有其它的目录。 特别地,不应该使用下面这些目录: /opt/sw/man/opt/sw/info/opt/sw/doc/opt/sw/libexec/opt/sw/lib/locale

5 Compilers

Fink uses the gcc family of compilers, as provided by Apple computer through the Apple Developer Connection. Different versions of gcc exist, and usually more than one is available on a Mac OS X system.

This section explains some of the ways Fink deals with these different versions of gcc. An email to the Fink mailing list has more explanation.

5.1 Compiler Versions

As GCC has evolved, there have been different fink "distributions" to cope with the changes.

Each Fink distribution has had certain default values for the gcc and g++ compilers, which any user compiling from source is expected to have installed. You can expect that direct calls to "gcc" and "g++" from within your package will use these default values. If you need to use a different value (for example, during a transition to a new distribution, your packages .info file must specify this using the versioned binaries provided by Apple. Exactly how you will do this depends on the build system of your software, but for many packages, the SetCC and SetCXX fink fields can be used for this puporse. For example, you might change the g++ compiler to version 3.3 by the setting SetCXX: g++-3.3. Examine the output when building your package to make sure that the correct compiler is being used.

The 10.1 distribution assumes that the compiler version is 2.95; the 10.2 distribution assumes that the compiler version is 3.1; the 10.2-gcc3.3 and 10.3 distributions assume tha the compiler version is 3.3. The compiler for the 10.4-transitional distribution is complicated: g++-3.3 is being used along with gcc-4.0. This will change again in the 10.4 distribution, which will use both gcc-4.0 and g++-4.0.

A new method was introduced for ensuring the correct g++ compiler starting with the 10.4-transitional distribution. During compilation, a directory /opt/sw/var/lib/fink/path-prefix-g++-XXX (where XXX is the version number) is added to the PATH during compilation. This directory contains shell scripts which ensure that the correct version of g++ is used.

5.2 The g++ ABI

The g++ ABI has changed 3 times during the lifetime of OS X: the ABI is different for versions 2.95, 3.1, 3.3 and 4.0. These different ABIs are not compatible with each other, and any libraries which use C++ code and are linked to by your project must be compiled with the same ABI as the one currently being used.

Fink keeps track of the g++ ABI by means of the GCC field. This field should be defined for any package which invokes the g++ or c++ compilers. (It should NOT be defined for packages which don't invoke those compilers.) Whenever an ABI upgrade occurs, all the dependencies of the packages must be checked for their own GCC field. When all of the dependencies have been upgraded, the package itself may be upgraded. The versions of the dependencies must be changed to guarantee that users will have the correct, updated, dependencies in place before they attempt to build the new version of your package.

A small group of packages which depend only on each other can be left at the previous version of the ABI when the distribution changes, if they are not ready to be upgrade. When the upgrade is eventually done, they must be all upgraded together with the correct versioning on all the packages. For this reason, it is best to upgrade most packages at the time the distribution changes.

Fink uses the GCC field to ensure that users have the correct version of the g++ compiler installed. If the GCC field is defined by the package, fink checks to see if the gcc_select command has been set to the correct current value. (This correct value is 3.3 for the 10.2 and 10.3 versions of OS X, and 4.0 for the 10.4 version of OS X. The gcc_select command was not available prior to OS X 10.2.)

6 操作手册

6.1 构建过程

要理解一些字段的含义,你需要有对 Fink 所采用的构建过程有些了解。它由五个阶段组成:解压,补丁,编译,安装和构建。下面的示例路径是关于安装在 /opt/sw 的 gimp-1.2.1-1 软件包的。

解压阶段/opt/sw/src/fink.build/gimp-1.2.1-1 这个目录会被创建,源代码压缩档会被在这里解压。多数情况下,这会创建一个名为 gimp-1.2.1 的目录,里面包括源代码;下面的操作步骤会在那个目录里面执行(即 /opt/sw/src/fink.build/gimp-1.2.1-1/gimp-1.2.1)。我们可以使用 SourceDirectory,NoSourceDirectory 和 SourceNExtractDir 这三个字段来控制有关细节。

补丁阶段,源代码会被打上补丁,以使得可以在 Darwin 下面编译。由 UpdateConfigGuess,UpdateLibtool,Patch 和 PatchScrip 这几个字段所指明的操作将被按照顺序执行。

编译阶段,源代码被配置和编译。通常这会以某些参数来调用 configure 脚本,然后执行一个 make 命令。 详细信息请查看 CompileScript 字段的描述。 If test suites are enabled for the build (a new feature in fink 0.25, currently achieved by building in maintainer mode), the TestScript will be run immediately after the CompileScript.

安装阶段,软件包被安装到一个临时目录,/opt/sw/src/fink.build/root-gimp-1.2.1-1 (= %d)。(注意 "root-" 部分。) 所有通常应该安装到 /opt/sw 的文件现在被安装在 /opt/sw/src/fink.build/root-gimp-1.2.1-1/opt/sw (= %i = %d%p)。 详细信息请查看 InstallScript 字段的描述。

(从 fink 0.9.9 开始,可以通过 SplitOff 字段从一个软件包描述文件生成几个软件包。在安装阶段的尾段,会为每个软件包建立一个单独的安装目录,文件会被移到相应的目录中,)

构建阶段,会根据临时文件夹的内容构建一个二进制安装包(.deb)文件。你不能直接影响这个步骤,但软件包描述里面的许多字段会用于生成 dpkg 的 control 文件。

6.2 字段

我们在这里把字段分成几类。这里所描述的内容并不一定包括全部的字段。:-)

初始化数据:

FieldValue
Package

软件包名。 可以包括小写字母,数字和这几个特殊字符:"."', "+" 和 "-"。 不可以使用下划线("_"),不可以使用大写字母。 这是一个必需字段。

对这个字段,只可应用 %N、%{Ni}、%type_raw[] 和 %type_pkg[] 这几种百分号扩展。

作为 Fink 的打包规则,给定的软件包应该总是使用相同的选项进行编译。 如果对一个软件包由多个变种(查阅关于 Type 字段的文档),你必须在 Package 字段中加入特定变种的信息(查阅关于 %type_pkg[] 百分号展开的文档)。 这样每个变种会由一个唯一的名称,软件包名字会指明包含了哪些变种的选项。 注意在 Package 字段使用 %type_pkg[] 和 %type_raw[] 百分号展开是新的功能,并与旧的 fink 版本严重不兼容,所以这些软件包的描述应该嵌入在 InfoN (N>=2)字段中。

Version

上游版本号。与 Package 字段具有同样的限制。 这是一个必需字段。

Note that some programs use nonstandard version numbering schemes that may cause sorting confusion or that contain characters that are not allowed in this field. In these situations, when writing the Fink package, you must convert the upstream value to one that is acceptable and that allows the versions to be arranged in the correct order. When in doubt about how version strings will be sorted, you can use the dpkg command at a shell prompt. For example,

  dpkg --compare-versions 1.2.1 lt 1.3 && echo "true"

will print "true" because version string "1.2.1" is less than "1.3". See the dpkg manpage for more details.

Revision

软件包的修订版号。 当你对一个相同的上游版本提供一个新的描述文件的时候,需要增加它。 修订版号从 1 开始。 这是一个必需字段。

Fink's policy is that any time you make a change to the .info file that results in changes to the binary (compiled) form of a package (the .deb file), you must increase Revision. This includes changing the Depends or other package lists, and adding, removing, or renaming splitoff packages or shifting files among them. When migrating a package to a new tree (from 10.2 to 10.3, for example) involves such changes, you should increase Revision by 10 (or some other large number) in the newer tree in order to leave space for future updates to the package in the older tree.

Architecture

A comma-separated list of CPU architecture(s) for which the package (and any splitoff packages) are intended. At present, the only valid values for architecture are powerpc and i386. If this field is present and not blank after conditional handling, fink will ignore the package description(s) if the local machine architecture is not listed. If the field is omitted or the value is blank, all architectures are assumed. (Introduced in a post-0.24.11 CVS version of fink.)

At present, the most common use of this field will be for packages which require a compiler earlier than gcc-4.0 (or packages which depend on such packages), which should be declared to have architecture powerpc.

This field supports the standard conditional syntax for any value in the value list and percent-expansions can be used (see the Depends field for more information). In this manner, certain variants can be restricted to certain architectures. For example:

  Package: foo-pm%type_pkg[perl]
  Type: perl (5.8.1 5.8.4 5.8.6)
  Architecture: (%type_pkg[perl] = 581) powerpc

will result in the field for the foo-pm581 variant being powerpc and the field being blank for all other variants. Remember that omitting a certain architecture value does not mean that the package is not for that architecture.

Distribution

A comma-separated list of distribution(s) for which the package (and any splitoff packages) are intended. At present, the only valid values for distribution are 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 10.12, 10.13, 10.14, 10.14.5, and 10.15 . If this field is present and not blank after conditional handling, fink will ignore the package description(s) if the local machine distribution is not listed. If the field is omitted or the value is blank, all distributions are assumed. (Introduced in fink 0.26.0.)

Since Fink's 10.9 through 10.14.5 distributions share a common set of finkinfo files, the most common use of this field will be for packages which are suitable for one of those distributions but not the other.

This field supports the standard conditional syntax for any value in the value list and percent-expansions can be used (see the Depends field for more information). In this manner, certain variants can be restricted to certain architectures. For example:

  Package: foo-pm%type_pkg[perl]
  Type: perl (5.8.1 5.8.6)
  Distribution: (%type_pkg[perl] = 581) 10.3, (%type_pkg[perl] = 581) 10.4

will result in the field for the foo-pm581 variant being 10.3, 10.4 and the field being blank for the foo-pm586 variant.

Since python 2.5 is not available in the 10.7+ distributions, and the available perl versions vary by distribution, these package types provide a common use of this field. For reference, we note the availabilty of various perl versions in the 10.3 through 13.0 distributions (bolded systems indicate system-perl at that version):

    perl 5.6.0:  10.3
    perl 5.8.0:  10.3
    perl 5.8.1:  10.3, 10.4
    perl 5.8.4:  10.3, 10.4
    perl 5.8.6:  10.3, 10.4, 10.5
    perl 5.8.8:        10.4, 10.5, 10.6
    perl 5.10.0:             10.5, 10.6
    perl 5.12.3:                         10.7, 10.8, 10.9
    perl 5.12.4:                         10.7, 10.8, 10.9
    perl 5.16.2:                         10.7, 10.8, 10.9, 10.10, 10.11, 10.12, 10.13
    perl 5.18.2:                         10.7, 10.8, 10.9, 10.10, 10.11, 10.12, 10.13, 10.14, 10.14.5, 10.15, 11.0, 11.3, 12.0, 13.0
    perl 5.18.4:                                     10.9, 10.10, 10.11, 10.12, 10.13, 10.14, 10.14.5, 10.15, 11.0, 11.3, 12.0, 13.0
    perl 5.28.2:                                     10.9, 10.10, 10.11, 10.12, 10.13, 10.14, 10.14.5, 10.15, 11.0, 11.3, 12.0, 13.0
    perl 5.30.2:                                     10.9, 10.10, 10.11, 10.12, 10.13, 10.14, 10.14.5, 10.15, 11.0, 11.3, 12.0, 13.0
    perl 5.30.3:                                     10.9, 10.10, 10.11, 10.12, 10.13, 10.14, 10.14.5, 10.15, 11.0, 11.3, 12.0, 13.0

A way to include all variants in a single finkinfo file is as follows.

  Package: foo-pm%type_pkg[perl]
  Type: perl (5.6.0 5.8.0 5.8.1 5.8.4 5.8.6 5.8.8 5.10.0 5.12.3)
  Distribution: <<
   (%type_pkg[perl] = 560) 10.3, (%type_pkg[perl] = 580) 10.3, 
   (%type_pkg[perl] = 581) 10.3, (%type_pkg[perl] = 581) 10.4, 
   (%type_pkg[perl] = 584) 10.3, (%type_pkg[perl] = 584) 10.4, 
   (%type_pkg[perl] = 586) 10.3, (%type_pkg[perl] = 586) 10.4, (%type_pkg[perl] = 586) 10.5,
   (%type_pkg[perl] = 588) 10.4, (%type_pkg[perl] = 588) 10.5, (%type_pkg[perl] = 588) 10.6,
   (%type_pkg[perl] = 5100) 10.5, (%type_pkg[perl] = 5100) 10.6,
   (%type_pkg[perl] = 5123) 10.7
  <<

Note that we do not include old distributions, such as 10.2 or 10.4-transitional, since the versions of fink which are relevant for them do not recognize this field.

Epoch

从 fink 0.12.0 开始。 这个可选字段可以用来指明软件包关键版本号(如果没有提供,默认值为 0).更多信息参考Debian 规则手册. Because Fink and some of the underlying Debian tools use name-version-revision as the unique identifier of a package, you must not create a package that differs from another solely by its epoch.

Description

对软件包的一个简单描述(有关它是什么东西的问题。)这是一个会显示在列表中的一行描述,所以它要简单明了。它应该少于 45 字符,必需少于 60 字符。在这个字段里面不需要重复软件包的名字-它总会被显式正确的上下文中。这是一个必需字段。

Type

这可以设为 bundle。 束(Bundle)软件包可以用于一套相关的软件包归类在一起。 它们只有依赖管理,但没有代码和安装文件。 对于束文件包,Source,PatchScript,CompileScript,InstallScript 以及其它相关的字段都会被忽略。

nosource 是一个很类似的类型。 它表明没有源程序压缩档,所以不会有东西被下载,解压阶段只是创建一个空目录。 不过,补丁,编译和安装阶段则会正常执行。 这样你可以通过补丁放进全部代码,或者只是在 InstallScript 中创建一些目录。 从 fink 0.18.0 开始,你可以通过设置 Source: none 来获得同样的效果。这样你可以把 "Type" 字段用于其它目的(比如:Type: perl,等等)。

从 fink 0.9.5 开始,开始有 perl 类型,它会对编译和安装脚本使用另外一套默认值。 从 fink 0.13.0 开始,有个这种类型的变种, perl $version,其中 $version 是 perl 的一个版本号,它由句点分开的三个数字组成,例如: perl 5.6.0

在 fink-0.19.2 后的一个 CVS 版本开始,language/language-version use 被通用化,以允许使用任意维护者定义的类型以及相应的子类型,并对一个给定的软件包可以使用多于一种类型。 类型和子类型均为不包含空白字符的任意字符串(但不应该使括号、逗号、花括号和百分号);不会进行百分号展开,类型(并非子类型)数值会被转换成小写。 多种类型值(每个类型可以有一个用空白字符分开的可选的子类型)可以用逗号分隔的列表指定。

另外,存在“变种”的概念,即一个 .info 文件描述一族相关的使用不同编译选项的软件包。 这个过程的关键是使用一系列子类型。 我们不使用单个字符串,而是使用括号中的一列用空格分开的字符串。 Fink 会对每种子类型克隆软件包描述文件,并在其中使用其中一个子类型。 例如:

Type: perl (5.6.0 5.8.1)

提供两个软件包描述,其中一个作为 Type: perl 5.6.0,另外一个作为 Type: perl 5.8.1。 特殊的子类型清单 "(boolean)" 代表一个包含它自己和一个句点的清单,因此下面的两种形式是相同的:

Type: -x11 (boolean)
Type: -x11 (-x11 .)

子类型清单展开/软件包克隆是递归的;如果在子类型清单中有多个类型,你会活得所有可能的组合:

Type: -ssl (boolean), perl (5.6.0 5.8.1)

可以使用 %type_raw[] 和 %type_pkg[] 伪哈希值来在其它字段中访问特定的变种子类型。 这里是两个示范的 .info 片段:

Info2: <<
Package: foo-pm%type_pkg[perl]
Type: perl (5.6.0 5.8.1)
Depends: perl%type_pkg[perl]-core
 <<
Info2: <<
Package: bar%type_pkg[-x11]
Type: -x11 (boolean)
Depends: (%type_raw[-x11] = -x11) x11
CompileScript:  <<
  #!/bin/bash -ev
  if [ "%type_raw[-x11]" == "-x11" ]; then
    ./configure %c --with-x11
  else
    ./configure %c --without-x11
  fi
  make
<<
<<

Starting in fink 0.26.0, there is a special Type: -64bit which controls a new percent expansion %lib and also changes the default value of LDFLAGS. When combined with the new construction %type_num[], this allows a single .info file to build both a 32-bit version of a library and a 64-bit version. Here's some sample code:

Info2: <<
Package: foo%type_pkg[-64bit]
Type: -64bit (boolean)
Depends: (%type_raw[-64bit] = -64bit) 64bit-cpu
ConfigureParams: --libdir='${prefix}/%lib'
SplitOff: <<
 Package: %N-shlibs
 Files: %lib/libfoo.*.dylib
 Shlibs: <<
    %p/%lib/libfoo.1.dylib 1.0.0 %n (>= 1.0-1) %type_num[-64bit]
  <<
<<
<<
License

本字段给出软件包发布所依据的授权协议的性质。它必须是本文档前面软件包授权协议中所描述的值之一。 另外,只有软件包确实满足打包规则在这方面的要求时,比如已经在软件包的 doc 目录安装了一份授权协议,才能够设置这个字段。

Maintainer

负责本软件包的人的姓名和电子邮件地址。这是一个必需字段,而且必需是下面格式的一个名字和地址:

Firstname Lastname <user@host.domain.com>
InfoN

本字段允许 fink 在软件包描述文件中实现后向兼容的语法改变。 一个给定版本的 fink 被配置为能够处理某个最大的 "N" 整数值。 任意在更高的 InfoN 字段的软件包会被忽略,所以这种机制仅在有需要的时候才使用,否则那些使用较旧版本的用户就会被没有必要地区别出去了。 要使用这个机制,把整个软件包描述放到合适的 InfoN 字段中间。 参考前面的 "File Format" 部分了解多行字段的语法。 Here are the features added for each InfoN level, along with the earliest version of fink that supports it:

  • Info2 (fink>=0.20.0): Ability to use percent-expansions in the main Package field of the .info file and the ability to use the %type_* percent-expansions in the Package field of SplitOff (and SplitOffN) packages.
  • Info3 (fink>=0.25.0): Can indent nicely in .info files, no more support for RFC-822 multi-lines, and can put comments in pkglist fields.
  • Info4 (fink>=0.26.2): adds %V expansion, and permits %lib in ConfigureParams field.

依赖关系:

FieldValue
Depends

在本软件包构建前必需安装的软件包的列表。 在这个字段中会进行百分号展开(也包括这部分中的其它软件包列表字段:BuildDepends、RuntimeDepends、Provides、Conflicts、Replaces、Recommends、Suggests 和 Enhances)。 通常,它只是以逗号分割软件包名清单,但 Fink 现在也和 dpkg 一样支持替代软件包和版本子句。 一个体现全部特性的例子是:

Depends: daemonic (>= 20010902-1), emacs | xemacs

注意,其实没有办法去表达真正的可选依赖关系。 如果一个软件包在有和没有另外一个软件包的情况下都可以工作,你必需要么确定即使有那个软件包存在的情况下都不会去使用它,或者把它添加到依赖关系字段中。 如果你想提供给用户两种选择,你应该使用两个软件包,例如:wget 和 wget-ssl。

操作顺序:在逗号分隔的列表中的每个软件包(或替代关系的集合)中,逻辑"OR"(可替代项的列表)具有比逻辑"AND"更优先的操作次序。不象算术中可以使用括号,没有办法特别在 Depends 或类似的字段中指明某个软件包组具有优先的次序。

从 fink 的 0.18.2 后 CVS 版本开始,你可以使用条件依赖关系。它通过在软件包名字前面放置 (string1 op string2) 来指定。首先会对这两个字符串进行通常的百分号展开,然后这两个字符串(都不能为空)会按照 op 运算符进行比较:<<, <=,=,!=,>>,>=。只有在比较的结果为真的时候,后面的软件包才会被认为是一个依赖关系。

你可以使用这个格式来简化维护几个类似的软件包的工作。例如,elinks 和 elinks-ssl 包里面都可以这样写:

Depends: (%n = elinks-ssl) openssl097-shlibs, expat-shlibs

这和在 elinks 中写:

Depends: expat-shlibs

elinks-ssl 中写:

Depends: openssl097-shlibs, expat-shlibs

是等价的。

作为替代的语法格式,如果 string 不为空的话,你也可以指定 (string) 为"true"。例如:

package: nethack%type_pkg[-x11]
Type: -x11 (boolean)
Depends: (%type_pkg[-x11]) x11

会把软件包 X11 设为 nethack-x11 变量的一个依赖关系,而不是 nethack。

Note that when using Depends/BuildDepends for shared library packages for which more than one major-version is available, you must not do the following:

  Package: foo
  Depends: id3lib3.7-shlibs | id3lib3.7-shlibs
  BuildDepends: id3lib3.7-dev | id3lib4-dev

even if your package could work with either library. Pick one (preferably the highest version that can be used successfully) and use it consistently in your package.

As explained in the Shared Library Policy, only one of the -dev packages can be installed at a time, and each has links of the same name that could point to different filenames in the associated -shlibs package. When compiling package foo, the actual filename (in the -shlibs package) gets hard-coded into the foo binary. That means the resulting package needs the specific -shlibs package associated with the -dev that was installed at compile-time. As a result, one cannot have a Depends that indicates that either one will suffice.

In the past, non-essential packages implicitly depended on the essential ones; this is no longer true.

BuildDepends

从 fink 0.9.0 开始。 只在编译时需要的依赖关系的清单。 这可以用于列出构建软件包必须使用工具(比如 flex)。它支持和 Depends 相同的语法。 If a build is being done with test suites enabled, the dependencies in the TestDepends field will be added to this list.

RuntimeDepends

从 fink 0.32.0 开始。 A list of dependencies that is applied at run time only, that is, when the package is being installed. This can be used to list packages that must be present to run the package, but which are not used at build time. Supports the same syntax as Depends.

Provides

一个逗号分隔的软件包名字清单,它表示本软件包会"提供"那些软件包的功能。 如果一个名为 "pine" 的软件包指明 Provides: mailer 的话,那么只要安装了"pine",所有对"mailer"的依赖关系都会被认为已经满足。 你通常会把这些软件包名字同时列在 "Conflicts" 和 "Replaces" 字段。

Note that there is no versioning data associated with Provides items. They do not inherit from the parent package that contains the Provides list nor is there a syntax for specifing an arbitrary version in the Provides field itself. Further, a dependency that contains a version specification is not satisfied by a package that Provides that needed package name. As a result, having many variants provide a common surrogate package may be harmful, because it precludes the use of versioned dependencies. For example, if foo-gnome and foo-nognome both have "Provides: foo", another package with "Depends: foo (> 1.1)" will not work.

Conflicts

一个逗号分隔的软件包名清单,这些软件包不应该和本软件安装在同一台机器上。 对于虚拟软件包,可以把它们代表的软件包的名字列在这里,它们会被自动正确处理。这个也支持和 Depend 字段类似的版本相关的依赖关系,但没有替换选择(这也不符合逻辑)。如果一个软件被列为它自己的 Conflicts 字段中,它将被从中清除(不会有特别的提示),这个功能在 fink 的 0.18.2 后 CVS 版本中提供。

注意:Fink 自己本身会忽略这个字段。不过,它会被传递给 dpkg 并做相应的处理。概括来说,它仅影响运行时,而不应该构建时。

BuildConflicts

A list of packages that must not be installed while this package is being compiled. This can be used to prevent ./configure or the compiler from seeing undesired library headers or to avoid use of a version of a tool that is known to be broken (for example, a bug in a certain version of sed). If a build is being done with test suites enabled, the packages in the TestConflicts field will be added to this list.

Replaces

这和 "Conflicts" 同时使用,当软件包不仅仅替代冲突的软件包的功能,还会有一些共同的文件的时候。 没有这个字段的话,dpkg 会按安装的时候报错,因为这些文件还由别的软件包所拥有。 它也可以作为一个提示说,这两个软件是真正的完全替代的,一个可以完全替代另外一个。如果一个软件列为它自己的 Replaces,它会被自动(没有提示)地从中清除(从 fink 的 0.18.2 后 CVS 版本开始提供)。

注意:Fink 自己本身会忽略这个字段。不过,它会被传递给 dpkg 并做相应的处理。概括来说,它仅影响运行时,而不应该构建时。

Recommends, Suggests, Enhances

这些字段以其它依赖关系的风格,指明一些额外的软件包关系。这三个关系不会影响通过dpkgapt-get 的实际安装过程。 它们由 dselect 或其它前端程序来帮助用户作出合理的选择。

Pre-Depends

对 Depends 字段进行更强的要求的特殊变量。 本字段只有在开发者邮件列表中经过讨论,并被大部分人同意需要这样做以后才可以使用。

Essential

一个表明是关键软件包的布尔值。 所有的非关键软件包都隐含地依赖于关键软件包。 dpkg 会拒绝从系统中删除关键软件包,除非设置了特别的标识来覆盖它。 In the past, non-essential packages implicitly depended on the essential ones; this is no longer true.

BuildDependsOnly

从 fink 0.9.9 开始。 一个布尔值,它表明没有其它软件包会依赖于它,它们应该只是 BuildDepend。 Unlike usual boolean fields, BuildDependsOnly is tri-state: leaving it undefined (not specifying it at all) is different than defining it as logically false. See the Shared Library Policy for more information.

As of fink 0.20.5, the presence or absence of this field, and its value if present, are recorded into the .deb file when the package is built. Therefore, if you change the value of BuildDependsOnly or if you add or remove it, you must increase the revision number of the package.

解压阶段:

FieldValue
CustomMirror

镜像站点的列表。每个镜像站点占一行,格式如下:<location>: <url>location 可以是洲代号(例如 nam),也可以是国家代号(比如 nam-us),或者其它的东西;镜像站点会按照它的顺序来进行尝试。 例如:

CustomMirror: <<
nam-US: ftp://ftp.fooquux.com/pub/bar
asi-JP: ftp://ftp.qiixbar.jp/pub/mirror/bar
eur-DE: ftp://ftp.barfoo.de/bar
Primary: ftp://ftp.barbarorg/pub/
>>

The standard continent and country codes are listed in /opt/sw/lib/fink/mirror/_keys, which is part of the fink or fink-mirrors package.

Source

源代码压缩档的 URL。它应该是一个 HTTP 或 FTP URL,但 Fink 本身并不关心这一点-它只是把它传递给 wget。这个字段对镜像站点的 URL 标记模式: mirror:<mirror-name>:<relative-path>。 这会在 Fink 的配置中寻找 mirror-name 镜像的设置,然后添加 relative-path 部分,并把结果作为实际的 URL。已知的 mirror-name 被列在 /opt/sw/lib/fink/mirror/_list 中。它是 fink 或 fink-mirror 软件包的一部分。另一方面,使用 custom 作为 mirror-name 会使 Fink 使用 CustomMirror 字段。 在 URL 使用前,会进行百分号展开。 记住 %n 包括所有 %type_ 变种数据,所以你可能会希望在这里使用 %{ni}(也许还包括一些特定的 %type_ 展开)。

从 0.18.0 开始,Source: none 具有特别的含义。它标识不需要下载源文件。参考 Type 字段的描述获取更多信息。 gnu 这个值代表 mirror:gnu:%n/%n-%v.tar.gzgnome 则代表 mirror:gnome:stable/sources/%n/%n-%v.tar.gz。默认值是 %n-%v.tar.gz (即一个手工指定的下载)。 This implicitly-defined Source form is deprecated (explicitly-stated simple filename/manual download is still okay).

Sources that are only needed in order to run test suites should use TestSource and related fields, inside the InfoTest block.

SourceN

如果一个软件包包含几个压缩档,在这些额外的字段中说明它们呢,从 N = 2 开始。所以,第一个压缩档(它应该是所谓的"主"压缩档)会被放在 Source,第二个压缩档则作为 Source2,依此类推。这里的规则和 Source 是一样的,区别只是 "gnu" 和 "gnome" 捷径不会被展开-那样做并没有意义。从 fink 的 0.19.2 后的一个 CVS 版本开始,你可以使用任意(不需要连续)的 N >= 2 的整数值。不过,你仍然要保证它们是不重复的。

SourceDirectory

在压缩档被解压到一个目录里面的时候必须使用,但目录名会和压缩档的基本部分不同。 通常,一个名为 "foo-1.0.tar.gz" 会产生一个名为 "foo-1.0" 的目录。如果它产生不同名字的目录,用这个参数指明它。对这个字段会应用百分号展开。

NoSourceDirectory

把这个布尔值参数设为真的话,压缩档不会展开到一个单独的目录中。 通常,一个名为 "foo-1.0.tar.gz" 会产生一个名为 "foo-1.0" 的目录。如果它只是把文件解压到当前目录,使用这个参数并把它设为真。

SourceNExtractDir

通常,一个辅助压缩档会被解压到主压缩档相同的目录中。如果你需要把它解压到一个特别的子目录中,使用这个字段来指明它。 正如一般人想象的一样,Source2ExtractDir 对应于 Source2 压缩档。查阅 ghostscript,vim 和 tetex 作为使用的例子。

SourceRename

这个字段可以在下载过程中改变源程序压缩档的名字。它经常用于在服务器上用目录来区别不同的版本,但压缩档的名字却都是相同的场合。例如: http://www.foobar.org/coolapp/1.2.3/source.tar.gz。要解决这个问题,你可以使用:

SourceRename: %n-%v.tar.gz

对于上面的例子,这会使得下载的源代码压缩档保存在 /opt/sw/src/coolapp-1.2.3.tar.gz,以满足我们的一般命名约定。

SourceNRename

这和 SourceRename 字段是一模一样的,除了它是用来重命名与 SourceN 字段对应的压缩档外。参考其它有关的部分来了解使用的例子。

Source-MD5

从 fink 0.10.0 开始。 在这个字段中,你可以指定源程序文件的 MD5 校验值。 这个信息会被 Fink 用来检测是否使用了错误的源文件版本,也就是说, 那些和维护者所使用的版本不同的软件包。通常引起这个问题的原因是:未完全下载的压缩档;上游维护者在未通知的情况下修改了源代码;木马或类似的攻击;等等。

典型的使用例子是:

Source-MD5: 4499443fa1d604243467afe64522abac

要计算校验值,可以使用 md5sum 工具。如果你希望检查压缩档 /opt/sw/src/apache_1.3.23.tar.gz 的校验值, 你可以运行下面的命令(下面还包括命令的输出结果):

fingolfin% md5sum /opt/sw/src/apache_1.3.23.tar.gz 
4499443fa1d604243467afe64522abac  /opt/sw/src/apache_1.3.23.tar.gz

正如你所看见的一样,靠左边的数值就是你需要的结果。

SourceN-MD5

从 fink 0.10.0 开始。 这个字段和 Source-MD5 字段完全一样,除了它是指定与 SourceN 字段对应的压缩档的 MD5 校验值。

Source-Checksum

Alternative method to list the checksum for a source file. This field takes a hash type, followed by the actual checksum. For example:

Source-Checksum: SHA256(5048f1c8fc509cc636c2f97f4b40c293338b6041a5652082d5ee2cf54b530c56)

Current valid checksums are MD5, SHA1, and SHA256. The shasum tool can be used to calculate SHA checksums:

$ shasum -a 256 /opt/sw/src/libexif-0.6.22.tar.xz 
5048f1c8fc509cc636c2f97f4b40c293338b6041a5652082d5ee2cf54b530c56  /opt/sw/src/libexif-0.6.22.tar.xz

The Source-Checksum field should only be used once per .info file. If both the Source-MD5 and Source-Checksum fields are present, Source-Checksum takes precedence.

SourceN-Checksum

This is just the same as the Source-Checksum field, except that it is used to specify the checksum of the tarball specified by the corresponding SourceN field.

TarFilesRename

从 fink 0.10.0 开始。 这个字段只对那些使用 tar 格式的源程序文件有效。

通过这个字段,你可以在解压压缩档的时候,重命名给定的源程序压缩档里面的文件。这是针对 HFS+ 文件系统大小写不敏感的特性的一个解决办法。比方说在标准的 Mac OS X 环境下 installINSTALL 这两个文件会发生冲突。通过这个字段,你可以不需要重新建立一个新的压缩档(过去需要这样做)就可以避免这个问题。

这个字段中,你只需要简单第列出需要重命名的文件。你可以使用通配符。 默认情况下,这些文件名后面会被加上 _tmp。你可以通过使用在 FilesDocFiles 字段中的相同语法来修改这个默认行为,就是在原来的文件名后面加上一个冒号,然后再加上新的文件名。 例如:

TarFilesRename: foo bar.* qux:quux
Tar2FilesRename: directory/INSTALL:directory/INSTALL.txt
TarNFilesRename

从 fink 0.10.0 开始。 这和 TarFilesRename 字段一致,除了它作用于与 SourceN 字段对应的压缩档以外。

补丁阶段:

FieldValue
UpdateConfigGuess

一个布尔值。如果为真的话,构建目录中的 config.guess 和 config.sub 会被替换为了解 Darwin 的版本。这发生在补丁阶段,并在 PatchScript 运行之前。仅仅 在你确定必须这么做的时候才使用它,即,当配置脚本以 "unknown host" 而失败的时候。

UpdateConfigGuessInDirs

从 0.9.0 后 CVS 版本开始。 这是一些子目录的清单。 这和 UpdateConfigGuess 完成相同的工作,但只对那些在几个子目录里面的 config.guess 文件是过期的情况下使用。 以前,你需要在 PatchScript 中手工拷贝/移动那里面的文件。 而有了这个新的字段以后,你可以仅仅是列出目录。 使用 . 来更新处于构建目录本身的文件。

UpdateLibtool

这是一个布尔值。如果为真的话,那么构建目录里面的 ltconfig 和 ltmain.sh 文件会被替换为与 Darwin 兼容的版本。 这发生在补丁阶段,在 PatchScript 脚本运行之前。 仅仅在你肯定需要软件包需要它的时候才这样做。 有些软件包会因为替换不正确版本的 libtool 脚本而被破坏。 查看libtool 网页获取更进一步的信息。

UpdateLibtoolInDirs

从 0.9.0 后 CVS 版本开始。 一个子目录的清单。 它和 UpdateLibtool 的作用一样,但只对那些源代码中几个目录中有过期的 libtool 1.3.x 脚本的软件包有用。 以前你需要在 PatchScript 脚本中手工拷贝/移动这些文件。 有了这个新的字段以后,你只需要指定这些目录。 使用 . 来更新在构建目录本身里面的文件。

UpdatePoMakefile

一个布尔值。 为真的话,在 po 目录中的 Makefile.in.in 文件会被替换为打过补丁的版本。 这发生在补丁阶段,并在 PatchScript 脚本运行之前。

打过补丁的版本可以识别 DESTDIR 并确保信息目录是在 /opt/sw/share/locale,而不是 /opt/sw/lib/locale。 在使用这个字段之前,确定你不会破坏软件包以及的确有这个必要。 你可以运行 diff 命令来找出软件包的版本和 Fink 的版本的区别(在 /opt/sw/lib/fink/update)。

Patch

应用于 patch -p1 <patch-file 命令的补丁文件的名字。这应该只是一个文件名;正确的路径会被自动添加(the same directory where the .info file  is located)。 在本字段中会应用百分号展开。所以典型的设置值只是 %f.patch%n.patch。补丁会在 PatchScript 脚本运行之前 in a separate step 应用(如果有的话)。

记住 %n 包括所有 %type_ 变种数据,所以你可能需要在这里使用 %{ni} (也许需要包括一些特定的 %type_ 展开)。 维护一个单独的补丁文件,然后在 PatchScript 字段中列出与变种有关的修改会比对每个变种使用单独的补丁文件容易些。

PatchFile

The same syntax as the Patch field. The full path to this file is available using the %{PatchFile} percent expansion--do not use %a to access this file. Unlike Patch, PatchFile is applied as part of PatchScript. Fink checks that the listed file exists, is readable, and that its checksum matches the PatchFile-MD5 field.

You may not use both Patch and PatchFile in the same package description. Any package that uses PatchFile must declare at least BuildDepends: fink (>= 0.24.12). Giving a higher version requirement is allowed if it is necessary for other reasons.

PatchFile-MD5

The MD5 checksum of the file given in the PatchFile field. This field is required if PatchFile is used. (Introduced in fink-0.24.12)

PatchScript

在补丁阶段运行的一系列命令。这是对软件包打补丁或修改软件包的地方。 参阅下面关于脚本的注意事项。 在命令运行之前,会进行百分号展开。 If a PatchFile field exists, the default PatchScript is:

patch -p1 < %{PatchFile}

If there is no PatchFile, the default is blank. If you have an explicit PatchScript, you must apply the PatchFile explicitly.

编译阶段:

FieldValue
SetENVVAR

在编译和安装阶段设置一些环境变量。这可以用于传递一些编译器标志等信息到 configure 脚本和 Makefile 文件。目前支持的变量包括: CC, CFLAGS, CPP, CPPFLAGS, CXX, CXXFLAGS, DYLD_LIBRARY_PATH, JAVA_HOME, LD, LDFLAGS, LIBRARY_PATH, LIBS, MACOSX_DEPLOYMENT_TARGET, MAKE, MFLAGS, MAKEFLAGS。 你指定的值也会应用前面说过百分号展开。一个常见的例子是:

SetCPPFLAGS: -no-cpp-precomp

Some environment variables have default preset values. If you specify a value for one of these, it will be prepended to the default value. The preset variables (and their default values) are:

CPPFLAGS: -I%p/include
LDFLAGS: -L%p/lib

Starting in fink 0.26.0, there is one exception to these defaults: if Type: -64bit is set to -64bit, then the default value of LDFLAGS is -L%p/%lib -L%p/lib instead.

Finally, MACOSX_DEPLOYMENT_TARGET is set to a default value depending on which version of OSX is being run, but setting a value for it for a package will override (rather than prepend to) the default value.

NoSetENVVAR

When set to a true value, deactivates the default values for the preset variables (such as CPPFLAGS, LDFLAGS, CXXFLAGS mentioned above). For example, if you want LDFLAGS to remain unset, specify NoSetLDFLAGS: true .

ConfigureParams

传递给 configure 脚本的额外参数(查阅 CompileScript 字段的说明获取详细信息)。 For packages not of Type: Perl, the parameter --prefix=%p is prepended to this value. As of fink > 0.13.7, this field will also work with perl modules Type: Perl; the default perl Makefile.PL string is prepended to the value supplied for ConfigureParams.

If a build is being done with test suites enabled, the value of the TestConfigureParams field will be appended to the normal ConfigureParams value.

Starting in fink-0.22.0, this field supports conditionals. The syntax is the same as that used in the Depends and other package-list fields. The conditional expression only applies to the whitespace-delimited "word" immediately following it. For example

Type: -x11 (boolean)
ConfigureParams: --mandir=%p/share/man (%type_pkg[-x11]) --with-x11 --disable-shared

will always pass the --mandir and --disable-shared flags, but only pass --with-x11 in the -x11 variant.

GCC

This field specifies the GCC-ABI used by C++ code in this package. (It is needed because that ABI has changed twice, and any libraries which you link to containing C++ code must be compiled with the same ABI you are currently using.)

The allowed values are: 2.95.2 (or 2.95), 3.1, 3.3, and 4.0. Our understanding is that the GCC authors intend to stabilize the GCC-ABI at some point; we can hope that it won't change again.

The GCC field does not have a default value, per se, since it is ignored if it is not set. However, for each tree, there is an expected value for GCC corresponding to the default g++ compiler for that tree. The expected values for the various package trees are: 2.95 in the 10.1 tree, 3.1 in the 10.2 tree, 3.3 in the 10.2-gcc3.3, 10.3, and 10.4-transitional trees, and 4.0 in the (upcoming) 10.4 tree.

Note that when the GCC value is different from the expected value, the compiler must be specified within the package (typically by setting the CC or CXX flags), and a dependency on one of the (virtual) gcc packages should be specified.

对于 fink 0.13.8,如果使用了这个标志,会使用 gcc_select 来检测 gcc 的版本,如果检测到错误的版本,fink 会出错退出。

This field was added to fink to aid maintainers in tracking the transition between the gcc compilers, which introduced a binary incompatibility between libraries that involve C++ code which is not reflected in the versioning scheme.

CompileScript

在编译阶段运行的一系列命令。这里是放置配置和编译软件包的命令的地方。 参阅下面关于脚本的注意事项。 在命令运行之前,会进行百分号展开。 通常默认值是:

./configure %c
make

这对于使用 GNU autoconf 的软件包是恰当的。 对于那些是 perl (通过 Type 字段指定)类型,但却没有指明 perl 版本的软件包,默认的替代值是:

perl Makefile.PL PREFIX=%p \
 INSTALLPRIVLIB=%p/lib/perl5 \
 INSTALLARCHLIB=%p/lib/perl5/darwin \
 INSTALLSITELIB=%p/lib/perl5 \
 INSTALLSITEARCH=%p/lib/perl5/darwin \
 INSTALLMAN1DIR=%p/share/man/man1 \
 INSTALLMAN3DIR=%p/share/man/man3 \
 INSTALLSITEMAN1DIR=%p/share/man/man1 \
 INSTALLSITEMAN3DIR=%p/share/man/man3 \
 INSTALLBIN=%p/bin \
 INSTALLSITEBIN=%p/bin \
 INSTALLSCRIPT=%p/bin
make
make test

如果是指定版本的 perl $version 类型(比如 $version 可能是 5.6.0), 默认值是:

perl$version Makefile.PL \
 PERL=perl$version PREFIX=%p \
 INSTALLPRIVLIB=%p/lib/perl5/$version \
 INSTALLARCHLIB=%p/lib/perl5/$version/$perlarchdir \
 INSTALLSITELIB=%p/lib/perl5/$version \
 INSTALLSITEARCH=%p/lib/perl5/$version/$perlarchdir \
 INSTALLMAN1DIR=%p/share/man/man1 \
 INSTALLMAN3DIR=%p/share/man/man3 \
 INSTALLSITEMAN1DIR=%p/share/man/man1 \
 INSTALLSITEMAN3DIR=%p/share/man/man3 \
 INSTALLBIN=%p/bin \
 INSTALLSITEBIN=%p/bin \
 INSTALLSCRIPT=%p/bin
make
make test

where $perlarchdir is "darwin" for versions 5.8.0 and earlier, and is "darwin-thread-multi-2level" for versions 5.8.1 and later.

NoPerlTests

从 fink 0.13.7 之后开始。 一个针对 perl 模块软件包的布尔值。如果为真的话,CompileScriptmake test 部分会对那些指定的 perl 模块忽略。

Test Suites:

FieldValue
InfoTest

Introduced in fink 0.25. This field encapsulates information that will only be used when performing a build with test suites enabled. It contains other fields. If present, this field must contain a TestScript. All other fields are optional. The following fields are allowed inside InfoTest:

  • TestScript: A script which runs the test suite. This script should exit with status 0 if the suite passes, 1 to indicate warnings, or any other value to indicate failures serious enough to be considered fatal. Because of this tri-state logic, you should explicitly set an exit value in this script. For instance, make check is a bad script, since it will exit with status 1 if the check target doesn't exist. make check || exit 2 would be a better script.
  • TestConfigureParams: A value which will be appended to ConfigureParams.
  • TestDepends and TestConflicts: Lists of packages that will be added to the BuildDepends or BuildConflicts lists.
  • TestSource: Extra sources necessary to run the test suite. All of the affiliated fields are also supported, so you must also specify TestSource-MD5 or TestSource-Checksum, and you may also have TestSourceN and corresponding TestSourceN-MD5, TestSourceN-Checksum, TestTarFilesRename, etc.
  • TestSuiteSize: Describes approximately how long the test suite takes to run. Valid values are small, medium, and large. This field is currently ignored.
  • Any other standard field. If a field is specified both inside and outside InfoTest, the value inside InfoTest will replace the other value when test suites are active.

Here's an example:

InfoTest: <<
    TestScript: make check || exit 2
    TestConfigureParams: --enable-tests
<<

安装阶段:

FieldValue
UpdatePOD

从 fink 0.9.5 开始。 一个针对 perl 模块软件包的布尔值。 为真的话,它会添加代码到 install,postrm 和 postinst 脚本来维护 perl 软件包所提供的 .pod 文件。 这包括在中央的/opt/sw/lib/perl5/darwin/perllocal.pod文件中添加和删除 .pod 数据。 (如果类型是以 perl $version 这样包括特定版本的形式给出,例如 5.6.0,那么这些脚本会被用于处理在 /opt/sw/lib/perl5/$version/perllocal.pod 的中央 .pod 文件。)

InstallScript

一系列在安装阶段运行的命令。 这是把软件包的需要文件拷贝到正确的地方的指令。 参阅下面关于脚本的注意事项。 在命令运行之前,会进行百分号展开。 通常的默认值是:

make install prefix=%i

这么默认值对使用 GNU autoconf 的软件包是合适的。 对于那些 perl (通过 Type 字段指明) 模块类型的软件包, 如果没有指定 perl 版本的话, 默认的值为:

make install INSTALLPRIVLIB=%i/lib/perl5 \
 INSTALLARCHLIB=%i/lib/perl5/darwin \
 INSTALLSITELIB=%i/lib/perl5 \
 INSTALLSITEARCH=%i/lib/perl5/darwin \
 INSTALLMAN1DIR=%i/share/man/man1 \
 INSTALLMAN3DIR=%i/share/man/man3

如果类型是指定版本 perl $version (比如 $version 为 5.6.0)的 perl 模块, 默认值为:

make install INSTALLPRIVLIB=%i/lib/perl5/$version \
 INSTALLARCHLIB=%i/lib/perl5/$version/darwin \
 INSTALLSITELIB=%i/lib/perl5/$version \
 INSTALLSITEARCH=%i/lib/perl5/$version/darwin \
 INSTALLMAN1DIR=%i/share/man/man1 \
 INSTALLMAN3DIR=%i/share/man/man3

如果软件包支持的话,首选会使用 make install DESTDIR=%d

AppBundles

Introduced in a post-0.23.1 version. This field installs the specified application bundle(s) into %p/Applications. It will also create a symlink to the /Applications/Fink directory. Example:

AppBundles: build/*.app Foo.app
JarFiles

从 fink 0.10.0 开始。 这个字段和 DocFiles 有些类似。它安装指定的 jar 文件到 %p/share/java/%n 目录中。 例如:

JarFiles: lib/*.jar foo.jar:fooBar.jar

这将安装全部原来在 lib 目录中 jar 文件,同时会把 foo.jar 安装为 fooBar.jar。

它同时确保这些 jar 文件(尤其是:所有在 %p/share/java/%n 目录中以 .jar 结尾的文件) 被添加到 CLASSPATH 环境变量中。 这使得象 configure 或 ant 之类的工具能够正确地检测到已安装的 jar 文件。

DocFiles

这个字段提供一个安装软件包中 doc 目录中%p/share/doc/%n README 或 COPYING 文件的方便方法。 它的值是一些以空格分开的文件清单。 你可以从构建目录的子目录拷贝文件,但最后它们应该拷贝到 doc 目录本身,而不是它的子目录。 可以使用 Shell 通配符。 也可以在拷贝的同时重命名某个文件,这可以在一个冒号后面添加新的文件名来实现, 比如 libgimp/COPYING:COPYING.libgimp。 这个字段的功能是通过在 InstallScript 中添加合适的 install 命令。

Shlibs

从 fink 0.11.0 开始。 这个字段声明软件包中要安装的共享库。 There is one line for each shared library, which contains the -install_name of the library and information about its binary compatibility. Shared libraries that are "public" (i.e., provided for use by other packages) have, separated by whitespace after the filename, the -compatibility_version, versioned package dependency information specifying the Fink package which provides this library at this compatibility version, and the library architecture. (The library architecture may either be "32", "64", or "32-64", and may be absent; the value defaults to "32" if it is absent.) 依赖信息应该以下面的形式描述: foo (>= version-revision) 其中 version-revision 指提供(这个兼容版本)函数库的 Fink 软件包的 第一个版本。 Shlibs 声明表明维护者承诺这个名字和至少 -compatibility_version的兼容版本号的函数库会在这个 Fink 软件包的新版本中找到。 Shared libraries that are "private" are denoted by an exclamation mark preceeding the filename, and no compatilibity or versioning information is given. See the Shared Library Policy for more information.

RuntimeVars

从 fink 0.10.0 开始。 这个字段提供设置运行时环境变量为一些静态值的简便方法(如果你需要更灵活的方式,参考 profile.d 脚本部分)。在你的软件包安装以后,这些变量会通过 /opt/sw/bin/init.[c]sh 脚本设置。

你的环境的值可以包括空格(尾部的连续空格会被截断);另外,百分号展开也会进行。例如:

RuntimeVars: <<
 SomeVar: %p/Value
 AnotherVar: foo bar
<<

会设置两个环境变量 "SomeVar" 和 "AnotherVar",它们的值相应地被设置为 "/opt/sw/Value" (或你选择的前缀)以及 "foo bar"。

这个字段通过添加合适的命令到 InstallScript 来实现。 这些命令为每个变量添加一行 setenv/export 到软件包的 profile.d 脚本,所以你也提供你自己,它们不会被覆盖。这些行被作为脚本考虑,你可以在你的脚本中使用这些变量。

SplitOff

从 fink 0.9.9 开始。 在同一个编译/安装过程中产生第二个软件包。 有关详细信息,查看下面单独的 剥离(splitoff)部分

SplitOffN

Introduced in fink 0.9.9. 这和 SplitOff 一样,用于从同一个编译/安装过程产生第三、第四个等等软件包。 从 fink 0.19.2 后的一个 CVS 版本开始,你可以使用 N >=2 的任意整数值。不过,你仍然要保证它们是互不重复的。

Files

从 fink 0.9.9 开始。 SplitOffSplitOffN 字段内使用, 它用于指定哪些文件和目录需要从父文件包的安装目录 %I 移动到当前安装目录 %i。 注意这在父文件包的 InstallScript 和 DocFiles 之后,但在当前文件包的 InstallScript 和 Docfiles 之前执行。

构建阶段:

FieldValue
PreInstScript, PostInstScript, PreRmScript, PostRmScript

这些字段指明当软件包安装、升级或删除的时候执行的 shell 脚本。 Fink 会自动添加脚本的头部 #!/bin/sh,并调用 set -e,所以任何失败的命令都会导致脚本的立即终止。 Fink 还会在最后添加一个 exit 0。 要指明错误,从脚本中以一个非零值退出。 第一个参数 ($1) 被设为一个指明应该采用什么操作的值。 一些可能的值包括 installupgraderemovepurge。 注意还有更多的值,用于错误回退或因为另外一个文件包而删除的情况。

脚本会在下面的时候被调用:

  • PreInstScript: 当软件包第一次安装和升级到这个版本时。
  • PostInstScript: 解压和设置软件包之后。
  • PreRmScript: 软件包被删除或升级到新版本之前。
  • PostRmScript: 软件包被删除或升级到新版本之后。

更清楚地说,升级过程包括:新版本的 Inst scripts,和旧版本的 Rm scripts。 细节可以在 Debian 规则手册找到, 第六章.

脚本中会进行百分号展开。 命令通常会不使用完整路径来调用。

ConfFiles

以空格分开的用户可以编辑的配置文件的列表。 Percent expansion  is performed on this field. 这些文件必须以绝对路径指明,例如,%p/etc/%n.conf。 这些文件会被 dpkg 特别对待。 当软件包被升级,而软件包和磁盘上的文件相比被改动过的话,用户会被询问使用哪个版本,以及是否需要进行备份。 当一个软件包被删除后,配置文件仍然还保留在磁盘上。 只有 "purge" 会删除配置文件。

InfoDocs

软件包安装在 %p/share/info 目录的信息文件的清单。 这会在 postinst 和 prerm 脚本中添加合适的代码来维护 Info 目录的文件 dir文件。

Note: Only use the un-numbered file in the case of split Info documents. E.g. if a package has:

foo.info
foo.info-1
foo.info-2

you should only use:

InfoDocs:  foo.info

这个特性仍然在增加过程,将来可能会加入更多的字段以获得更精细的控制。

DaemonicFile

给出 daemonic 的服务描述。 daemonic 被 Fink 用于创建和删除 daemon 进程的 StartupItems (例如 web 服务器)。 描述会被作为一个名为 %p/etc/daemons/name.xml 的文件添加到软件包中,这里 name 由 DaemonicName 字段指定,默认为软件包名字。 对本字段的内容可以进行百分号展开。 注意如果你的软件包需要使用它的时候,你必须添加 daemonic 到依赖关系清单中。

DaemonicName

daemonic 服务描述文件的名字。 查看 DaemonicFile 字段的描述获取更多的信息。

额外数据:

FieldValue
Homepage

软件包上游提供者的首页 URL。

DescDetail

一个相比 Description 字段更详细的描述(内容包括它是什么,我可以用它来做什么?)。 这里允许使用多行。因为这个字段在显示的时候不会由自动单词绕回,你应该手工插入分行符,使得每行不超过 79 个字符(如果可能的话)。

DescUsage

这是对如果使用软件有关的信息(我怎么使用它?)。 就好象 "在使用 WindowMaker 运行 wmaker.inst 一次" 这样的信息。可以使用多行。因为这个字段在显示的时候不会由自动单词绕回,你应该手工插入分行符,使得每行不超过 79 个字符(如果可能的话)。

DescPackaging

关于软件包的注解。类似 "对 Makefile 进行修正已使得正确放置所有的文件" 之类的信息会放在这里。可以使用多行。

DescPort

这是专门针对移植到 Darwin 的软件包的。 象 "config.guess 和 libtool 脚本已被更新,需要使用 -no-cpp-precomp " 之类的信息会被放在这里。可以使用多行。

6.3 剥离分支(SplitOffs)

从 fink 0.9.9 开始,可以用一个单独的 .info 文件来构建多个软件包。 安装阶段和正常的类似,执行 InstallScriptDocFiles 命令。 如果存在 SplitOffSplitOffN 字段,会触发额外一个安装目录的创建。 在 SplitOffSplitOffN 字段里面,新的安装目录以 %i 代表, 而父文件包的原始安装目录则用 %I 代表。

每个 SplitOffSplitOffN 字段必须包含它自己的一系列字段。 事实上,它由一个备有包含字段的一个完整的软件包描述组成。下面是在子描述里面可以包含的内容(分类说明):

Because %n-%v-%r is treated as the unique identifier of a package, you must not have the same Package (at the same Version and Revision) listed as a SplitOff (or SplitOffN) of multiple packages. If you use variants, remember that each variant is considered an independent package, so the following package layout is forbidden:

Package: mime-base64-pm%type_pkg[perl]
Type: perl (5.8.1 5.8.6)
SplitOff: <<
  Package: mime-base64-pm-bin
<<

在安装阶段,父文件包的 InstallScriptDocFiles 会被首先执行。 然后处理 SplitOffSplitOffN 字段。对每个这种字段,Files 命令会导致命令中所列的文件和目录会从父文件包的安装目录 %I 移到当前的安装目录 %i。然后给定 SplitOffSplitOffN 软件包的 InstallScriptDocFiles 会被执行。

目前,SplitOff 会被首先执行(如果存在的话),然后是按照 N 的顺序执行每个 SplitOffN。 不过,在将来这可能会被改变。因此,例如:

SplitOff: <<
  Description: Some header files
  Files: include/foo.h include/bar.h
<<
SplitOff2: <<
  Description: All other header files
  Files: include/*
<<

只有 SplitOffSplitOff2 之前处理才是正确的。 比较安全的作法是在每个块中都显式列出每个文件(或使用更明确的文件名描述)。

在构建阶段,每个软件包的安装/删除的前/后脚本会通过相应软件包构建阶段的命令来生成。

每个被构建的软件包都要求把授权协议文件存放到 %i/share/doc/%n (当然对于每个软件包 %n 有不同的取值)目录中。 注意 DocFiles 是拷贝文件而不是移动它们,所以可以通过多次使用 DocFiles 命令而把一个相同文档拷贝安装在几个不同的地方。

6.4 脚本

PatchScript,CompileScript 和 InstallScript 字段允许你指定需要执行的 shell 命令。 构建目录(%b)是脚本执行的当前目录。 你应该总是使用相对路径名或百分号扩展来引用 fink 目录结构中的文件和目录,而不应该是绝对路径的形式。 它有两种形式。

这个字段可以是命令的简单罗列。它和一个 shell 脚本类似。不过,命令是通过 system() 调用执行的,每次一行,所以设置环境变量和更改路径只对同一行有效。从 fink 0.18.2 后的 CVS 版本开始,你可以用与普通 shell 脚本类似的方法来绕回太长的行: 在一行末尾的反斜线 (\) 表明下一行是一个续行。

作为替代方案,你可以在这里嵌入一个完整的脚本,使用你选择的解析器。 对于任何 Unix 脚本,第一行必须以 #! 开始,后面紧跟解析器的完整路径名以及需要的标志(例如 #!/bin/csh#!/bin/bash -ev等等)。在这种情况下,整个 *Script 字段会被写到一个临时文件,然后被执行。

6.5 补丁

如果你的软件包需要补丁采可以在 Darwin 上编译(或与 Fink 配合), 把补丁命名为与软件包描述文件相同的名字,使用 ".patch" 来取代 ".info" 作为扩展名,并把它放在和 .info 文件相同的目录下面。 如果你在文件名中使用完整的软件包名,那么使用下面的任意一种方式(它们是等效的):

Patch: %f.patch
PatchScript: patch -p1 <%a/%f.patch

如果你使用比较新的简单软件包命名约定,使用 %n 来代替 %f。这两个字段不是互斥的,你可以两个都使用,它们都会被执行。这种情况下,PatchScript 会在后面被执行。 Alternately, you can use the newer PatchFile instead of Patch and apply with an implicit or explicit PatchScript--see the descriptions of the PatchFile and PatchScript fields for more information.

因为你可能会在补丁文件中允许用户选择安装前缀,建议在补丁文件中使用类似 @PREFIX@ 的变量来代替 /opt/sw,然后使用:

PatchScript: sed 's|@PREFIX@|%p|g' <%a/%f.patch | patch -p1

补丁文件应该是 unidiff 格式,而且一般应该通过:

diff -urN <originalsourcedir> <patchedsourcedir>

命令产生。

如果你用过 emacs 编辑文件,你可以在上面的 diff 命令中加上 -x'*~' 来派出自动产生的后备文件。

另外需要注意的是非常大的补丁不应该放到 CVS 中。 它们应该被放到一个 web/ftp 服务器,并使用 SourceN: 字段来指明。如果你自己没有网站,fink 项目管理员可以把它放到 fink 自己的网站上。如果你的补丁大于 30Kb,你应该考虑把它作为一个单独的下载。

6.6 Profile.d 脚本

如果你的软件包需要一些运行时的初始化(例如,设置环境变量),你可以使用 profile.d 脚本。 这些脚本片段由 /opt/sw/bin/init.[c]sh 脚本所运行。通常,所有 fink 的用户都会把这些脚本放到它们的起动文件(.cshrc 或类似的文件)中。 你的软件包必须为两个变种都提供脚本:一个给 sh 兼容的 shells (sh, zsh, bash, ksh, ...) 而另一个给 csh 兼容的 shells (csh, tcsh)。它们应该被安装在 /opt/sw/etc/profile.d/%n.[c]sh (和往常一样,%n 代表软件包名)。 另外,它们的可读和可执行属性都应该被设置(即,用 -m 755 参数安装它们),否则它们不能被正确加载。

如果你只需要设置一些环境变量(例如,把 QTDIR 设置为 '/opt/sw'),你可以使用 RuntimeVars 字段来比较方便地实现这个所说的功能。


Copyright Notice

Copyright (c) 2001 Christoph Pfisterer, Copyright (c) 2001-2020 The Fink Project. You may distribute this document in print for private purposes, provided the document and this copyright notice remain complete and unmodified. Any commercial reproduction and any online publication requires the explicit consent of the author.


Generated from $Fink: packaging.zh.xml,v 1.45 2023/08/04 4:54:31 nieder nieder Exp $