# 命名

FreeBSD Porter 手册
上一页 | 第5章 　配置 Makefile | 下一页

# 5.2 命名

Makefile 的第一部分便是 port 的名字、 版本号， 以及它所属的分类。

## 5.2.1 `PORTNAME` 和 `PORTVERSION`

您应该把 `PORTNAME` 设置为您 port 的名字， `PORTVERSION` 则是 port 的版本号。

## 5.2.2 `PORTREVISION` 和 `PORTEPOCH`

### 5.2.2.1 `PORTREVISION` (port 的修订版本号)

`PORTEREVISION` 变量是一个单调递增的值， 如果不为 0， 就会被加到包名的后面， 当 `PORTVERSION` 增加 的时候应被置 0 (也就是当官方有新版本发布的时候)。 `PORTREVISION` 会被自动化工具 (比如 pkg_version(1)) 用来检测是否存在可用的新版本。

每当 port 发生变化并对生成的 package 的内容或结构有显著影响时， 都应增加 `PORTREVISION` 值。

下面是一些应当修改 `PORTREVISION` 的情况：

- 有新的补丁用来修正安全漏洞、 错误， 或给 port 添加了新的功能。

- 修改了 `Makefile` 里编译时开启或禁用的选项。

- 修改了要安装文件的列表或安装时的行为 (例如， 修改了一个用来给 package 初始化数据的脚本， 如 ssh host keys)。

- 一个port依赖的共享库版本改变 (在这种情况下， 当安装了新版本的共享库， 后再去安装较早的软件就会出错， 因为它们要依赖老的 libfoo.x 而不是libfoo.(x+1))。

- 原作者修改了 port distfile， 并且 distfile 的新老版本之间用 `diff -ru` 只能发现一些细微的变化， 这时我们只需要对 `distinfo` 做相应的修正， 而不需要修改 `PORTVERSION`。

不需要修改 `PORTREVISION` 的例子：

- port 结构风格的改变， 但对于打成的包没有功能的上的变化。

- `MASTER_SITES` 发生变化， 或进行了对 port 功能的修改， 但不致影响最后打成的包。

- 对 distfiles 诸如修正拼写错误之类的补丁， 对用户而言没有升级上的麻烦。

- 对一个原本编译失败的包的修改， 使其可编译， 而没有加入新功能。 因为 `PORTREVISION` 表示包的内容发生了变化， 如果先前没有可编译的包， 也就不需要修改 `PORTREVISION` 来表示变化。

一个修改并提交 port 的原则是： 使得别人能从中受益 (改进、 修改已有错误， 或使新的 package 能够运行)， 您还要权衡一下这是否应让那些经常更新 ports 树的人升级， 如果回答是 “是” 的话， `PORTREVISION` 就应该修改了。

### 5.2.2.2 `PORTEPOCH` (port 的加权版本号)

有时软件商或 FreeBSD 的 porter 会使用比旧版的版本号小的数字做为新版本号的情况。 举例来说， 从 foo-20000801 到 foo-1.0 (从形式上来说这是不对的， 因为 20000801 在数值上比1大很多)。

在这种情况下， `PORTEPOCH` 应当增加。 如果 `PORTEPOCH` 非 0， 就应当加到包名字的后面。 `PORTEPOCH` 永远不能被减少或清零， 因为那样会导致与前一时期的 package 比较版本时产生不正确的结果。 (就是说， 那个 package 就不会被检测到已经过时了。) 新的版本号 (比如前面在前面那个例子中的 `1.0,1`) 在数值上比前一个版本 (20000801) 小， 但多数自动化的工具会认为 `,1` 后缀意味着比前一个包的后缀 `,0` 大。

错误的去除或重置 `PORTEPOCH` 会导致很多不幸发生； 如果您还不明白前面的讨论， 请多阅读几次直至明白为止， 或到邮件列表上来提问。

大多数 port 都不会用到 `PORTEPOCH`， 并且如果某个软件的下一个版本改变了版本号结构的话， 用巧妙的方法来设定 `PORTVERSION` 也能避免使用 `PORTEPOCH`。 然而， FreeBSD porter 也需要注意， 当有新版本的软件发布， 但并非正式版本时 ── 比如 “snapshot” 版本， 原作者可能会使用当时的日期来命名， 这在新的 “官方” 版本发布的时候， 就很容易引起前面提到的问题。

举个例子， 如果 snapshot 版本的发布日期是 20000917， 这个软件的上一个版本是1.2， 那么这个版本的 `PORTVERSIN` 应该设为 1.2.20000917 或类似的样子， 而不是20000917， 这样在 1.3 发布以后， 新版本就可以在数值上大于旧的版本了。

