5.4.源代码包文件

Makefile 的第二部分描述了必须下载的文件以构建port以及它们可以在哪里下载。

5.4.1. DISTNAME

DISTNAME 是软件作者称呼 port 的名称。 DISTNAME 默认为 ${PORTNAME}-${DISTVERSIONPREFIX}${DISTVERSION}${DISTVERSIONSUFFIX} ,如果没有设置, DISTVERSION 默认为 ${PORTVERSION} ,所以只有在必要时才覆盖 DISTNAME 。 DISTNAME 仅在两个地方使用。首先,分发文件列表( DISTFILES )默认为 ${DISTNAME}${EXTRACT_SUFX} 。其次,分发文件将被解压到名为 WRKSRC 的子目录中,默认为 work/${DISTNAME}。

一些供应商的分发名称不符合 ${PORTNAME}-${PORTVERSION} 方案,可以通过设置 DISTVERSIONPREFIX 、 DISTVERSION 和 DISTVERSIONSUFFIX 自动处理。 PORTVERSION 将自动从 DISTVERSION 派生。

如果上游版本方案可以转换为ports兼容的版本方案,请将某个变量设置为上游版本,不要使用 DISTVERSION 作为变量名。根据您创建的变量设置 PORTVERSION 为计算版本,并相应地设置 DISTNAME 。

如果上游版本方案不能轻易地转换为ports兼容的值,请将 PORTVERSION 设置为一个合理的值,并用上游版本直接设置 DISTNAME 和 PORTNAME 。

示例 6.手动派生 PORTVERSION

BIND9 使用一种与 ports 版本不兼容的版本方案(其版本中包含 - ),并且不能使用 DISTVERSION 派生版本,因为在 9.9.9 发布后,它将以 9.9.9-P1 形式发布“补丁级别”。DISTVERSION 会将其转换为 9.9.9.p1 ,在 ports 版本方案中意味着 9.9.9 预发布版本 1,位于 9.9.9 之前而不是之后。因此, PORTVERSION 是手动从 ISCVERSION 变量派生而来以输出 9.9.9p1 。

ports 框架和 pkg 排序版本的顺序是使用 pkg-version(8) 的 -t 参数进行检查的:

% pkg version -t 9.9.9 9.9.9.p1
> 
% pkg version -t 9.9.9 9.9.9p1
< 
> 符号意味着传递给 -t 的第一个参数大于第二个参数。 9.9.9 在 9.9.9.p1 之后。

< sign represents the first argument passed to -t is less than the second argument. 9.9.9 before 9.9.9p1 .

In port Makefile, for example dns/bind99, it is achieved by:

PORTNAME=	bind
PORTVERSION=	${ISCVERSION:S/-P/P/:S/b/.b/:S/a/.a/:S/rc/.rc/}
CATEGORIES=	dns net
MASTER_SITES=	ISC/bind9/${ISCVERSION}
PKGNAMESUFFIX=	99
DISTNAME=	${PORTNAME}-${ISCVERSION}

MAINTAINER=	mat@FreeBSD.org
COMMENT=	BIND DNS suite with updated DNSSEC and DNS64
WWW=		https://www.isc.org/bind/

LICENSE=	ISCL

# ISC releases things like 9.8.0-P1 or 9.8.1rc1, which our versioning does not like
ISCVERSION=	9.9.9-P6

Define upstream version in ISCVERSION , with a comment saying why it is needed. Use ISCVERSION to get a ports-compatible PORTVERSION . Use ISCVERSION directly to get the correct URL for fetching the distribution file. Use ISCVERSION directly to name the distribution file.

例 7. 从 PORTVERSION 派生 DISTNAME

有时,发布文件名与软件版本几乎没有关系。

在 comms/kermit 中,发行文件中仅包含版本的最后一个元素:

PORTNAME=	kermit
PORTVERSION=	9.0.304
CATEGORIES=	comms ftp net
MASTER_SITES=	ftp://ftp.kermitproject.org/kermit/test/tar/
DISTNAME=	cku${PORTVERSION:E}-dev20

0 make(1)修改器返回变量的后缀,在本例中是 1。分发文件将正确生成为 2。

示例 8。特殊情况 1

有时,软件名称、版本及其分发的分发文件之间没有关联。

来自音频/libworkman:

PORTNAME=       libworkman
PORTVERSION=    1.4
CATEGORIES=     audio
MASTER_SITES=   LOCAL/jim
DISTNAME=       ${PORTNAME}-1999-06-20

示例 9。异国风情案例 2

在 comms/librs232 中,分发文件没有版本号,因此需要使用 DIST_SUBDIR :

PORTNAME=       librs232
PORTVERSION=    20160710
CATEGORIES=     comms
MASTER_SITES=   http://www.teuniz.net/RS-232/
DISTNAME=       RS-232
DIST_SUBDIR=	${PORTNAME}-${PORTVERSION}

5.4.2. MASTER_SITES

记录指向原始压缩包的 FTP/HTTP-URL 的目录部分在 MASTER_SITES 中。不要忘记结尾的斜杠 (/)!

如果在系统上找不到它们, make 宏将尝试使用该规范从 FETCH 抓取分发文件。

推荐包含多个站点在列表中,最好来自不同的大陆。这将防范广域网问题。

5.4.2.1. 使用 MASTER_SITE_* 变量

快捷缩写可用于流行的存档,如 SourceForge( SOURCEFORGE ),GNU( GNU )或 Perl CPAN( PERL_CPAN )。 MASTER_SITES 可以直接使用它们:

