5.4.源代码包文件
5.4.1. DISTNAME
DISTNAMEDISTNAME 是由软件的作者指定的名称。DISTNAME 默认为 ${PORTNAME}-${DISTVERSIONPREFIX}${DISTVERSION}${DISTVERSIONSUFFIX},如果未设置,则 DISTVERSION 默认为 ${PORTVERSION},因此只有在必要时才需要覆盖 DISTNAME。DISTNAME 只在两个地方使用。首先,分发文件列表(DISTFILES)默认值为 ${DISTNAME}${EXTRACT_SUFX}。其次,分发文件预计会解压到一个名为 WRKSRC 的子目录中,默认值为 work/${DISTNAME}。
一些厂商的分发名称不适合 ${PORTNAME}-${PORTVERSION} 方案时,可以通过设置 DISTVERSIONPREFIX、DISTVERSION 和 DISTVERSIONSUFFIX 来自动处理。PORTVERSION 会从 DISTVERSION 自动派生。
重要
PORTVERSION和DISTVERSION只能设置其中一个。如果DISTVERSION无法派生出正确的PORTVERSION,则不要使用DISTVERSION。
如果上游版本方案可以派生为与 Port 兼容的版本方案,请设置一个变量来表示上游版本,不要 使用 DISTVERSION 作为变量名。根据你创建的变量将 PORTVERSION 设置为计算出的版本,并相应地设置 DISTNAME。
如果上游版本方案无法轻松转换为兼容的 Port 版本值,请将 PORTVERSION 设置为一个合理的值,并将 DISTNAME 设置为包含上游版本的 PORTNAME。
示例 6. 手动派生 PORTVERSION
BIND9 使用的版本方案与 Port 版本方案不兼容(版本中包含 -),且无法使用 DISTVERSION 派生,因为在 9.9.9 版本发布后,它将以 9.9.9-P1 的形式发布“补丁级别”。DISTVERSION 会将其转换为 9.9.9.p1,而在 Port 版本方案中,9.9.9.p1 表示 9.9.9 的预发布 1,意味着它是在 9.9.9 之前,而不是之后。因此,PORTVERSION 是从 ISCVERSION 变量手动派生的,输出为 9.9.9p1。
通过使用 pkg-version(8) 的 -t 参数检查 Port 框架和 pkg 对版本的排序:
% 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后面。②
<符号表示传递给-t的第一个参数小于第二个参数。9.9.9排在9.9.9p1前面。
例如,在 Port Makefile 中,如 dns/bind99,它通过以下方式实现:
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= [email protected]
COMMENT= BIND DNS suite with updated DNSSEC and DNS64
WWW= https://www.isc.org/bind/
LICENSE= ISCL
# ISC 发布的版本如 9.8.0-P1 或 9.8.1rc1,与我们的版本管理不兼容。
ISCVERSION= 9.9.9-P6在此示例中,定义了上游版本为 ISCVERSION,并带有说明 为什么 需要它。使用 ISCVERSION 来获得兼容 Port 的 PORTVERSION,并使用 ISCVERSION 直接获得正确的分发文件 URL,并以 ISCVERSION 来命名分发文件。
示例 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其中,:E 是 make(1) 修饰符,用于返回变量的后缀,在此示例中是 304。因此,分发文件会正确生成为 cku304-dev20.tar.gz。
示例 8. 特殊情况 1
有时,软件名称、版本及其分发文件之间没有任何关联。
例如在 audio/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}注意
PKGNAMEPREFIX和PKGNAMESUFFIX不会影响DISTNAME。还需要注意的是,如果WRKSRC等于 ${WRKDIR}/${DISTNAME},而原始源归档的名称与${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX}不同,则只需定义DISTFILES,而不需要同时定义DISTNAME和WRKSRC(以及可能的EXTRACT_SUFX)。
5.4.2. MASTER_SITES
MASTER_SITES在 MASTER_SITES 中记录指向原始 tarball 的 FTP/HTTP URL 的目录部分。不要忘记尾部的斜杠(/**/)!
如果系统上找不到分发文件,make 宏将尝试使用此规范通过 FETCH 获取分发文件。
建议在此列表中包含多个站点,最好来自不同的大陆。这将有助于避免广域网问题。
重要
MASTER_SITES不能为空。它必须指向实际托管分发文件的站点。不能指向网页档案或 FreeBSD 分发文件缓存站点。唯一的例外是没有分发文件的 Ports。例如,meta-Ports 没有分发文件,因此不需要设置MASTER_SITES。
5.4.2.1. 使用 MASTER_SITE_* 变量
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_SITE_FOO变量,可以使用简写形式FOO。例如,使用:MASTER_SITES= FOO如果需要
MASTER_SITE_SUBDIR,则使用:MASTER_SITES= FOO/bar
重要
一些
MASTER_SITE_*名称较长,为了便于使用,已定义了简写形式:MASTER_SITE_*宏的简写
PERL_CPAN
CPAN
GITHUB
GH
GITHUB_CLOUD
GHC
LIBREOFFICE_DEV
LODEV
NETLIB
NL
RUBYGEMS
RG
SOURCEFORGE
SF
5.4.2.2. Magic MASTER_SITES 宏
一些流行站点有可预测的目录结构,存在一些“魔法”宏。对于这些站点,只需使用简写,系统会自动选择子目录。例如,对于名为 Stardict,版本为 1.2.3,并托管在 SourceForge 上的 Port,添加以下行:
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/^(<span class="0-9">\.[0-9]</span>).*/\1/}
GNU
${PORTNAME}
GNUPG
${PORTNAME}
GNU_ALPHA
${PORTNAME}
HORDE
${PORTNAME}
LODEV
${PORTNAME}
MATE
${PORTVERSION:C/^(<span class="0-9">\.[0-9]</span>).*/\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
USE_GITHUB如果分发文件来自 GitHub 上的特定提交或标签,而没有官方发布的文件,可以通过一种简单的方法自动设置正确的 DISTNAME 和 MASTER_SITES。
重要
从 2023 年 2 月 21 日起,GitHub 宣布源代码下载将稳定一年。请切换到发布的资产,如果没有发布,要求上游生成相应的资产。
以下是可用的变量:
表 5. USE_GITHUB 说明
GH_ACCOUNT
托管项目的 GitHub 用户名
${PORTNAME}
GH_PROJECT
GitHub 上的项目名称
${PORTNAME}
GH_TAGNAME
要下载的标签名称(例如 2.0.1、哈希值等)。这里使用分支名称是不正确的。也可以使用提交 ID 的哈希值来进行快照。
${DISTVERSIONPREFIX}${DISTVERSION}${DISTVERSIONSUFFIX}
GH_TUPLE
GH_TUPLE 允许将 GH_ACCOUNT、GH_PROJECT、GH_TAGNAME 和 GH_SUBDIR 放入一个变量中。格式为 account:project:tagname:group/*subdir*。其中/`subdir 部分是可选的。当有多个 GitHub 项目需要获取时,这非常有用。
重要
不要使用
GH_TUPLE来处理默认的分发文件,因为它没有默认值。
示例 10. 简单使用 USE_GITHUB
在为来自 GitHub 上 FreeBSD 用户的 pkg 版本 1.2.7 制作 Port 时,位于 https://github.com/freebsd/pkg/ 上,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 用户的 pkg 的最新版本制作 Port 时,位于 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 是 GH_TAGNAME 中引用的提交的日期,而不是 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 -t g20140411 0
<这意味着,如果上游将来决定创建版本,则不需要使用 PORTEPOCH。
示例 14. 使用 USE_GITHUB 来访问两个版本之间的提交
如果当前版本的软件使用 Git 标签,而 Port 需要更新到一个没有标签的较新中间版本,可以使用 git-describe(1) 来找出要使用的版本:
% git describe --tags f0038b1
v0.7.3-14-gf0038b1v0.7.3-14-gf0038b1 可以分为三个部分:
v0.7.3 这是在请求的提交之前,Git 提交历史中出现的最后一个 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 -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-gc66c71d5.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部分 必须 只用于一个分发文件。它作为一个唯一的键使用,如果多次使用,它将覆盖之前的值。
注意
由于这是
DISTFILES和MASTER_SITES之上的语法糖,组名必须遵循 从多个位置获取多个分发文件或补丁文件 中列出的组名限制。
在从 GitHub 获取多个文件时,有时默认的分发文件不会从 GitHub 获取。要禁用默认分发文件的获取,请设置:
USE_GITHUB= nodefault重要
使用
USE_GITHUB=nodefault时,Makefile 必须在其 顶部块 中设置DISTFILES。定义应为: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示例 16. 使用 USE_GITHUB 获取多个分发文件并使用 GH_TUPLE
这与 使用 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. 如何使用 USE_GITHUB 与 Git 子模块一起使用?
使用 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 上找到。每个子模块的子目录显示为 目录 @ 哈希,例如,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
USE_GITLAB与 GitHub 类似,如果发行文件来自 gitlab.com 或托管 GitLab 软件时,可以使用以下变量,并且可能需要设置它们。
GL_ACCOUNT
托管项目的 GitLab 用户的账户名
${PORTNAME}
GL_PROJECT
GitLab 上的项目名称
${PORTNAME}
GL_COMMIT
要下载的提交哈希值,必须是完整的 160 位、40 字符的十六进制 sha1 哈希值。对于 GitLab,这是一个必需的变量。
(none)
GL_TUPLE
GL_TUPLE 允许将 GL_SITE、GL_ACCOUNT、GL_PROJECT、GL_COMMIT 和 GL_SUBDIR 放入一个变量中,格式为 site:account:project:commit:group/subdir。其中site和subdir` 部分是可选的。当有多个 GitLab 项目需要获取时,它非常有用。
示例 18. 使用 USE_GITLAB 的简单示例
在尝试为来自 gitlab.com 上的 accounts-sso 用户的 libsignon-glib 版本 1.14 创建 Port 时,位于 https://gitlab.com/accounts-sso/libsignon-glib/,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 的示例
USE_GITLAB 的示例如果该 Port 没有版本,并且来自 foo 用户的项目 bar 位于自托管的 GitLab 站点 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。
技巧
20170906是所引用的GL_COMMIT中提交的日期,而不是编辑 Makefile 的日期或提交到 FreeBSD Ports 树的日期。
注意
GL_SITE的协议、Port 和网页根目录可以在同一个变量中修改。
5.4.4.1. 从 GitLab 获取多个文件
USE_GITLAB 框架还支持从 GitLab 和 GitLab 托管站点的不同位置获取多个分发文件。它的工作方式与 从多个位置获取多个分发文件或补丁文件 和 从 GitLab 获取多个文件 类似。
可以将多个值添加到 GL_SITE、GL_ACCOUNT、GL_PROJECT 和 GL_COMMIT 中。每个不同的值分配一个组。 USE_GITLAB 描述。
还可以使用 GL_TUPLE,当有许多分发文件时,它有助于将站点、账户、项目、提交和组信息集中在一起。
对于每个组,创建一个 ${WRKSRC_group} 帮助变量,包含文件被提取到的目录。可以在 post-extract 期间使用 ${WRKSRC_group} 变量来移动目录,或者将其添加到 CONFIGURE_ARGS,或者做其他必要的操作,以确保软件正确构建。
小心
:group部分 必须 仅用于 一个 分发文件。它作为唯一键使用,使用多次将覆盖之前的值。
注意
由于这只是
DISTFILES和MASTER_SITES的语法糖,因此组名称必须遵守 从多个位置获取多个分发文件或补丁文件 中规定的组名限制。
示例 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 获取多个分发文件 功能上是等效的,但使用了 GL_TUPLE:
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如果只有一个分发文件,并且它使用奇怪的后缀来表示压缩机制,可以设置 EXTRACT_SUFX。
例如,如果分发文件的名称是 foo.tar.gzip 而不是更常见的 foo.tar.gz,可以写:
DISTNAME= foo
EXTRACT_SUFX= .tar.gzipUSES=tar[:xxx]、USES=lha 或 USES=zip 会自动根据需要设置 EXTRACT_SUFX 为最常见的归档扩展名,更多信息请参阅使用 USES 宏。如果没有设置这些,EXTRACT_SUFX 默认为 .tar.gz。
注意
由于
EXTRACT_SUFX仅在DISTFILES中使用,因此只需设置其中之一。
5.4.6. DISTFILES
DISTFILES有时下载的文件名称与 Port 的名称没有任何关系。例如,它可能被称为 source.tar.gz 或类似名称。在其他情况下,应用程序的源代码可能分散在几个不同的归档文件中,所有这些文件都必须下载。
如果是这种情况,可以将 DISTFILES 设置为一个由空格分隔的文件列表,列出所有需要下载的文件。
DISTFILES= source1.tar.gz source2.tar.gz如果未明确设置,DISTFILES 默认为 ${DISTNAME}${EXTRACT_SUFX}。
5.4.7. EXTRACT_ONLY
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
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},该目录可能不可写。
技巧
如果有多个补丁,并且它们的
strip参数需要不同的值,可以在PATCHFILES中的补丁名称旁边添加这些值,例如:PATCHFILES= patch1 patch2:-p1这不会与主站分组功能冲突,添加分组也同样有效:
PATCHFILES= patch2:-p1:source2
注意
tarball 会与常规源代码一起解压,因此如果它是常规压缩 tarball,就不需要显式地解压它。提取时请特别小心,不要覆盖该目录中已经存在的文件。如果手动提取补丁,记得在
pre-clean目标中添加命令以删除已复制的补丁。
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 中有两个文件,MASTER_SITES 中有 20 个站点,其中 beta 文件在所有站点上都有,而 alpha 文件只能在第 20 个站点找到。如果维护者事先知道这个情况,完全可以避免在所有站点中浪费时间,不是吗?这样就避免了在愉快的周末里浪费大量时间!
现在你明白了这个概念,试想更多的 DISTFILES 和更多的 MASTER_SITES,肯定会让我们的“distfiles 调查专家”对减少网络压力感到轻松。
在接下来的章节中,将介绍 FreeBSD 对这个想法的实现。我们对 OpenBSD 的概念做了一些改进。
重要
组名称不能包含连字符(
-),事实上,它们不能包含任何超出[a-zA-Z0-9_]范围的字符。这是因为,虽然 make(1) 可以接受包含连字符的变量名,但 sh(1) 不允许。
5.4.9.1. 简化信息
本节解释了如何快速准备从不同站点和子目录下载多个分发文件和补丁的精细化获取。我们在这里描述了简化版 MASTER_SITES:n 的使用。这对于大多数场景来说已经足够了。更多详细信息请参见 详细信息。
有些应用程序由多个分发文件组成,这些文件必须从多个不同的站点下载。例如,Ghostscript 包含程序的核心部分,还有大量驱动文件,这些驱动文件根据用户的打印机不同而有所不同。部分驱动文件随核心文件一起提供,但许多其他驱动文件必须从不同的站点下载。
为了解决这个问题,DISTFILES 中的每个条目可以跟随一个冒号和一个“组名”。然后,MASTER_SITES 中列出的每个站点都将跟随一个冒号和该组,表示从该站点下载的分发文件。
例如,考虑一个由两个部分组成的应用程序,source1.tar.gz 和 source2.tar.gz,这两个文件必须从不同的站点下载。Port 的 Makefile 应包括如下内容:
示例 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 应写成如下:
示例 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:source25.4.9.2. 详细信息
好的,那么之前的例子没有反映出新的 Port 的需求吗?在这一节中,我们将详细解释细粒度获取机制 MASTER_SITES:n 的工作原理以及如何使用它。
带有
:n后缀的元素属于组n,带有:m后缀的元素属于组m,依此类推。没有后缀的元素没有分组,它们都属于特殊组
DEFAULT。任何带有DEFAULT后缀的元素都是冗余的,除非该元素同时属于DEFAULT和其他组(请参阅 5 项)。 这些示例是等效的,但第一个是首选:MASTER_SITES= alphaMASTER_SITES= alpha:DEFAULT组不是互斥的,一个元素可以同时属于多个不同的组,一个组可以包含多个不同的元素,也可以没有元素。
当一个元素同时属于多个组时,使用逗号操作符(
,)。 我们可以一次列出多个组,而不是多次重复每次不同的后缀。例如,:m,n,o表示该元素属于组m、n和o。所有这些示例都是等效的,但最后一个是首选:
MASTER_SITES= alpha alpha:SOME_SITEMASTER_SITES= alpha:DEFAULT alpha:SOME_SITEMASTER_SITES= alpha:SOME_SITE,DEFAULTMASTER_SITES= alpha:DEFAULT,SOME_SITE给定组内的所有站点按照
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后缀。请参见 详细使用MASTER_SITES:n在MASTER_SITE_SUBDIR中 和 详细使用MASTER_SITES:n与逗号操作符。示例 24. 在MASTER_SITE_SUBDIR中详细使用MASTER_SITES:nMASTER_SITE_SUBDIR= old:n new/:NEW属于
DEFAULT组的目录 → old:n属于
NEW组的目录 → new
示例 25. 使用逗号操作符的详细示例,多个文件、多个站点和多个子目录
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上述示例的细粒度获取结果如下。站点将按使用顺序列出。
file1 将从以下站点获取:
MASTER_SITE_OVERRIDEMASTER_SITE_BACKUP
file2 将与 file1 完全相同地获取,因为它们属于相同的组
MASTER_SITE_OVERRIDEMASTER_SITE_BACKUP
file3 将从以下站点获取:
MASTER_SITE_OVERRIDEMASTER_SITE_BACKUP
file4 将从以下站点获取:
MASTER_SITE_OVERRIDEMASTER_SITE_BACKUP
file5 将从以下站点获取:
MASTER_SITE_OVERRIDEMASTER_SITE_BACKUP
file6 将从以下站点获取:
MASTER_SITE_OVERRIDEMASTER_SITE_BACKUP
如何将 bsd.sites.mk 中的某个特殊宏分组,例如 SourceForge (
SF)? 这已经尽可能简化。请参见 详细使用MASTER_SITES:n与 SourceForge (SF)。示例 26. 详细使用
MASTER_SITES:n与 SourceForge (SF)MASTER_SITES= http://site1/ SF/something/1.0:sourceforge,TEST DISTFILES= something.tar.gz:sourceforgesomething.tar.gz 将从 SourceForge 中的所有站点获取。
如何与
PATCH*一起使用? 所有示例都使用了MASTER*,但它们与PATCH*一样适用,正如在 简化使用MASTER_SITES:n与PATCH_SITES中所见。示例 27. 简化使用
MASTER_SITES:n与PATCH_SITESPATCH_SITES= [http://site1/](http://site1/) [http://site2/\:test](http://site2/:test) PATCHFILES= patch1\:test
5.4.9.3. 对 Ports 的影响:变化与不变之处
所有当前的 Ports 保持不变。只有当存在按上述语法规则附加
:n后缀的元素时,MASTER_SITES:n特性才会被激活,特别是在 第 7 项 中显示的那样。Port 目标保持不变:
checksum、makesum、patch、configure、build等。唯一的例外是do-fetch、fetch-list、master-sites和patch-sites。do-fetch:部署新分组,并根据其匹配的组元素,在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 项。
新的 Port 目标:
master-sites-n和patch-sites-n目标将列出各自组n中的元素。例如,master-sites-DEFAULT和patch-sites-DEFAULT将返回DEFAULT组的元素,master-sites-test和patch-sites-test将返回test组的元素,依此类推。新的目标
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
DIST_SUBDIR不要让 Port 混乱 /usr/ports/distfiles。如果 Port 需要获取大量文件,或者包含一个可能与其他 Ports 冲突的文件(例如,Makefile),请将 DIST_SUBDIR 设置为 Port 的名称(${PORTNAME} 或 ${PKGNAMEPREFIX}${PORTNAME} 都可以)。这将把 DISTDIR 从默认的 /usr/ports/distfiles 改为 /usr/ports/distfiles/${DIST_SUBDIR},从而将该 Port 所需的所有文件放入该子目录中。
它还会查看备份主站点上具有相同名称的子目录,网址为 http://distcache.FreeBSD.org(仅在 Makefile 中显式设置 DISTDIR 是无法实现这一点的,请使用 DIST_SUBDIR)。
注意
这不会影响 Makefile 中定义的
MASTER_SITES。
最后更新于
这有帮助吗?