### 5.2.2.3 关于 `PORTREVISION` 和 `PORTEPOCH` 的用例

`gtkmumble` port，版本号 `0.10`， 被提交到 ports collection:

    PORTNAME=       gtkmumble
    PORTVERSION=    0.10

`PKGNAME` 变成 `gtkmumble-0.10`。

然后有人发现了一个安全漏洞， 需要用一个FreeBSD的补丁。 `PORTREVISION` 就要相应的增加。

    PORTNAME=       gtkmumble
    PORTVERSION=    0.10
    PORTREVISION=   1

`PKGNAME`变成了 `gtkmumble-0.10_1`

软件的作者发布了新的版本， 版本为 `0.2` (作者本来的意思是， 用 `0.10` 表示 `0.1.0`，“而不是指 0.9 之后的那个版本” - 但是现在太迟了)。 因为现在的次版本号 `2` 在数值上比上一个版本 `10` 小， `PORTEPOCH` 必须增加， 以使新的 package 被认为是 “更新的”。 由于那是作者发布的一个新版本， 因此 `PORTREVISION` 应被置0 (或者从 `Makefile` 里面删除它)。

    PORTNAME=       gtkmumble
    PORTVERSION=    0.2
    PORTEPOCH=      1

`PKGNAME` 变成了 `gtkmumble-0.2,1`

下一个版本将会是 0.3。 由于 `PORTEPOCH` 从不减少， 那么就无须改动：

    PORTNAME=       gtkmumble
    PORTVERSION=    0.3
    PORTEPOCH=      1

`PKGNAME` 变成 `gtkmumble-0.3,1`

> 注意: 如果在这次升级中 `PORTEPOCH` 被置为了`0`， 那么在装了 `gtkmumble-0.10_1` 包的机器上就无法检测到 `gtkmumble-0.3` 包的更新， 因为 `3` 在数值上比 `10` 小。 记住， 这是 `PORTEPOCH` 最重要的地方。

## 5.2.3 `PKGNAMEPREFIX` 和 `PKGNAMESUFFIX`

2 个可选的变量， `PKGNAMEPREFIX` 和 `PKGNAMESUFFIX` 可以和 `PORTNAME` 还有 `PORTVERSION` 配合使用， 形成像这样的 `PKGNAME`： `${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}`。 请确定符合我们的 包命名规则。 当然， 不 允许在 `PORTVERSION` 中使用连字符 (`-`)。 如果包名有 `language-` 或 `-compiled.specifics` 部分 (见下文)， 请分别用 `PKGNAMEPREFIX` 和 `PKGNAMESUFFIX`， 不要直接加到 `PORTNAME` 中。

## 5.2.4 `LATEST_LINK`

有时， 在 ports 套件中可能会存在同一程序的多个版本。 索引和预编译包的联编系统都需要能够将它们视为不同的软件包， 尽管其 `PORTNAME`、 `PKGNAMEPREFIX`， 以及 even `PKGNAMESUFFIX` 可能是一模一样的。 遇到这种情况时， 就需要将除了 “主” port 之外的其他 port 中的 `LATEST_LINK` 变量设为不同的值 ── 请参见 `editors/vim5` 和 `editors/vim` port， 以及 `www/apache*` 系列， 以了解它的用法。 需要注意的是， 如何确定 “主” 版本 ── “最流行”、 “受支持最好”， “变动最少”， 等等 ── 已经超过了本书能够给出的建议范围； 这里只是向您介绍在选定了一个 “主” port 之后如何指定其他 port 的版本。

## 5.2.5 包命名规则

以下是您在命名您的包时应当遵守的规则。 这将使得我们放包的目录更利于浏览， 因为我们已经有数以万计的包了， 如果用户觉得查看包名很困难的话， 他们会很快走开的。

一个包的名字应该看起来像这样： ``[language[_region]]-name[[-]compiled.specifics]-version.numbers``。

要像这样来定义包的名字： `${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}`。 确保所有的变量符合上面的格式。

1. FreeBSD 会尽力去支持用户当地的语言。 如果这个 port 是某种语言专用的， 那么 `language-` 部分应该是 由 ISO-639 定义的自然语言的 2 个字母缩写。 比如， `ja`是表示日本， `ru` 是表示俄罗斯， `vi` 表示越南， `zh` 表示中国， `ko` 表示韩国， `de` 表示德国。

   如果是针对某种语言的某一地区的话， 再要加上2个字母的国家代码。 例如， `en_US` 表示美国英语， `fr_CH` 表示瑞士法语。

   `language-` 部分应该在 `PKGNAMEPREFIX` 变量里设置。