MASTER_SITES=	GNU/make

较旧的扩展格式仍然有效,但所有 ports 已转换为紧凑格式。扩展格式如下所示:

MASTER_SITES=		${MASTER_SITE_GNU}
MASTER_SITE_SUBDIR=	make

这些值和变量在 Mk/bsd.sites.mk 中定义。新条目经常添加,因此在提交 port 之前,请务必检查该文件的最新版本。

MASTER_SITES=	FOO

如果 MASTER_SITE_SUBDIR ,请使用这个:

MASTER_SITES=	FOO/bar

5.4.2.2. 魔法 MASTER_SITES 宏

对于一些在 SourceForge 上有可预测目录结构的流行站点,存在几个“魔法”宏。对于这些站点,只需使用缩写,系统将自动选择子目录。对于以 Stardict 命名的port,版本为 1.2.3 ,并托管在 SourceForge 上的情况,添加这行:

MASTER_SITES=	SF

推断一个名为 /project/stardict/stardict/1.2.3 的子目录。如果推断的目录不正确,可以重写:

MASTER_SITES=	SF/stardict/WyabdcRealPeopleTTS/${PORTVERSION}

这也可以写成

MASTER_SITES=	SF
MASTER_SITE_SUBDIR=	stardict/WyabdcRealPeopleTTS/${PORTVERSION}

表 4. 魔法 MASTER_SITES 宏

假定的子目录

APACHE_COMMONS_BINARIES

${PORTNAME:S,commons-,,}

APACHE_COMMONS_SOURCE

${PORTNAME:S,commons-,,}

APACHE_JAKARTA

${PORTNAME:S,-,/,}/source

BERLIOS

${PORTNAME:tl}.berlios

CHEESESHOP

source/${DISTNAME:C/(.).*/\1/}/${DISTNAME:C/(.*)-[0-9].*/\1/}

CPAN

