OCTAVE_VERSION= ${PORTREVISION} PLIST_SUB= OCTAVE_VERSION=${OCTAVE_VERSION}
第 8 章。高级 pkg-plist 实践
目录
8.1. 根据 Make 变量更改 pkg-plist
某些端口,特别是p5-
端口,需要根据其配置选项(或perl
的版本,对于p5-
端口而言)更改其pkg-plist。为了简化操作,pkg-plist中的所有%%OSREL%%
、%%PERL_VER%%
和%%PERL_VERSION%%
实例将被适当地替换。%%OSREL%%
的值是操作系统的数字修订版(例如,4.9
)。%%PERL_VERSION%%
和%%PERL_VER%%
是perl
的完整版本号(例如,5.8.9
)。与端口文档文件相关的其他%%VARS%%
在相关部分中描述。
要进行其他替换,请使用VAR=VALUE
对列表设置PLIST_SUB
,并将pkg-plist中的%%VAR%%
实例替换为VALUE。
例如,如果端口在特定于版本的子目录中安装了许多文件,请使用占位符表示版本,这样pkg-plist就不必在每次更新端口时重新生成。例如,设置
在Makefile中,并在pkg-plist中出现版本的任何地方使用%%OCTAVE_VERSION%%
。当端口升级时,就不需要编辑pkg-plist中的几十(或者在某些情况下是几百)行。
如果文件根据端口中设置的选项有条件地安装,则处理它的常用方法是在需要启用选项时在pkg-plist行之前添加%%OPT%%
,或者在禁用选项时添加%%NO_OPT%%
,并将OPTIONS_SUB=yes
添加到Makefile中。有关更多信息,请参阅OPTIONS_SUB
。
例如,如果某些文件仅在启用X11
选项时安装,并且Makefile具有
OPTIONS_DEFINE= X11 OPTIONS_SUB= yes
在pkg-plist中,在仅在启用选项时安装的行之前添加%%X11%%
,如下所示
%%X11%%bin/foo-gui
此替换将在pre-install
和do-install
目标之间执行,方法是读取PLIST并写入TMPPLIST(默认值:WRKDIR/.PLIST.mktmp)。因此,如果端口动态构建PLIST,则在pre-install
中或之前执行此操作。此外,如果端口需要编辑结果文件,则在post-install
中将其编辑到名为TMPPLIST的文件中。
修改端口打包列表的另一种方法是基于设置变量PLIST_FILES
和PLIST_DIRS
。每个变量的值被视为一个路径名列表,这些路径名将与PLIST内容一起写入TMPPLIST。虽然PLIST_FILES
和PLIST_DIRS
中列出的名称会受到上面描述的%%VAR%%
替换的影响,但最好直接使用${VAR}
。除了这一点之外,来自PLIST_FILES
的名称将保持不变地出现在最终的打包列表中,而来自PLIST_DIRS
的名称将被@dir
前缀。为了生效,PLIST_FILES
和PLIST_DIRS
必须在写入TMPPLIST之前设置,即在pre-install
或更早之前设置。
有时,使用OPTIONS_SUB
还不够。在这些情况下,在Makefile中向PLIST_SUB
添加一个特定的TAG
,其特殊值为@comment
,这将使包工具忽略该行。例如,如果某些文件仅在X11
选项开启且架构为i386
时安装
.include <bsd.port.pre.mk> .if ${PORT_OPTIONS:MX11} && ${ARCH} == "i386" PLIST_SUB+= X11I386="" .else PLIST_SUB+= X11I386="@comment " .endif
8.2. 空目录
8.2.1. 清理空目录
在卸载时,端口必须删除它创建的空目录。大多数这些目录由pkg(8)自动删除,但对于在${PREFIX}之外创建的目录或空目录,需要做一些额外的工作。这通常是通过为这些目录添加@dir
行来完成的。在删除父目录之前必须删除子目录。
[...] @dir /var/games/oneko/saved-games @dir /var/games/oneko
8.3. 配置文件
如果端口将配置文件安装到PREFIX/etc(或其他位置),请不要将它们列在pkg-plist中。这将导致pkg delete
删除用户精心编辑的文件,并且重新安装会将它们删除。
相反,请安装带有filename.sample扩展名的示例文件。@sample
宏会自动执行此操作,请参阅使用关键字扩展包列表,了解它的确切作用。对于每个示例文件,请在pkg-plist中添加一行
@sample etc/orbit.conf.sample
如果出于某种非常好的理由,不希望默认安装一个有效的配置文件,则只在pkg-plist中列出示例文件名,不要在后面添加@sample
和空格,并添加一条消息,指出用户必须复制并编辑该文件才能使用该软件。
当端口将它的配置安装在${PREFIX}/etc的子目录中时,使用 |
示例配置文件应始终具有.sample后缀。如果由于某些历史原因,无法使用标准后缀,或者示例文件来自其他目录,请使用此构造 @sample etc/orbit.conf-dist etc/orbit.conf 或 @sample %%EXAMPLESDIR%%/orbit.conf etc/orbit.conf 格式为 |
8.4. 动态与静态包列表
静态包列表是指在 Ports Collection 中提供的包列表,可以是pkg-plist(有或没有变量替换),也可以通过PLIST_FILES
和 PLIST_DIRS
嵌入到 Makefile 中。即使内容是通过 Makefile 中的工具或目标在提交者将它包含到 Ports Collection 之前自动生成的(例如,使用make makeplist
),这仍然被认为是静态列表,因为可以在不下载或编译 distfile 的情况下检查它。
动态包列表是指在编译端口时根据安装的文件和目录生成的包列表。在下载和编译移植的应用程序的源代码之前,或者在运行make clean
之后,无法检查它。
虽然不禁止使用动态包列表,但维护者应尽可能使用静态包列表,因为它使用户能够grep(1) 可用端口,以发现例如哪个端口安装了某个文件。动态列表应该主要用于复杂的端口,其中包列表根据端口的可选功能发生很大变化(因此维护静态包列表不可行),或者根据使用的依赖软件的版本改变包列表的端口。例如,使用 Javadoc 生成文档的端口。
8.5. 自动化包列表创建
首先,确保端口几乎完成,只缺少pkg-plist。运行make makeplist
将显示pkg-plist的示例。makeplist
的输出必须仔细检查其正确性,因为它尝试自动猜测一些内容,并且可能会出错。
用户配置文件应安装为filename.sample,如配置文件中所述。info/dir 不应列出,并且必须添加适当的 install-info 行,如信息文件部分中所述。端口安装的任何库都必须如共享库部分中所述列出。
8.5.1. 使用正则表达式扩展PLIST_SUB
要替换的字符串有时需要非常具体,以避免不必要的替换。这是使用较短值时常见的问题。
为了解决这个问题,对于每个PLACEHOLDER=value
,可以设置一个PLACEHOLDER_regex=regex
,其中regex
部分更精确地匹配value。
Perl 端口可以在特定树中安装依赖于体系结构的文件。在 FreeBSD 上,为了简化移植,这棵树被称为mach
。例如,安装文件路径包含mach
的端口,可能将路径字符串的那部分替换为错误的值。考虑这个Makefile
PORTNAME= Machine-Build DISTVERSION= 1 CATEGORIES= devel perl5 MASTER_SITES= CPAN PKGNAMEPREFIX= p5- MAINTAINER= [email protected] COMMENT= Building machine WWW= https://search.cpan.org/dist/Machine-Build USES= perl5 USE_PERL5= configure PLIST_SUB= PERL_ARCH=mach
端口安装的文件是
/usr/local/bin/machine-build /usr/local/lib/perl5/site_perl/man/man1/machine-build.1.gz /usr/local/lib/perl5/site_perl/man/man3/Machine::Build.3.gz /usr/local/lib/perl5/site_perl/Machine/Build.pm /usr/local/lib/perl5/site_perl/mach/5.20/Machine/Build/Build.so
运行make makeplist
会错误地生成
bin/%%PERL_ARCH%%ine-build %%PERL5_MAN1%%/%%PERL_ARCH%%ine-build.1.gz %%PERL5_MAN3%%/Machine::Build.3.gz %%SITE_PERL%%/Machine/Build.pm %%SITE_PERL%%/%%PERL_ARCH%%/%%PERL_VER%%/Machine/Build/Build.so
将Makefile中的PLIST_SUB
行更改为
PLIST_SUB= PERL_ARCH=mach \ PERL_ARCH_regex=\bmach\b
现在make makeplist
会正确地生成
bin/machine-build %%PERL5_MAN1%%/machine-build.1.gz %%PERL5_MAN3%%/Machine::Build.3.gz %%SITE_PERL%%/Machine/Build.pm %%SITE_PERL%%/%%PERL_ARCH%%/%%PERL_VER%%/Machine/Build/Build.so
8.6. 使用关键字扩展包列表
所有关键字也可以在括号中接受可选参数。参数是所有者、组和模式。此参数用于引用的文件或目录。要更改配置文件的所有者、组和模式,请使用
@sample(games,games,640) etc/config.sample
参数是可选的。如果只需要更改组和模式,请使用
@sample(,games,660) etc/config.sample
如果关键字用于可选条目,则必须在助手之后添加它 %%FOO%%@sample etc/orbit.conf.sample 这是因为选项 plist 助手用于注释掉该行,因此它们需要放在首位。有关更多信息,请参阅 |
8.6.1. @desktop-file-utils
将在安装和卸载后运行update-desktop-database -q
。永远不要直接使用,在Makefile中添加USES=desktop-file-utils
。
8.6.3. @fontsdir
directory
为作为参数传递的目录添加一个@dir
条目,并在安装和卸载后对该目录运行mkfontscale
和 mkfontdir
。此外,在卸载时,如果 fonts.scale 和 fonts.dir 缓存文件为空,它会删除它们。
8.6.4. @info
file
将作为参数传递的文件添加到 plist 中,并在安装和卸载时更新信息文档索引。此外,它会在卸载时删除空索引。这永远不应该手动使用,而应该通过INFO
使用。有关更多信息,请参阅信息文件。
8.6.7. @sample
文件 [文件]
这用于处理配置文件的安装,通过打包示例文件。 “实际”的非示例文件是第二个文件名(如果存在),或者第一个文件名不带.sample扩展名。
这将执行三项操作。首先,将作为参数传递的第一个文件(示例文件)添加到plist中。然后,在安装时,如果未找到实际文件,则将示例文件复制到实际文件。最后,在卸载时,如果实际文件未被修改,则删除它。有关详细信息,请参见配置文件。
8.6.10. @terminfo
不要单独使用。如果端口安装了*.terminfo文件,请在其Makefile中添加USES=terminfo
。
在安装和卸载时,如果存在tic
,则从${PREFIX}/shared/misc中的*.terminfo文件刷新${PREFIX}/shared/misc/terminfo.db。
8.6.11. 基本关键字
有一些关键字是硬编码的,在pkg-create(8)中有所描述。为了完整起见,它们也在此处进行说明。
8.6.11.1. @
[文件]
空关键字是一个占位符,用于在需要更改文件的所有者、组或模式时使用。例如,要将文件的组设置为games
并添加setgid位,请添加
@(,games,2755) sbin/daemon
8.6.11.2. @preexec
命令, @postexec
命令, @preunexec
命令, @postunexec
命令
在软件包安装或卸载过程中执行命令。
@preexec
命令在pre-install脚本中执行命令。
@postexec
命令在post-install脚本中执行命令。
@preunexec
命令在pre-deinstall脚本中执行命令。
@postunexec
命令在post-deinstall脚本中执行命令。
如果命令在其中包含任何这些序列,它们将在内联展开。对于以下示例,假设@cwd
设置为/usr/local,并且最后一个提取的文件为bin/emacs。
%F
展开到最后一个提取的文件名(如指定)。在示例中为bin/emacs。
%D
展开到当前目录前缀,由
@cwd
设置。在示例中为/usr/local。%B
展开到完全限定文件名的基本名称,即当前目录前缀加上最后一个文件规范,减去尾随文件名。在示例中,这将是/usr/local/bin。
%f
展开到完全限定名称的文件名部分,或
%B
的反义词。在示例中为emacs。
这些关键字旨在帮助你设置软件包,使其尽可能地易于使用。它们不能被滥用以启动服务、停止服务或运行任何会修改当前正在运行的系统的其他命令。 |
8.6.11.3. @mode
模式
将所有后续提取文件的默认权限设置为模式。格式与chmod(1)中使用的相同。不带参数使用以将其重置为默认权限(打包时文件的模式)。
这必须是一个数字模式,例如 |
8.6.11.7. @dir
目录
声明目录名称。默认情况下,软件包安装在PREFIX
下创建的目录会自动删除。当PREFIX
下的空目录需要创建,或者目录需要具有非默认所有者、组或模式时使用。PREFIX
以外的目录需要注册。例如,/var/db/${PORTNAME}需要具有@dir
条目,而${PREFIX}/shared/${PORTNAME}不需要,前提是它包含文件或使用默认所有者、组和模式。
8.6.11.8. @exec
命令, @unexec
命令 (已弃用)
在安装或卸载过程中执行命令。请改用@preexec
命令。
8.6.12. 创建新关键字
软件包列表文件可以通过在${PORTSDIR}/Keywords目录中定义的关键字进行扩展。每个关键字的设置都存储在一个名为keyword.ucl的UCL文件中。该文件必须至少包含以下部分之一
attributes
action
pre-install
post-install
pre-deinstall
post-deinstall
pre-upgrade
post-upgrade
8.6.12.1. attributes
更改关键字使用的所有者、组或模式。包含一个关联数组,其中可能的键是owner
、group
和mode
。值分别是用户名、组名和文件模式。例如
attributes: { owner: "games", group: "games", mode: 0555 }
8.6.12.2. action
定义对关键字参数的操作。包含一个数组,其中可能的取值是
setprefix
为下一个plist条目设置前缀。
dir
注册一个在安装时创建并在卸载时删除的目录。
dirrm
注册一个在卸载时要删除的目录。已弃用。
dirrmtry
注册一个在卸载时尝试删除的目录。已弃用。
file
注册一个文件。
setmode
为下一个plist条目设置模式。
setowner
为下一个plist条目设置所有者。
setgroup
为下一个plist条目设置组。
comment
不执行任何操作,等同于不输入
action
部分。ignore_next
忽略plist中的下一个条目。
8.6.12.3. arguments
如果设置为true
,则添加参数处理,将整行%@
拆分为编号参数%1
、%2
等。例如,对于以下行
@foo some.content other.content
%1
和%2
将包含
some.content other.content
它还会影响action
条目的工作方式。当存在多个参数时,必须指定参数编号。例如
actions: [file(1)]
8.6.12.4. pre-install
, post-install
, pre-deinstall
, post-deinstall
, pre-upgrade
, post-upgrade
这些关键字包含一个sh(1)脚本,在软件包安装、卸载或升级之前或之后执行。除了@preexec
命令中描述的常用@exec %foo
占位符之外,还有一个新的占位符%@
,它表示关键字的参数。
8.6.12.5. 自定义关键字示例
@dirrmtryecho
关键字示例此关键字执行两项操作:它将@dirrmtry 目录
行添加到打包列表中,并回显在卸载软件包时删除目录的事实。
actions: [dirrmtry] post-deinstall: <<EOD echo "Directory %D/%@ removed." EOD
@sample
的实现方式此关键字执行三项操作:它将作为参数传递给@sample
的第一个文件名添加到打包列表中,它将向post-install
脚本指令添加内容,如果实际配置文件不存在,则将示例复制到实际配置文件,并且它将向post-deinstall
脚本指令添加内容,如果实际配置文件未被修改,则删除它。
actions: [file(1)] arguments: true post-install: <<EOD case "%1" in /*) sample_file="%1" ;; *) sample_file="%D/%1" ;; esac target_file="${sample_file%.sample}" set -- %@ if [ $# -eq 2 ]; then target_file=${2} fi case "${target_file}" in /*) target_file="${target_file}" ;; *) target_file="%D/${target_file}" ;; esac if ! [ -f "${target_file}" ]; then /bin/cp -p "${sample_file}" "${target_file}" && \ /bin/chmod u+w "${target_file}" fi EOD pre-deinstall: <<EOD case "%1" in /*) sample_file="%1" ;; *) sample_file="%D/%1" ;; esac target_file="${sample_file%.sample}" set -- %@ if [ $# -eq 2 ]; then set -- %@ target_file=${2} fi case "${target_file}" in /*) target_file="${target_file}" ;; *) target_file="%D/${target_file}" ;; esac if cmp -s "${target_file}" "${sample_file}"; then rm -f "${target_file}" else echo "You may need to manually remove ${target_file} if it is no longer needed." fi EOD
上次修改时间:2024年9月23日,由Fernando Apesteguía修改