2. `name` 部分的首字母应该 小写。 (余下的部分可以包含大写字母， 所以当您 要转换一个包含大写字母软件的名字时， 您需要 自己做出判断。) 对于 `Perl 5` 模块的命名， 有个传统的规则是， 在前面 加上 `p5-` 并把两个冒号的部分改为连字号， 如： `Data::Dumper` 模块对应的名字， 就应该是 `p5-Data-Dumper`。

3. 确认 port 的名字和版本之间有清晰的分隔， 并放入 `PORTNAME` 和 `PORTVERSION` 变量。 在 `PORTNAME` 中包含版本部分的唯一理由是上游软件包真的采用这样的命名方式， 类似 `textproc/libxml2` 或 `japanese/kinput2-freewnn` port 这样。 否则， 在 `PORTNAME` 中就不应包含任何版本信息。 许多 port 采用同样的 `PORTNAME` 名字是很正常的， `www/apache*` port 便是如此； 在这种情况下， 不同的版本 (以及不同的索引项) 是由 `PKGNAMEPREFIX`、 `PKGNAMESUFFIX`， 以及 `LATEST_LINK` 的值的不同而有所区别的。

4. 如果 port 可以使用不同的 硬编码默认配置 进行联编 (通常是一系列 port 的一部分目录名)， 则 `-compiled.specifics` 部分就应该明示编译进去的默认值 (此处连字号是可选的)。 通常的用例包括纸型和不同的字体尺寸。

   `-compiled.specifics` 部分应该通过 `PKGNAMESUFFIX` 变量来设置。

5. 版本号应该紧随在连字号 (`-`) 后面并由数字和字母组成。 特别指出， 另外的连字号是不允许出现在版本号里的。 唯一例外的是字符串 `pl` (表示 “patchlevel”)， 只能 用在软件没有主版本号和次版本号的情况下。 如果软件的版本号里出现了像 “alpha”， “beta”， “rc”， “pre”， 取第一个字母把它放在小数点的后面。 如果在版本号里一直出现那些名字， 那么在数字和字母之间不应有多余的小数点。

   这个方法是为了更容易得凭版本号来排序 port。 特别注意的是， 确保版本号之间的每部分都由小数点来分隔， 如果日期也是版本号的一部分， 就用这样的格式， ``yyyy`.`mm`.`dd`` 或者 ``dd`.`mm`.`yyyy`` 这样的格式， 而非 ``yy`.`mm`.`dd`， 因为后者不适合表示千年的格式。`

这里是一些真实的例子， 我们藉此说明如何把软件作者对软件的命名， 转换为适合我们包的命名方式：

发行版的名字 | `PKGNAMEPREFIX` | `PORTNAME` | `PKGNAMESUFFIX` | `PORTVERSION` | 说明
--- | --- | --- | --- | --- | ---
mule-2.2.2 | (空) | mule | (空) | 2.2.2 | 没什么需要修改的
EmiClock-1.0.2 | (空) | emiclock | (空) | 1.0.2 | 程序的名字不能使用大写字母
rdist-1.3alpha | (空) | rdist | (空) | 1.3.a | 像 `alpha` 这样的字符串是不允许出现的
es-0.9-beta1 | (空) | es | (空) | 0.9.b1 | 像 `beta` 这样的字符串是不允许出现的
mailman-2.0rc3 | (空) | mailman | (空) | 2.0.r3 | 像 `rc` 这样的字符串是不允许出现的
v3.3beta021.src | (空) | tiff | (空) | 3.3 | 那个是啥鬼东西？
tvtwm | (空) | tvtwm | (空) | pl11 | 总需要有个版本号吧
piewm | (空) | piewm | (空) | 1.0 | 总需要有个版本号吧
xvgr-2.10pl1 | (空) | xvgr | (空) | 2.10.1 | `pl` 只允许在没有 主/次 版本号的情况下才能出现
gawk-2.15.6 | ja- | gawk | (空) | 2.15.6 | 日文版
psutils-1.13 | (空) | psutils | -letter | 1.13 | 纸张大小已经在编译的时候被硬编码到程序里了
pkfonts | (空) | pkfonts | 300 | 1.0 | 300dpi 字体的包

如果在原始的代码里没有版本号， 或者原作者并不打算开发另外的版本， 就应把版本号设成 `1.0` (就像前面 `piewm` 的例子那样)。 否则， 要求原始的作者加上版本号或使用日期 (``yyyy`.`mm`.`dd``) 来作为版本号。

上一页 | 起始页 | 下一页
配置 Makefile | 上一级 | 分类

若您有关于 FreeBSD ports 系统的问题， 请发送电子邮件至 <ports@FreeBSD.org>。
关于此文档的任何问题， 请致函 <doc@FreeBSD.org>。