5.17.安装文件
重要
安装阶段对最终用户来说是非常重要的, 因为它向他们的系统添加了文件。所有在 port Makefile 的
*-install
目标中运行的额外命令, 都应该被回显到屏幕上。不要用@
或.SILENT
来使这些命令沉默。
5.17.1. INSTALL_*
Macros
INSTALL_*
Macros使用 bsd.port.mk 中提供的宏来确保 port 的 *-install
目标中的文件的正确模式。直接在 pkg-plist 中用相应的条目来设置所有权, 例如 @(owner,group,)
、 @owner owner
和 @group group
。这些操作符在被覆盖之前, 或在 pkg-plist 结束之前都是有效的, 所以记得在不再需要它们时重新设置。默认的所有权是 root:wheel
。更多信息请参见基础关键词。
INSTALL_PROGRAM
是一个安装二进制可执行文件的命令。INSTALL_SCRIPT
是一个安装可执行脚本的命令。INSTALL_LIB
是一个安装共享库(但不是静态库)的命令。INSTALL_KLD
是一个安装内核可加载模块的命令。有些架构不喜欢模块被剥离,所以用这个命令代替INSTALL_PROGRAM
。INSTALL_DATA
是一个安装可共享数据的命令,包括静态库。INSTALL_MAN
是一个安装手册和其他文档的命令(它不压缩任何东西)。
这些变量被设置到 install(1) 命令中,并为每种情况设置适当的标志。
重要
不要使用
INSTALL_LIB
来安装静态库,因为剥离它们会使它们变得无用。使用INSTALL_DATA
代替。
5.17.2. 剥离二进制文件和共享库
已安装的二进制文件应该被剥离。除非绝对需要,否则不要手动剥离二进制文件。INSTALL_PROGRAM
宏在安装的同时也剥离了二进制文件。INSTALL_LIB
宏对共享库做同样的事情。
当一个文件必须被剥离, 但 INSTALL_PROGRAM
和 INSTALL_LIB
宏都不可取时, ${STRIP_CMD}
会剥离程序或共享库。这通常是在安装后的目标中完成的。举例来说:
当多个文件需要被剥离时:
在一个文件上使用 file(1) 来确定它是否已经被剥离。二进制文件会被 file(1) 报告为已被剥离,或未被剥离。此外, strip(1) 会检测到已经被剥离的程序,并干净地退出。
重要
当
WITH_DEBUG
被定义时,elf 文件必须不被剥离。框架提供的变量(
STRIP_CMD
,INSTALL_PROGRAM
,INSTALL_LIB
, ...)和USES
自动处理这个问题。有些软件,在其
LDFLAGS
中加入了-s
,在这种情况下,如果设置了WITH_DEBUG
,就删除-s
,或者无条件地删除它,在安装后使用STRIP_CMD
。
5.17.3. 安装一整棵树的文件
有时,必须安装大量的文件,同时保留它们的层次结构。例如, 将整个目录树从 WRKSRC
复制到 PREFIX
下的目标目录。请注意 PREFIX
、EXAMPLESDIR
、DATADIR
和其他路径变量必须始终以 STAGEDIR
为前缀, 以尊重分期付款 (参见分期付款)。
有两个宏用于这种情况。使用这些宏而不是 cp
的好处是, 它们可以保证目标文件的正确所有权和权限。第一个宏, COPYTREE_BIN
, 将把所有安装的文件设置为可执行文件, 因此适合安装到 PREFIX/bin。第二个宏,COPYTREE_SHARE
,不设置文件的可执行权限,因此适合于在 PREFIX/share 目标下安装文件。
这个例子将把供应商 distfile 中的 examples 目录的内容安装到 port 中适当的 examples 位置。
而这个例子将把夏季各月的数据安装到一个 DATADIR 的夏季子目录下。
额外的查找参数可以通过第三个参数传递给 COPYTREE_*
宏。例如,要安装第一个例子中除 Makefiles 之外的所有文件,可以使用这些命令。
这些宏不会将已安装的文件添加到 pkg-plist 中。它们必须手动添加。对于可选的文档 (PORTDOCS
, 参见 安装附加文档) 和示例 (PORTEXAMPLES
), 必须在 pkg-plist 中预留 %%PORTDOCS%%
或 %%PORTEXAMPLES%%
前缀。
5.17.4. 安装附加文件
如果该软件除了标准的 man 和 info 页之外还有一些对用户有用的文档,请将其安装在 DOCSDIR
下。这可以像前一项一样,在安装后的目标中完成。
为 port 创建一个新的目录。这个目录的名字是 DOCSDIR
。这通常等同于 PORTNAME
。不过, 如果用户可能希望同时安装不同版本的 port, 可以使用整个 PKGNAME
。
由于只有 pkg-plist 中列出的文件才会被安装,因此安全的做法是始终将文件安装到 STAGEDIR
(参见 Staging)。因此,只有当所安装的文件大到足以造成明显的 I/O 开销时,才需要 .if
块。
另一方面, 如果 port 中有 DOCS 选项, 则应在 post-install-DOCS-on
目标中安装文档。这些目标在 Additional Build Targets, target-OPT-on
和 target-OPT-off
中有所描述。
下面是一些方便的变量,以及它们在 Makefile 中使用时的默认扩展方式:
DATADIR
被扩展为PREFIX/share/PORTNAME。DATADIR_REL
被扩展为share/PORTNAME。DOCSDIR
被扩展为PREFIX/share/doc/PORTNAME。DOCSDIR_REL
被扩展为share/doc/PORTNAME。EXAMPLESDIR
被扩展为PREFIX/share/examples/PORTNAME。EXAMPLESDIR_REL
被扩展为share/examples/PORTNAME。
注意
DOCS
选项只控制安装在DOCSDIR
中的额外文档。它并不适用于标准的 man 页和 info 页。安装在EXAMPLESDIR
的东西由EXAMPLES
选项控制。
这些变量会被输出到 PLIST_SUB
。如果可能的话, 它们的值将以相对于 PREFIX 的路径名出现在那里。也就是说, 在装箱单中, share/doc/PORTNAME 将被默认替换为 %%DOCSDIR%%
, 以此类推。(关于 pkg-plist 替换的更多信息,请参见[这里](https://docs.freebsd.org/en/books/porters-handbook/book/#plist-sub)。
所有有条件安装的文档文件和目录都包括在 pkg-plist 中, 其前缀为 %%PORTDOCS%%
, 例如:
作为在 pkg-plist 中列举文档文件的一种替代方法, port 可以将 PORTDOCS
变量设置为文件名和 shell glob 模式的列表, 以加入到最终的打包列表中。这些名字将是相对于 DOCSDIR
的。因此, 利用 PORTDOCS
的 port, 如果使用了非默认的文档位置, 就必须相应地设置 DOCSDIR
。如果一个目录被列在 PORTDOCS
中, 或被这个变量的 glob 模式所匹配, 那么整个包含文件和目录的子树将被登记在最终的装箱单中。如果没有设置 DOCS
选项, 则 PORTDOCS
中列出的文件和目录将不会被安装或添加到 port 包装列表中。如上所示, 在 PORTDOCS
中安装文档的工作仍由 port 自己决定。一个利用 PORTDOCS
的典型例子:
注意
对于安装在
DATADIR
和EXAMPLESDIR
下的文件,PORTDOCS
的对应物分别是PORTDATA
和PORTEXAMPLES
。pkg-message 的内容会在安装时显示。详情请参见使用 pkg-message 一节。 pkg-message 不需要被添加到 pkg-plist 中。
5.17.5. PREFIX 下的子目录
试着让 port 把东西放到 PREFIX
的正确子目录里。有些 port 会把所有东西混在一起, 放在以 port 的名字命名的子目录中, 这是不正确的。另外, 许多 port 把除了二进制文件、 头文件和手册页之外的所有东西都放在 lib 的子目录中, 这与 BSD 的范式不相符。许多文件必须移到这些目录中: etc (设置/配置文件)、 libexec (内部启动的可执行文件)、 sbin (供超级用户/管理员使用的可执行文件)、 info (信息浏览器的文档) 或 share (与架构无关的文件)。详情请参见 hier(7); 管理 /usr 的规则也几乎适用于 /usr/local。例外的情况是处理 USENET “新闻”的 port。它们可以使用 PREFIX/news 作为其文件的目的地。
最后更新于