在 Makefile
中的第二部分是描述用于联编 port
所必需下载的文件, 以及到什么地方去下载它们。
DISTNAME
是作者称呼您所 port 软件的名字。
DISTNAME
的默认值是
${PORTNAME}-${PORTVERSION}
,
因此只有在需要时才应手工指定。
DISTNAME
只在两个地方用到。 第一处是源码包文件列表
(DISTFILES
), 其默认值是
${DISTNAME}
${EXTRACT_SUFX}
。
第二处是源码包应被展开到的目录名,
即 WRKSRC
所指定的目录,
其默认值是 work/${DISTNAME}
。
某些软件作者发布源码包的时候并不采取
${PORTNAME}-${PORTVERSION}
这样的模式,
这可以通过设置 DISTVERSION
来自动处理。
PORTVERSION
和 DISTNAME
会自动地展开, 当然, 也可以改掉它。 下表给出了一些例子:
DISTVERSION | PORTVERSION |
---|---|
0.7.1d | 0.7.1.d |
10Alpha3 | 10.a3 |
3Beta7-pre2 | 3.b7.p2 |
8:f_17 | 8f.17 |
PKGNAMEPREFIX
和
PKGNAMESUFFIX
并不影响
DISTNAME
。 此外还应注意
WRKSRC
等于
work/${PORTNAME}-${PORTVERSION}
,
而源代码的压缩包则可能是
${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX}
以外的其它名字。 一般情况下应该保持 DISTNAME
不变 ── 更好的方法是定义
DISTFILES
而不是同时设置
DISTNAME
和 WRKSRC
(可能还有 EXTRACT_SUFX
)。
记录 FTP/HTTP-URL 指向 MASTER_SITES
中原始压缩档的目录部分。 不要忘了结尾的斜线
(/
)!
make
宏将尝试使用
FETCH
来抓取所指定的源码包文件,
如果无法在本地系统中找到这些文件的话。
建议您指定多个镜像站点, 最好是在不同的大洲上的。 这样将有效地防止由于大范围网络问题所导致无法下载的问题。 我们甚至打算增加自动检测距离最近的站点并从那里下载的功能; 使用多个站点是这样做的重要一步。
如果原始的源码包可以从比较流行的软件下载站点,
例如 SourceForge、 GNU 或是 Perl CPAN 等等来获得,
您可能会希望使用类似
MASTER_SITE_
这样的缩写来表示它们
(例如 *
MASTER_SITE_SOURCEFORGE
、
MASTER_SITE_GNU
以及
MASTER_SITE_PERL_CPAN
)。 只需将
MASTER_SITES
设为这些变量, 并使用
MASTER_SITE_SUBDIR
来指定路径就可以了。
下面是一个例子:
此外, 您还可以用更为简略的格式:
这些变量是在
/usr/ports/Mk/bsd.sites.mk
中定义的。
新项目会随时增加, 因此在您提交 port 之前,
应先看一看这个文件的最新版本。
针对常用软件下载站的许多 暗黑魔法 宏, 还能够自动判断目录的结构。 对于这些站点, 只要使用与之对应的缩写, 系统便会自动为您生成相关的子目录配置。
如果系统猜测的路径不对, 则可以使用下面这样的配置来替换。
MASTER_SITES
宏宏 | 自动猜测的子目录 |
---|---|
APACHE_JAKARTA | /dist/jakarta/${PORTNAME:S,-,,/,}/source |
BERLIOS | /${PORTNAME:L} |
CHEESESHOP | /packages/source/source/${DISTNAME:C/(.).*/\1/}/${DISTNAME:C/(.*)-[0-9].*/\1/} |
DEBIAN | /debian/pool/main/${PORTNAME:C/^((lib)?.).*$/\1/}/${PORTNAME} |
GCC | /pub/gcc/releases/${DISTNAME} |
GNOME | /pub/GNOME/sources/${PORTNAME}/${PORTVERSION:C/^([0-9]+\.[0-9]+).*/\1/} |
GNU | /gnu/${PORTNAME} |
MOZDEV | /pub/mozdev/${PORTNAME:L} |
PERL_CPAN | /pub/CPAN/modules/by-module/${PORTNAME:C/-.*//} |
PYTHON | /ftp/python/${PYTHON_PORTVERSION:C/rc[0-9]//} |
RUBYFORGE | /${PORTNAME:L} |
SAVANNAH | /${PORTNAME:L} |
SF | /project/${PORTNAME:L}/${PORTNAME:L}/${PORTVERSION} |
如果您有一个源码包文件,
而它使用了某种怪异的扩展名来表达压缩方法, 应设置
EXTRACT_SUFX
。
例如, 如果源码包文件的名字是
foo.tgz
而非更为一般的
foo.tar.gz
, 您应写上:
USE_BZIP2
和 USE_ZIP
变量会自动根据需要将 EXTRACT_SUFX
设置为
.tar.bz2
或 .zip
。
如果这两个都没设置, 则 EXTRACT_SUFX
的
默认值将是 .tar.gz
。
任何时候都不需要同时设置 EXTRACT_SUFX
和
DISTFILES
.
有些时候所下载的文件名字和 port 的名字没有任何联系。
例如, 可能是 source.tar.gz
,
或者与此类似的其它名字。 也有一些其它的应用软件,
它们的源代码可能被存放到了不同的压缩包中, 而且全都需要下载。
如果遇到这种情况, 可以将 DISTFILES
设置为以空格分隔的一组需要下载的文件列表。
如果没有予以明确的设置, DISTFILES
的默认值将是
${DISTNAME}${EXTRACT_SUFX}
。
如果只有一部分 DISTFILES
需要解压缩
── 例如, 其中的一个是源代码, 而其它则是未压缩的文档 ──
此时应把那些需要解压缩的文件加到
EXTRACT_ONLY
中。
如果 DISTFILES
中 没有
需要解压缩的文件, 则应将 EXTRACT_ONLY
设为空串。
如果您的 port 需要来自 FTP 或 HTTP 的一些额外的补丁,
应将 PATCHFILES
设置为这些文件的名字,
并将 PATCH_SITES
指向包含这些文件的目录的 URL
(格式与 MASTER_SITES
相同)。
如果这些补丁, 由于包含了其它的目录名,
而导致它们不是相对于源代码目录的顶级目录
(也就是 WRKSRC
) 的话,
就需要相应地设置 PATCH_DIST_STRIP
了。
例如, 如果补丁中所有的目录名前面都有一个多余的
foozolix-1.0/
, 就应设置
PATCH_DIST_STRIP=-p1
。
不需要担心补丁文件本身是否是压缩的; 如果文件名以
.gz
or .Z
结尾, 系统会自动解压缩。
如果补丁是同某些其它文件, 例如文档, 一同以 gzip 压缩的 tar
格式发布的, 就不能简单地使用
PATCHFILES
了。 这种情况下,
您应将这些补丁包的文件和位置加入到
DISTFILES
和 MASTER_SITES
中。 然后, 用 EXTRA_PATCHES
变量来指出这些文件,
这样 bsd.port.mk
就会自动地为您应用这些补丁了。
需要特别注意的是, 不要 将补丁文件复制到
PATCHDIR
目录中 ── 这个目录可能是不可写的。
压缩包会以同源代码一样的方式解压缩, 因此不需要自行完成解压缩操作,
并复制补丁文件。 如果您一定要这样做, 就要注意,
不要让解压缩出来的文件覆盖先前已经存在的文件。
此外, 这么做还需要手工增加命令,
以便在 pre-clean
target
中删除这些复制出来的文件。
(这一节在某种程度上应被视作 “进阶话题”; 刚开始阅读这份文档的读者可能会希望先跳过这一部分)。
这一节提供了被称作 MASTER_SITES:n
和
MASTER_SITES_NN
的下载控制机制。
这里我们把它们称为 MASTER_SITES:n
。
首先给出一些背景。 OpenBSD 在其 DISTFILES
和
PATCHFILES
变量中提供了一个很棒的功能,
即, 允许这些文件和补丁拥有 :n
后缀, 其中 n
可以使用
[0-9]
, 来表达组。 例如:
在 OpenBSD 中, 源码包文件 alpha
应被关联到变量
MASTER_SITES0
而不是公共的
MASTER_SITES
变量上; 而
beta
则应关联到
MASTER_SITES1
上。
这是一个很有意思的功能, 它可以避免无休止地搜索正确的下载站点的过程。
想象 DISTFILES
中指定了 2 个文件,
而 MASTER_SITES
包含了 20 个站点的情形,
这其中许多站点慢如蜗牛, 而 beta
可以在
MASTER_SITES
的所有站点找到, 而
alpha
只能在第 20 个上面找到。
如果监护人了解这一点, 那么检查所有的站点无疑是在浪费时间,
不是吗? 这显然不是开始一个愉快周末的好办法!
现在您有了一个感性的认识了, 想象一下
DISTFILES
和更多的
MASTER_SITES
。 显然, 我们的
“distfiles 调查员先生”
会感谢您减少他浪费在等待下载上所耗费的时间。
下一节中, 将按照 FreeBSD 对上述想法的实现来加以阐释。 我们对 OpenBSD 所提出的概念进行了一些改进。
这一节将介绍如何迅速地对从不同的站点以及子目录下载多个源码包和补丁进行精确的控制。
这里, 我们将描述 MASTER_SITES:n
的一种简化用法。
对于多数情况而言这样做是足够的。 然而, 如果您需要更多信息,
还需要参考下面的几节。
一些应用程序需要从多个站点下载不同的源码包。 例如, Ghostscript 包括了程序核心本身, 以及大量的驱动文件, 以及则取决于用户的打印机品牌和型号的驱动程序。 某些驱动文件已经随程序核心附带, 但也有很多需要从其它站点下载。
为了适应这种需要, 每一个
DISTFILES
项应跟随一个冒号,
以及一个 “标签名”。 在
MASTER_SITES
的每个站点也应跟随冒号和标签名,
以便指定从哪个网站下载源码包文件。
例如, 考虑一个将源代码包分为两部分,
即 source1.tar.gz
和 source2.tar.gz
的软件,
它必须从两个不同的站点下载。 port 的
Makefile
应包括类似
例 5.1 “简化的 MASTER_SITES:n
用法, 每个文件来自一个站点”
的配置。
MASTER_SITES:n
用法, 每个文件来自一个站点多个源码包可以使用同一个标签。 继续前面的例子,
假定增加了第三个源码包, source3.tar.gz
,
应从 ftp.example2.com
下载。
Makefile
的这部分应写成
例 5.2 “简化的 MASTER_SITES:n
用法,
其中同一个站点上提供了不止一个文件”
的样子。
MASTER_SITES:n
用法,
其中同一个站点上提供了不止一个文件前面的例子无法满足您的需求? 这一节,
我们将详细介绍 MASTER_SITES:n
的精细控制是如何工作的, 以及如何修改您的 port
来使用它们。
元素可以包含
:n
这样的后缀, 其中
n
是
[^:,]+
, 概念上即
n
可以取任意数字或字母,
但我们目前将其限定为
[a-zA-Z_][0-9a-zA-Z_]+
。
此外, 字符串匹配时对大小写是敏感的;
换言之, n
与
N
不同。
但是, 由于表达特殊的意义, 下列单词不能用于后缀:
default
、 all
和
ALL
(它们会在 ii
中介绍的部分用到)。 此外, DEFAULT
是一个有特殊用途的词 (请参见 3)。
后缀为 :n
的项目属于 n
组, 而
:m
属于
m
组, 依此类推。
没有后缀的元素是无组的, 也就是它们都属于那个特殊的
DEFAULT
组。 给元素加入
DEFAULT
后缀通常是多余的,
除非您有同时属于 DEFAULT
和其它组的元素
(参见 5)。
下面的例子是等价的, 但通常应适用第一个:
组之间不是互斥的, 同一元素可以同时隶属于多个组, 而组则可以为空或者有任意多个元素。 同一组中的重复元素, 并不会被自动消去。
如果希望同一元素同时属于多个组, 可以用逗号
(,
) 分开。
这种办法可以避免仅为指定不同的组而多次重复同一元素。 例如
:m,n,o
表示这个元素同时属于
m
、 n
和 o
这三组。
下面这些写法都是等价的, 但只推荐使用最后一种:
同一组中的所有站点, 会根据
MASTER_SORT_AWK
排序。
在 MASTER_SITES
和
PATCH_SITES
中的组也会进行排序。
在 MASTER_SITES
、
PATCH_SITES
、
MASTER_SITE_SUBDIR
、
PATCH_SITE_SUBDIR
、
DISTFILES
, 以及
PATCHFILES
中, 都可以使用组,
其语法为:
所有 MASTER_SITES
、
PATCH_SITES
、
MASTER_SITE_SUBDIR
以及
PATCH_SITE_SUBDIR
的元素, 都必须以
/
字符结尾。 如果有元素属于某些组,
则组后缀
:n
必须出现在终结符
/
之后。
MASTER_SITES:n
机制依赖于
/
的存在, 以避免在 :n
是元素一部分, 而 :n
同时又表示组
n
时发生混淆。 为了兼容性的考虑,
因为之前 /
终结符在
MASTER_SITE_SUBDIR
和
PATCH_SITE_SUBDIR
元素中都不是必需的,
如果后缀所紧跟的字符不是 /
,
则 :n
将被认为是元素的一部分,
而不被当作组后缀, 即使元素拥有 :n
后缀。 请参见 例 5.3 “在 MASTER_SITE_SUBDIR
中
MASTER_SITES:n
的详细用法”
和 例 5.4 “用到逗号分隔符、 多个文件, 多个站点和
不同子目录的 MASTER_SITES:n
详细用法”
以了解进一步的细节。
MASTER_SITE_SUBDIR
中
MASTER_SITES:n
的详细用法组 DEFAULT
中的目录
-> old:n
组 NEW
中的目录
-> new
MASTER_SITES:n
详细用法前述的例子的结果是下述的对于下载行为的精细控制。 站点的列表按照使用的顺序给出。
file1
将从
MASTER_SITE_OVERRIDE
http://site1/directory-trial:1/
http://site1/directory-one/
http://site1/directory/
http://site2/
http://site7/
MASTER_SITE_BACKUP
下载。
file2
将和
file1
以同样的方式下载,
因为它们属于同一组
MASTER_SITE_OVERRIDE
http://site1/directory-trial:1/
http://site1/directory-one/
http://site1/directory/
http://site2/
http://site7/
MASTER_SITE_BACKUP
file3
将从
MASTER_SITE_OVERRIDE
http://site3/
MASTER_SITE_BACKUP
下载。
file4
将从
MASTER_SITE_OVERRIDE
http://site4/
http://site5/
http://site6/
http://site7/
http://site8/directory-one/
MASTER_SITE_BACKUP
下载。
file5
将从
MASTER_SITE_OVERRIDE
MASTER_SITE_BACKUP
下载。
file6
将从
MASTER_SITE_OVERRIDE
http://site8/
MASTER_SITE_BACKUP
下载。
如何对来自
bsd.sites.mk
的特殊变量, 例如
MASTER_SITE_SOURCEFORGE
进行分组?
参见 例 5.5 “MASTER_SITE_SOURCEFORGE
中
MASTER_SITES:n
的详细用法”。
MASTER_SITE_SOURCEFORGE
中
MASTER_SITES:n
的详细用法something.tar.gz
将从所有
MASTER_SITE_SOURCEFORGE
中的站点下载。
如何与 PATCH*
变量连用?
前面的例子介绍的都是
MASTER*
变量,
但对于 PATCH*
也是完全一样的,
它们在 例 5.6 “简化的 PATCH_SITES
中的
MASTER_SITES:n
用法。”
有所介绍。
PATCH_SITES
中的
MASTER_SITES:n
用法。所有普通的 ports 的行为都会保持不变。
MASTER_SITES:n
功能的代码,
只有在某些元素包含了前述, 特别是 7
中所提及语法的
:n
后缀时,
才会启用。
不受影响的 port target:
checksum
、
makesum
、
patch
、
configure
、
build
, 等等。
显然, do-fetch
、
fetch-list
、
master-sites
和
patch-sites
的行为会发生变化。
do-fetch
: 会按照新的、
带有组后缀的
DISTFILES
和
PATCHFILES
在
MASTER_SITES
和
PATCH_SITES
所匹配的组元素, 以及
MASTER_SITE_SUBDIR
和
PATCH_SITE_SUBDIR
来进行。
请参见 例 5.4 “用到逗号分隔符、 多个文件, 多个站点和
不同子目录的 MASTER_SITES:n
详细用法”。
fetch-list
: 和旧式的
fetch-list
类似, 但以同
do-fetch
相似的方式处理组。
master-sites
和
patch-sites
:
(与旧版本不兼容) 仅返回组 DEFAULT
的元素; 事实上, 它们会执行
master-sites-default
和
patch-sites-default
这两个 target。
更进一步, 使用
master-sites-all
或
patch-sites-all
这两个
target 之一, 要比直接检查
MASTER_SITES
或
PATCH_SITES
更好。
此外, 未来版本可能不再保证直接检查能够正确工作。
请参见 B
以了解关于这些新 target 的更多技术细节。
port 中的新 target
一系列
master-sites-
和
n
patch-sites-
target 可以分别用来列出 n
MASTER_SITES
和
PATCH_SITES
中的 n
组的内容。 例如,
master-sites-DEFAULT
和
patch-sites-DEFAULT
都会返回
DEFAULT
组的内容, 而
master-sites-test
和
patch-sites-test
则返回
test
组的内容, 等等。
新增的
master-sites-all
和
patch-sites-all
这两个 target,
会完成先前
master-sites
和
patch-sites
所做的工作。
它们会返回所有组的元素, 就像这些元素都属于同一组一样,
并且会列出与
MASTER_SITE_BACKUP
或
MASTER_SITE_OVERRIDE
中在
DISTFILES
或
PATCHFILES
中指定的同样多个; 分别对于
master-sites-all
和
patch-sites-all
。
避免让您的 port 使
/usr/ports/distfiles
陷入混乱。
如果您的 port 需要下载很多文件, 或者需要下载可能与其它 port
的源文件名冲突的文件 (例如,
Makefile
), 则应将 DIST_SUBDIR
设置为 port 的名字 (通常可以用 ${PORTNAME}
或
${PKGNAMEPREFIX}${PORTNAME}
)。 这将把
DISTDIR
从默认的
/usr/ports/distfiles
改为
/usr/ports/distfiles/DIST_SUBDIR
,
并将与您的 port 有关的文件放到那个目录中。
此外, 它也会在备份文件主服务器 ftp.FreeBSD.org
上查找同一子目录下的文件 (直接在您的
Makefile
中设置 DISTDIR
则不会有这样的效果, 因此您应使用
DIST_SUBDIR
。)
这一设置并不影响您在 Makefile
中定义的 MASTER_SITES
。
如果您的 port 采用的是预编译的包,
但却采用了某种要求源代码必须与预编译版本一同提供的授权,
例如 GPL, 则应使用 ALWAYS_KEEP_DISTFILES
来告诉 FreeBSD 联编集群保留一份在 DISTFILES
中文件的副本。 一般来说这些 port 的用户并不需要这些文件,
因此, 只在定义了
PACKAGE_BUILDING
符的时候,
才将源代码包文件加入 DISTFILES
是个好主意。
ALWAYS_KEEP_DISTFILES
。当您在 DISTFILES
加入其它文件时,
请务必确保这些文件也出现在了 distinfo
中。
此外, 这些额外的文件通常也会展开到
WRKDIR
中, 对于某些 ports,
这可能导致一些不希望的副作用, 因而需要进行特别的处理。
本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读
文档,如不能解决再联系
<questions@FreeBSD.org>.
关于本文档的问题请发信联系
<doc@FreeBSD.org>.