${PORTNAME:C/-.*//}

DEBIAN

pool/main/${PORTNAME:C/^((lib)?.).*$/\1/}/${PORTNAME}

FARSIGHT

${PORTNAME}

FESTIVAL

${PORTREVISION}

GCC

releases/${DISTNAME}

GENTOO

distfiles

GIMP

${PORTNAME}/${PORTVERSION:R}/

GH

${GH_ACCOUNT}/${GH_PROJECT}/tar.gz/${GH_TAGNAME}?dummy=/

GHC

${GH_ACCOUNT}/${GH_PROJECT}/

GNOME

sources/${PORTNAME}/${PORTVERSION:C/^(\.[0-9]).*/\1/}

GNU

${PORTNAME}

GNUPG

${PORTNAME}

GNU_ALPHA

${PORTNAME}

HORDE

${PORTNAME}

LODEV

${PORTNAME}

MATE

${PORTVERSION:C/^(\.[0-9]).*/\1/}

MOZDEV

${PORTNAME:tl}

NL

${PORTNAME}

QT

archive/qt/${PORTVERSION:R}

SAMBA

${PORTNAME}

SAVANNAH

${PORTNAME:tl}

SF

${PORTNAME:tl}/${PORTNAME:tl}/${PORTVERSION}

5.4.3. USE_GITHUB

如果分发文件来自 GitHub 上的特定提交或标签,而该文件没有官方发布的版本,有一种简单的方法可以自动设置正确的 DISTNAME 和 MASTER_SITES 。

这些变量可用:

表 5. USE_GITHUB 描述|变量|描述|默认值| | ----------| -------------| ---------| | GH_ACCOUNT |托管项目的 GitHub 用户的帐户名称| ${PORTNAME} | | GH_PROJECT |GitHub 上的项目名称| ${PORTNAME} | | GH_TAGNAME |要下载的标签名称(2.0.1、哈希值等)在此处使用分支名称是不正确的。也可以使用提交 ID 的哈希值进行快照。| ${DISTVERSIONPREFIX}${DISTVERSION}${DISTVERSIONSUFFIX} | | GH_SUBDIR |当软件需要在 ${WRKSRC} 中提取额外的分发文件时,可以使用此变量。有关更多信息,请参阅从 GitHub 获取多个文件的示例。|(无)|

示例 10. USE_GITHUB 的简单用法

在尝试为来自 FreeBSD 用户在 github 上 https://github.com/freebsd/pkg/的 pkg 版本 1.2.7 制作port时,Makefile 看起来会像这样(示例中稍微简化):

PORTNAME=	pkg
DISTVERSION=	1.2.7

USE_GITHUB=	yes
GH_ACCOUNT=	freebsd

它会自动将 MASTER_SITES 设置为 GH 并将 WRKSRC 设置为 ${WRKDIR}/pkg-1.2.7 。

示例 11. 更完整地使用 USE_GITHUB

在尝试为 github 上的 FreeBSD 用户创建 bleeding edge 版本的 pkg 时,网址为 https://github.com/freebsd/pkg/,Makefile 最终看起来像这样(为了示例稍作删减):

PORTNAME=	pkg-devel
DISTVERSION=	1.3.0.a.20140411

USE_GITHUB=	yes
GH_ACCOUNT=	freebsd
GH_PROJECT=	pkg
GH_TAGNAME=	6dbb17b

它将自动将 MASTER_SITES 设置为 GH ,并将 WRKSRC 设置为 ${WRKDIR}/pkg-6dbb17b 。

20140411 是引用的提交日期,而不是编辑 Makefile 的日期,或者提交的日期。

例 12. 使用 USE_GITHUB 与 DISTVERSIONPREFIX

时不时, GH_TAGNAME 与 DISTVERSION 稍有不同。例如,如果版本是 1.0.2 ,标签就是 v1.0.2 。在这些情况下,可以使用 DISTVERSIONPREFIX 或 DISTVERSIONSUFFIX :

PORTNAME=	foo
DISTVERSIONPREFIX=	v
DISTVERSION=	1.0.2

USE_GITHUB=	yes

它会自动将 GH_TAGNAME 设置为 v1.0.2 ,而 WRKSRC 将保持为 ${WRKDIR}/foo-1.0.2 。

示例 13. 在上游不使用版本时使用 USE_GITHUB

如果上游没有版本,不要发明类似 0.1 或 1.0 的版本。使用 port 创建, DISTVERSION 的 gYYYYMMDD ,其中 g 是 Git, YYYYMMDD 代表在 GH_TAGNAME 中引用的提交日期。

PORTNAME=	bar
DISTVERSION=	g20140411

USE_GITHUB=	yes
GH_TAGNAME=	c472d66b

这会创建一个随时间增加的版本控制方案,并且仍在版本 0 之前(有关 pkg-version(8) 详细信息,请参阅使用 pkg-version(8) 进行版本比较)。

% pkg version -t g20140411 0
<

这意味着如果上游将来决定发布版本,将不需要使用 PORTEPOCH 。

示例 14. 使用 USE_GITHUB 访问两个版本之间的提交

如果软件的当前版本使用了 Git 标签,并且需要将 port 更新到一个新的中间版本(没有标签),可以使用 git-describe(1) 查找要使用的版本:

% git describe --tags f0038b1
v0.7.3-14-gf0038b1

v0.7.3-14-gf0038b1 可以分为三个部分:

v0.7.3 这是在请求的提交之前提交历史中出现的最后一个 Git 标签。

-14 这意味着请求的提交, f0038b1 ,是在 v0.7.3 标签之后的第 14 次提交。

-gf0038b1 -g 意味着 "Git",而 f0038b1 是此引用指向的提交哈希。

PORTNAME=	bar
DISTVERSIONPREFIX=  v
DISTVERSION=	0.7.3-14
DISTVERSIONSUFFIX=  -gf0038b1

USE_GITHUB=	yes

这会创建一个随时间(也就是随提交)递增的版本方案,并且不会与创建 0.7.4 版本冲突。(有关 pkg-version(8)的版本比较细节,请参阅如何使用 pkg-version(8)进行版本比较):

% pkg version -t 0.7.3 0.7.3.14
<
% pkg version -t 0.7.3.14 0.7.4
<

如果请求的提交与标签相同,则默认显示较短描述。较长版本等效:

% git describe --tags c66c71d
v0.7.3

% git describe --tags --long c66c71d
v0.7.3-0-gc66c71d

5.4.3.1. 从 GitHub 获取多个文件

该 USE_GITHUB 框架还支持从 GitHub 的不同位置获取多个分发文件。它的工作方式与从多个位置获取多个分发或补丁文件非常相似。

多个值被添加到 GH_ACCOUNT , GH_PROJECT 和 GH_TAGNAME 。每个不同的值被分配到一个组。主要值可以没有组,也可以是 :DEFAULT 组。如果值与 USE_GITHUB 中列出的默认值相同,则可以省略该值的描述。

当有大量分发文件时, GH_TUPLE 也可以使用。它有助于将账户、项目、标签名和组信息保持在同一位置。

对于每个组,会创建一个 ${WRKSRC_group} 辅助变量,其中包含文件已提取到的目录。可以使用 ${WRKSRC_group} 变量在 post-extract 期间移动目录,或添加到 CONFIGURE_ARGS ,或根据需要使软件正确构建。

:group 部分必须仅用于一个分发文件。它被用作唯一键,并且多次使用将覆盖先前的值。

从 GitHub 获取多个文件时,有时无法从 GitHub 获取默认的分发文件。要禁用获取默认的分发文件,请设置:

USE_GITHUB=	nodefault
DISTFILES=    ${DISTNAME}${EXTRACT_SUFX}

示例 15. 使用 USE_GITHUB 与多个分发文件

有时需要获取多个分发文件,例如当上游 git 仓库使用子模块时。可以通过 GH_* 变量中的组轻松完成这一操作:

PORTNAME=	foo
DISTVERSION=	1.0.2

USE_GITHUB=	yes
GH_ACCOUNT=	bar:icons,contrib
GH_PROJECT=	foo-icons:icons foo-contrib:contrib
GH_TAGNAME=	1.0:icons fa579bc:contrib
GH_SUBDIR=	ext/icons:icons

CONFIGURE_ARGS=	--with-contrib=${WRKSRC_contrib}

这将从 github 获取三个发行文件。默认的来自 foo/foo,版本为 1.0.2 。第二个,属于 icons 组,来自 bar/foo-icons,版本为 1.0 。第三个来自 bar/foo-contrib,使用 Git 提交 fa579bc 。发行文件名为 foo-foo-1.0.2_GH0.tar.gz、bar-foo-icons-1.0_GH0.tar.gz 和 bar-foo-contrib-fa579bc_GH0.tar.gz。

所有发行文件都提取到 ${WRKDIR} 的各自子目录中。默认文件仍提取到 ${WRKSRC} ,在这种情况下,为 ${WRKDIR}/foo-1.0.2。每个附加发行文件提取到 ${WRKSRC_group} 。这里,对于 icons 组,它被称为 ${WRKSRC_icons} ,包含 ${WRKDIR}/foo-icons-1.0。属于 contrib 组的文件被称为 ${WRKSRC_contrib} ,包含 ${WRKDIR}/foo-contrib-fa579bc 。

该软件的构建系统期望在其源文件中的 ext/icons 子目录中找到图标,所以使用了 GH_SUBDIR 。 GH_SUBDIR 确保 ext 存在,但 ext/icons 不存在。然后执行以下操作:

post-extract:
      @${MV} ${WRKSRC_icons} ${WRKSRC}/ext/icons

使用 USE_GITHUB 与多个分发文件一起使用 GH_TUPLE 的示例 16

这在功能上等同于与多个分发文件一起使用 USE_GITHUB ,但是使用 GH_TUPLE :

PORTNAME=	foo
DISTVERSION=	1.0.2

USE_GITHUB=	yes
GH_TUPLE=	bar:foo-icons:1.0:icons/ext/icons \
		bar:foo-contrib:fa579bc:contrib

CONFIGURE_ARGS=	--with-contrib=${WRKSRC_contrib}

在上一个示例中使用了分组与 bar:icons,contrib 。由于无法进行分组,因此使用 GH_TUPLE 存在一些冗余信息。

示例 17. 如何在 Git 子模块中使用 USE_GITHUB ?

Ports作为上游存储库时有时使用子模块。有关更多信息,请参见 git-submodule(1)。

子模块的问题在于每个子模块都是单独的存储库。因此,它们必须分别获取。

使用 finance/moneymanagerex 作为一个例子,其 GitHub 仓库在 https://github.com/moneymanagerex/moneymanagerex/。它在根目录下有一个 .gitmodules 文件。这个文件描述了该仓库中使用的所有子模块,并列出了需要的额外仓库。这个文件将告诉您需要哪些额外的仓库:

[submodule "lib/wxsqlite3"]
	path = lib/wxsqlite3
	url = https://github.com/utelle/wxsqlite3.git
[submodule "3rd/mongoose"]
	path = 3rd/mongoose
	url = https://github.com/cesanta/mongoose.git
[submodule "3rd/LuaGlue"]
	path = 3rd/LuaGlue
	url = https://github.com/moneymanagerex/LuaGlue.git
[submodule "3rd/cgitemplate"]
	path = 3rd/cgitemplate
	url = https://github.com/moneymanagerex/html-template.git
[...]

唯一缺失的信息是要用作版本的提交哈希或标签。此信息在克隆仓库后可以找到:

% git clone --recurse-submodules https://github.com/moneymanagerex/moneymanagerex.git
Cloning into 'moneymanagerex'...
remote: Counting objects: 32387, done.
[...]
Submodule '3rd/LuaGlue' (https://github.com/moneymanagerex/LuaGlue.git) registered for path '3rd/LuaGlue'
Submodule '3rd/cgitemplate' (https://github.com/moneymanagerex/html-template.git) registered for path '3rd/cgitemplate'
Submodule '3rd/mongoose' (https://github.com/cesanta/mongoose.git) registered for path '3rd/mongoose'
Submodule 'lib/wxsqlite3' (https://github.com/utelle/wxsqlite3.git) registered for path 'lib/wxsqlite3'
[...]
Cloning into '/home/mat/work/freebsd/ports/finance/moneymanagerex/moneymanagerex/3rd/LuaGlue'...
Cloning into '/home/mat/work/freebsd/ports/finance/moneymanagerex/moneymanagerex/3rd/cgitemplate'...
Cloning into '/home/mat/work/freebsd/ports/finance/moneymanagerex/moneymanagerex/3rd/mongoose'...
Cloning into '/home/mat/work/freebsd/ports/finance/moneymanagerex/moneymanagerex/lib/wxsqlite3'...
[...]
Submodule path '3rd/LuaGlue': checked out 'c51d11a247ee4d1e9817dfa2a8da8d9e2f97ae3b'
Submodule path '3rd/cgitemplate': checked out 'cd434eeeb35904ebcd3d718ba29c281a649b192c'
Submodule path '3rd/mongoose': checked out '2140e5992ab9a3a9a34ce9a281abf57f00f95cda'
Submodule path 'lib/wxsqlite3': checked out 'fb66eb230d8aed21dec273b38c7c054dcb7d6b51'
[...]
% cd moneymanagerex
% git submodule status
 c51d11a247ee4d1e9817dfa2a8da8d9e2f97ae3b 3rd/LuaGlue (heads/master)
 cd434eeeb35904ebcd3d718ba29c281a649b192c 3rd/cgitemplate (cd434ee)
 2140e5992ab9a3a9a34ce9a281abf57f00f95cda 3rd/mongoose (6.2-138-g2140e59)
 fb66eb230d8aed21dec273b38c7c054dcb7d6b51 lib/wxsqlite3 (v3.4.0)
[...]

它也可以在 GitHub 上找到。每个作为子模块的子目录显示为 directory @ hash ,例如, mongoose @ 2140e59 。

从 GitHub 获取信息似乎更为直接,而使用 git submodule status 所找到的信息将提供更有意义的信息。例如,在这里, lib/wxsqlite3 的提交哈希 fb66eb2 对应于 v3.4.0 。两者可以互换使用,但如果有标签可用,则使用标签。

现在,已收集到所有所需信息,可以编写 Makefile(仅显示 GitHub 相关行):

PORTNAME=	moneymanagerex
DISTVERSIONPREFIX=	v
DISTVERSION=	1.3.0

USE_GITHUB=	yes
GH_TUPLE=	utelle:wxsqlite3:v3.4.0:wxsqlite3/lib/wxsqlite3 \
		moneymanagerex:LuaGlue:c51d11a:lua_glue/3rd/LuaGlue \
		moneymanagerex:html-template:cd434ee:html_template/3rd/cgitemplate \
		cesanta:mongoose:2140e59:mongoose/3rd/mongoose \
		[...]

5.4.4. USE_GITLAB

类似于 GitHub,如果分发文件来自 gitlab.com 或托管 GitLab 软件,则这些变量可供使用,可能需要设置。

表格 6. USE_GITLAB 描述

变量描述默认

GL_SITE

托管 GitLab 项目的站点名称

GL_ACCOUNT

托管项目的 GitLab 用户帐户名称

${PORTNAME}

GL_PROJECT

在 GitLab 上的项目名称

${PORTNAME}

GL_COMMIT

下载的提交哈希。必须是完整的 160 位,40 字符的十六进制 SHA1 哈希。这是 GitLab 的必需变量。

(none)

GL_SUBDIR

当软件需要在 ${WRKSRC} 中提取另一个分发文件时,可以使用此变量。有关更多信息,请参阅从 GitLab 获取多个文件中的示例。

(无)

示例 18. 使用 USE_GITLAB 的简单示例

在尝试为 https://gitlab.com/accounts-sso/libsignon-glib/ 上的 accounts-sso 用户版本 1.14 的 libsignon-glib 进行port时,Makefile 最终将如下所示来获取分发文件:

PORTNAME=	libsignon-glib
DISTVERSION=	1.14

USE_GITLAB=	yes
GL_ACCOUNT=	accounts-sso
GL_COMMIT=	e90302e342bfd27bc8c9132ab9d0ea3d8723fd03

它將自動將 MASTER_SITES 設置為 gitlab.com,將 WRKSRC 設置為 ${WRKDIR}/libsignon-glib-e90302e342bfd27bc8c9132ab9d0ea3d8723fd03-e90302e342bfd27bc8c9132ab9d0ea3d8723fd03 。

例 19。更完整地使用 USE_GITLAB

如果上述port沒有版本控制,並且來自自託管 GitLab 站點的 foo 用戶項目欄位的 foobar https://gitlab.example.com/ ,那麼 Makefile 最終看起來會是這樣來獲取分發文件:

PORTNAME=	foobar
DISTVERSION=	g20170906

USE_GITLAB=	yes
GL_SITE=	https://gitlab.example.com
GL_ACCOUNT=	foo
GL_PROJECT=	bar
GL_COMMIT=	9c1669ce60c3f4f5eb43df874d7314483fb3f8a6

MASTER_SITES 設為 "https://gitlab.example.com" 並將 WRKSRC 設為 ${WRKDIR}/bar-9c1669ce60c3f4f5eb43df874d7314483fb3f8a6-9c1669ce60c3f4f5eb43df874d7314483fb3f8a6 。

5.4.4.1. 从 GitLab 获取多个文件

USE_GITLAB 框架也支持从 GitLab 和 GitLab 托管站点获取多个分发文件。其工作方式与从多个位置获取多个分发或补丁文件以及从 GitLab 获取多个文件非常相似。

多个值被添加到 GL_SITE , GL_ACCOUNT , GL_PROJECT 和 GL_COMMIT 中。每个不同的值都分配给一个组。 USE_GITLAB 描述。

当有大量分发文件时,也可以使用 GL_TUPLE 。它有助于将站点、帐户、项目、提交和组信息保持在同一位置。

对于每个组,会创建一个 ${WRKSRC_group} 辅助变量,其中包含文件已提取到的目录。 ${WRKSRC_group} 变量可以在 post-extract 期间移动目录,或添加到 CONFIGURE_ARGS ,或任何需要软件构建正确的操作。

:group 部分必须仅用于一个分发文件。它被用作唯一键,多次使用将覆盖先前的值。

当使用 GitLab 获取多个文件时,有时不会从 GitLab 站点获取默认分发文件。要禁用获取默认分发,请设置:

USE_GITLAB=	nodefault
DISTFILES=    ${DISTNAME}${EXTRACT_SUFX}

示例 20. 使用 USE_GITLAB 与多个分发文件

有时候,需要获取多个分发文件。例如,当上游 git 仓库使用子模块时。这可以通过 GL_* 变量中的组轻松完成:

PORTNAME=	foo
DISTVERSION=	1.0.2

USE_GITLAB=	yes
GL_SITE=	https://gitlab.example.com:9434/gitlab:icons
GL_ACCOUNT=	bar:icons,contrib
GL_PROJECT=	foo-icons:icons foo-contrib:contrib
GL_COMMIT=	c189207a55da45305c884fe2b50e086fcad4724b ae7368cab1ca7ca754b38d49da064df87968ffe4:icons 9e4dd76ad9b38f33fdb417a4c01935958d5acd2a:contrib
GL_SUBDIR=	ext/icons:icons

CONFIGURE_ARGS= --with-contrib=${WRKSRC_contrib}

这将从 gitlab.com 获取两个分发文件,一个来自 gitlab.example.com 托管的 GitLab。默认的文件来自 https://gitlab.com/foo/foo,提交是 c189207a55da45305c884fe2b50e086fcad4724b 。第二个文件来自 icons 组,来自 https://gitlab.example.com:9434/gitlab/bar/foo-icons,提交是 ae7368cab1ca7ca754b38d49da064df87968ffe4 。第三个文件来自 https://gitlab.com/bar/foo-contrib,提交是 9e4dd76ad9b38f33fdb417a4c01935958d5acd2a 。分发文件命名为 foo-foo-c189207a55da45305c884fe2b50e086fcad4724b_GL0.tar.gz、bar-foo-icons-ae7368cab1ca7ca754b38d49da064df87968ffe4_GL0.tar.gz 和 bar-foo-contrib-9e4dd76ad9b38f33fdb417a4c01935958d5acd2a_GL0.tar.gz。

所有分发文件都在 ${WRKDIR} 中各自的子目录中提取。默认文件仍在 ${WRKSRC} 中提取,在此例中是${WRKDIR}/foo-c189207a55da45305c884fe2b50e086fcad4724b-c189207a55da45305c884fe2b50e086fcad4724b。每个额外的分发文件都在 ${WRKSRC_group} 中提取。在 icons 组中,它被称为 ${WRKSRC_icons} ,其中包含${WRKDIR}/foo-icons-ae7368cab1ca7ca754b38d49da064df87968ffe4-ae7368cab1ca7ca754b38d49da064df87968ffe4。具有 contrib 组的文件称为 ${WRKSRC_contrib} ,含有 ${WRKDIR}/foo-contrib-9e4dd76ad9b38f33fdb417a4c01935958d5acd2a-9e4dd76ad9b38f33fdb417a4c01935958d5acd2a 。

软件建构系统期望在其源代码的 ext/icons 子目录中找到图标,因此使用 GL_SUBDIR 。 GL_SUBDIR 确保 ext 存在,但 ext/icons 不存在。然后它这样做:

post-extract:
        @${MV} ${WRKSRC_icons} ${WRKSRC}/ext/icons

示例 21. 使用 USE_GITLAB 与使用多个发行文件 GL_TUPLE

这在功能上等同于使用多个发行文件,但使用 USE_GITLAB :

PORTNAME=	foo
DISTVERSION=	1.0.2

USE_GITLAB=	yes
GL_COMMIT=	c189207a55da45305c884fe2b50e086fcad4724b
GL_TUPLE=	https://gitlab.example.com:9434/gitlab:bar:foo-icons:ae7368cab1ca7ca754b38d49da064df87968ffe4:icons/ext/icons \
		bar:foo-contrib:9e4dd76ad9b38f33fdb417a4c01935958d5acd2a:contrib

CONFIGURE_ARGS= --with-contrib=${WRKSRC_contrib}

在之前的示例中使用了分组 bar:icons,contrib 。由于无法分组,一些冗余信息存在 GL_TUPLE 。

5.4.5. EXTRACT_SUFX

如果有一个分发文件,并且它使用奇数后缀来指示压缩机制,请设置 EXTRACT_SUFX 。

例如,如果分发文件命名为 foo.tar.gzip 而不是更常见的 foo.tar.gz,请写:

DISTNAME=	foo
EXTRACT_SUFX=	.tar.gzip

USES=tar[:xxx] , USES=lha 或 USES=zip 会根据需要自动将 EXTRACT_SUFX 设置为最常见的归档扩展名,有关详细信息,请参见 使用 USES 宏。 如果这些都未设置,则 EXTRACT_SUFX 默认为 .tar.gz 。

5.4.6. DISTFILES

有时,要下载的文件名称与port 的名称毫无相似之处。 例如,它可能被称为 source.tar.gz 或类似名称。 在其他情况下,应用程序的源代码可能位于几种不同的归档文件中,所有这些文件都必须下载。

如果是这种情况,请将 DISTFILES 设置为需要下载的所有文件的空格分隔列表。

DISTFILES=	source1.tar.gz source2.tar.gz

如果没有明确设置, DISTFILES 默认为 ${DISTNAME}${EXTRACT_SUFX} 。

5.4.7. EXTRACT_ONLY

如果只有一些 DISTFILES 需要提取,例如其中一个是源代码,另一个是未压缩文档,请在 EXTRACT_ONLY 中列出必须提取的文件名。

DISTFILES=	source.tar.gz manual.html
EXTRACT_ONLY=	source.tar.gz

当没有 DISTFILES 需要解压缩时,将 EXTRACT_ONLY 设置为空字符串。

EXTRACT_ONLY=

5.4.8. PATCHFILES

如果port需要一些可以通过 FTP 或 HTTP 获得的额外补丁,请将 PATCHFILES 设置为文件名,并将 PATCH_SITES 设置为包含它们的目录的 URL(格式与 MASTER_SITES 相同)。

如果补丁不是相对于源代码树的顶部(即 WRKSRC )因为它包含一些额外的路径名,请相应地设置 PATCH_DIST_STRIP 。例如,如果补丁中的所有路径名前都有一个额外的 foozolix-1.0/ ,则设置 PATCH_DIST_STRIP=-p1 。

不要担心补丁是否已压缩;如果文件名以.Z、.gz、.bz2 或.xz 结尾,它们将自动解压缩。

如果补丁与其他文件一起分发,比如在一个压缩的 tarball 中包含文档,使用 PATCHFILES 是不可能的。如果是这种情况,请将补丁 tarball 的名称和位置添加到 DISTFILES 和 MASTER_SITES 。然后,使用 EXTRA_PATCHES 指向这些文件,bsd.port.mk 会自动应用它们。特别是不要将补丁文件复制到${PATCHDIR}中。该目录可能不可写。

PATCHFILES=	patch1 patch2:-p1

这不会与主站点分组功能发生冲突,添加一个组也是有效的:

PATCHFILES=	patch2:-p1:source2

5.4.9. 从多个位置获取多个发行版或补丁文件

(将其视为一个有些“高级主题”; 刚接触本文档的人可能希望先跳过此部分)。

本部分介绍了被称为 MASTER_SITES:n 和 MASTER_SITES_NN 的提取机制。我们将这种机制称为 MASTER_SITES:n 。

首先来点背景。OpenBSD 在 DISTFILES 和 PATCHFILES 中有一个很棒的特性,允许文件和补丁带有 :n 标识符。在这里, n 可以是包含 [0-9a-zA-Z_] 的任何单词,表示一个组别指定。例如:

DISTFILES=	alpha:0 beta:1

在 OpenBSD 中,分发文件 alpha 将与变量 MASTER_SITES0 关联,而非我们常见的 MASTER_SITES 和 beta 与 MASTER_SITES1 。

这是一个非常有趣的功能,可以减少对正确下载站点的无尽搜索。

想象一下在 DISTFILES 和 20 个站点中有 2 个文件,站点速度极慢,所有站点都载有 beta 版本,而 alpha 版本只能在第 20 个站点找到。如果维护者事先知道这些,要检查所有站点将是一种浪费,不是吗?这对美好的周末来说并不是一个好的开端!

现在你有了这个想法,想象更多的 DISTFILES 和更多的 MASTER_SITES 。我们的“distfiles 调查大师”肯定会欣赏这将带来的减轻网络负担的效果。

在接下来的部分中,将会提供有关这个想法在 FreeBSD 上的实现的信息。我们在 OpenBSD 的概念上有所改进。

5.4.9.1. 简化信息

本节将解释如何快速准备从不同站点和子目录中获取多个分发文件和补丁。我们在这里描述了一个简化 MASTER_SITES:n 使用情况。这将对大多数情景足够。更详细的信息可在详细信息中找到。

一些应用程序由必须从许多不同站点下载的多个分发文件组成。例如,Ghostscript 由程序的核心以及根据用户的打印机使用的大量驱动程序文件组成。其中一些驱动程序文件随核心提供,但许多其他文件必须从各种不同站点下载。

为支持此功能, DISTFILES 中的每个条目后面都可以跟着一个冒号和一个“组名”。然后每个在 MASTER_SITES 中列出的站点后面都跟着一个冒号,指示从该站点下载哪些分发文件的组。

例如,考虑一个应用程序,其源代码分为两部分,source1.tar.gz 和 source2.tar.gz,必须从两个不同的站点下载。port 的 Makefile 将包括类似于使用简化 MASTER_SITES:n 每个站点一个文件的行。

示例 22. 使用简化 MASTER_SITES:n 每个站点一个文件

MASTER_SITES=	ftp://ftp1.example.com/:source1 \
		http://www.example.com/:source2
DISTFILES=	source1.tar.gz:source1 \
		source2.tar.gz:source2

多个发布文件可以具有相同的组。继续上一个示例,假设有第三个发布文件,source3.tar.gz,它从 ftp.example2.com 下载。然后 Makefile 将写成使用简化 MASTER_SITES:n 每个站点多个文件。

例 23. 更简化的使用 MASTER_SITES:n ,一个站点对应多个文件

MASTER_SITES=	ftp://ftp.example.com/:source1 \
		http://www.example.com/:source2
DISTFILES=	source1.tar.gz:source1 \
		source2.tar.gz:source2 \
		source3.tar.gz:source2

5.4.9.2. 详细信息

好吧,之前的例子没有反映新 port 的需求?在本节中,我们将详细解释细粒度提取机制 MASTER_SITES:n 的工作原理及如何使用。

  1. 元素可以后缀为 :n ,其中 n 是``,也就是说,n 可以概念上是任何字母数字字符串,但我们现在将其限制为 [a-zA-Z_][0-9a-zA-Z_] 。此外,字符串匹配是区分大小写的;也就是说, n 与 N 是不同的。 然而,这些词不能用于后缀目的,因为它们具有特殊含义: default 、 all 和 ALL (它们在项 ii 中内部使用)。此外, DEFAULT 是一个特殊用途词(查看项目 3)。

  2. 后缀为 :n 的元素属于 n 组, :m 属于 m 组,依此类推。

  3. 没有后缀的元素是无组的,它们都属于特殊组 DEFAULT 。除非一个元素同时属于 DEFAULT 和其他组(查看项目 5),否则带有 DEFAULT 后缀的元素只是多余的。这些示例是等效的,但首选第一个:

    MASTER_SITES=	alpha
    MASTER_SITES=	alpha:DEFAULT
  4. 组不是排他的,一个元素可以同时属于几个不同的组,一个组可以有几个不同的元素,也可以没有任何元素。

  5. 当一个元素同时属于几个组时,使用逗号运算符( , )。不必重复多次,并每次使用不同的后缀,我们可以一次列出一组在一个后缀内。例如, :m,n,o 标记一个属于组 m 、 n 和 o 的元素。 所有这些示例都是等效的,但最后一个是首选:

    MASTER_SITES=	alpha alpha:SOME_SITE
    MASTER_SITES=	alpha:DEFAULT alpha:SOME_SITE
    MASTER_SITES=	alpha:SOME_SITE,DEFAULT
    MASTER_SITES=	alpha:DEFAULT,SOME_SITE
  6. 在给定组内,所有网站都根据 MASTER_SORT_AWK 进行排序。 MASTER_SITES 和 PATCH_SITES 内的所有组也是如此。

  7. 组语义可以用于任何变量 MASTER_SITES 、 PATCH_SITES 、 MASTER_SITE_SUBDIR 、 PATCH_SITE_SUBDIR 、 DISTFILES 和 PATCHFILES 中,按照此语法:

    1. 所有 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 。查看详细使用 MASTER_SITES:n 以及 MASTER_SITE_SUBDIR 和详细使用 MASTER_SITES:n 结合逗号运算符、多个文件、多个站点和多个子目录的例子 24。详细使用 MASTER_SITES:n 在 MASTER_SITE_SUBDIR 中

      MASTER_SITE_SUBDIR=	old:n new/:NEW
      • 组 DEFAULT 内的目录 → old:n

      • 组 NEW 内的目录 → new

      例 25. 使用 MASTER_SITES:n 运算符、多个文件、多个站点和多个子目录的详细示例

      MASTER_SITES=	http://site1/%SUBDIR%/ http://site2/:DEFAULT \
      		http://site3/:group3 http://site4/:group4 \
      		http://site5/:group5 http://site6/:group6 \
      		http://site7/:DEFAULT,group6 \
      		http://site8/%SUBDIR%/:group6,group7 \
      		http://site9/:group8
      DISTFILES=	file1 file2:DEFAULT file3:group3 \
      		file4:group4,group5,group6 file5:grouping \
      		file6:group7
      MASTER_SITE_SUBDIR=	directory-trial:1 directory-n/:groupn \
      		directory-one/:group6,DEFAULT \
      		directory

      前面的例子导致这种精细化的获取。站点按照它们将被使用的确切顺序列出。

  8. 我如何将 bsd.sites.mk 中的一个特殊宏分组,例如,SourceForge( SF )?这已经尽可能简化了。请参见 SourceForge( SF )的详细使用 MASTER_SITES:n 。 使用 SourceForge 进行 MASTER_SITES:n 的详细用法( SF )

    MASTER_SITES=	http://site1/ SF/something/1.0:sourceforge,TEST
    DISTFILES=	something.tar.gz:sourceforge

    something.tar.gz 将从 SourceForge 中的所有站点获取。

  9. 我如何使用 PATCH* 与此?所有示例均使用 MASTER* 完成,但它们对于 PATCH* 也完全相同,如简化用法中所示 MASTER_SITES:n 与 PATCH_SITES 一样。 简化使用 MASTER_SITES:n 和 PATCH_SITES 的示例 27。

    PATCH_SITES=	http://site1/ http://site2/:test
    PATCHFILES=	patch1:test

5.4.9.3. Ports 会发生什么变化?什么不会?

  1. 所有当前的 ports 保持不变。仅当元素后缀为 :n 时才会激活 MASTER_SITES:n 功能代码,尤其如第七项中所示的语法规则。

  2. 目标保持不变: 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 中的匹配组元素进行配对。检查详细使用 MASTER_SITES:n ,包括逗号操作符、多文件、多站点和多子目录。

    • fetch-list :与旧 fetch-list 类似,唯一的区别是它仅像 do-fetch 一样进行分组。

    • master-sites 和 patch-sites :(与旧版本不兼容)仅返回 DEFAULT 组的元素;实际上,它们分别执行目标 master-sites-default 和 patch-sites-default 。此外,优先使用目标 master-sites-all 或 patch-sites-all ,而不是直接检查 MASTER_SITES 或 PATCH_SITES 。直接检查在任何未来版本中都不能保证有效。有关这些新port目标的更多信息,请查看项目 B。

  3. 新port目标

    1. 有 master-sites-n 和 patch-sites-n 目标,将列出相应组 n 中的元素 MASTER_SITES 和 PATCH_SITES 。例如, master-sites-DEFAULT 和 patch-sites-DEFAULT 将返回组 DEFAULT 的元素, master-sites-test 和 patch-sites-test 将返回组 test 的元素,以此类推。

    2. 新的 master-sites-all 和 patch-sites-all 目标做旧的 master-sites 和 patch-sites 的工作。它们返回所有组的元素,就好像它们都属于同一组,但要注意,它列出与 DISTFILES 或 PATCHFILES 中定义的组数量相同的 MASTER_SITE_BACKUP 和 MASTER_SITE_OVERRIDE ;分别对于 master-sites-all 和 patch-sites-all 。

5.4.10. DIST_SUBDIR

不要让port混乱/usr/ports/distfiles。如果port需要获取很多文件,或包含可能与其他ports(例如 Makefile)冲突的文件,请将 DIST_SUBDIR 设置为port的名称( ${PORTNAME} 或 ${PKGNAMEPREFIX}${PORTNAME} 可行)。这将把port所需的所有内容放入该子目录下,从默认的/usr/ports/distfiles 更改为/usr/ports/distfiles/${DIST_SUBDIR,实际上将所有内容放入该子目录。

它还将查看 http://distcache.FreeBSD.org 上备份主站点上具有相同名称的子目录(在 Makefile 中明确设置 DISTDIR 将无法完成此操作,请使用 DIST_SUBDIR 。)

最后更新于

FreeBSD 中文社区