5.17.安装文件

重要

install 阶段对最终用户非常重要,因为它将文件添加到他们的系统中。Port Makefile 中的 *-install 目标运行的所有附加命令应回显到屏幕上。不要 使用 @.SILENT 来隐藏这些命令。

5.17.1. INSTALL_*

使用 bsd.port.mk 提供的宏来确保在 Port 的 *-install 目标中正确设置文件的权限。通过相应的条目(例如 @(owner,group,)@owner<span> </span>owner@group<span> </span>group)在 pkg-plist 中直接设置所有权。这些操作符在被重写之前有效,或者直到 pkg-plist 的结尾为止,因此请记得在不再需要时重置它们。默认的所有权是 root:wheel。有关更多信息,请参见 Base Keywords

  • 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_PROGRAMINSTALL_LIB 宏时,可以使用 ${STRIP_CMD} 来去除程序或共享库的符号表。这通常是在 post-install 目标中执行。例如:

post-install:
	${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/xdl

当需要去除多个文件的符号表时:

post-install:
.for l in geometry media body track world
	${STRIP_CMD} ${STAGEDIR}${PREFIX}/lib/lib${PORTNAME}-${l}.so.0
.endfor

使用 file(1) 命令可以确定文件是否已去除符号表。二进制文件会被 file(1) 报告为 strippednot stripped。此外,strip(1) 将检测到已去除符号表的程序,并平稳退出。

重要

当定义了 WITH_DEBUG 时,elf 文件 不得 被去除符号表。

框架提供的变量(如 STRIP_CMDINSTALL_PROGRAMINSTALL_LIB 等)和 USES 会自动处理这个问题。

如果某些软件在其 LDFLAGS 中添加了 -s,则在这种情况下,要么在设置了 WITH_DEBUG 时删除 -s,要么无条件地删除它,并在 post-install 中使用 STRIP_CMD

5.17.3. 安装整个文件树

有时,需要安装大量文件,并保持其层次结构不变。例如,将整个目录树从 WRKSRC 复制到 PREFIX 下的目标目录。请注意,PREFIXEXAMPLESDIRDATADIR 以及其他路径变量必须始终以 STAGEDIR 为前缀,以遵循 staging 机制(参见 Staging)。

针对这种情况,有两个宏。使用这些宏的优点是,它们能确保目标文件的正确所有权和权限。第一个宏,COPYTREE_BIN,会将所有安装的文件设置为可执行,因此适用于安装到 PREFIX/bin 目录下。第二个宏,COPYTREE_SHARE,不会为文件设置可执行权限,因此适合安装到 PREFIX/share 目标目录下。

post-install:
	${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
	(cd ${WRKSRC}/examples && ${COPYTREE_SHARE} . ${STAGEDIR}${EXAMPLESDIR})

此示例会将供应商分发文件中的 examples 目录的内容安装到 Port 的适当示例位置。

post-install:
	${MKDIR} ${STAGEDIR}${DATADIR}/summer
	(cd ${WRKSRC}/temperatures && ${COPYTREE_SHARE} "June July August" ${STAGEDIR}${DATADIR}/summer)

这个示例会将夏季月份的数据安装到 DATADIR 下的 summer 子目录。

可以通过 COPYTREE_* 宏的第三个参数传递额外的 find 参数。例如,要安装来自第一个示例的所有文件,但排除 Makefile,可以使用以下命令:

post-install:
	${MKDIR} ${STAGEDIR}${EXAMPLESDIR}
	(cd ${WRKSRC}/examples && \
	${COPYTREE_SHARE} . ${STAGEDIR}${EXAMPLESDIR} "! -name Makefile")

这些宏不会将已安装的文件自动添加到 pkg-plist 中。必须手动添加它们。对于可选文档(PORTDOCS,参见 安装附加文档)和示例(PORTEXAMPLES),必须在 pkg-plist 中的条目前加上 %%PORTDOCS%%%%PORTEXAMPLES%% 前缀。

5.17.4. 安装附加文档

如果软件有除标准 man 页面和 info 页面之外的其他文档,并且对用户有用,可以将其安装到 DOCSDIR 下。这可以像前面的示例一样,在 post-install 目标中进行。

为 Port 创建一个新目录。该目录名为 DOCSDIR,通常等于 PORTNAME。但是,如果用户可能希望同时安装不同版本的 Port,则可以使用整个 PKGNAME

由于只有在 pkg-plist 中列出的文件才会被安装,因此始终将文档安装到 STAGEDIR 是安全的(参见 Staging)。因此,.if 块仅在安装的文件足够大,可能导致显著的 I/O 开销时才需要。

post-install:
	${MKDIR} ${STAGEDIR}${DOCSDIR}
	${INSTALL_DATA} ${WRKSRC}/docs/xvdocs.ps ${STAGEDIR}${DOCSDIR}

另一方面,如果 Port 中有 DOCS 选项,则应在 post-install-DOCS-on 目标中安装文档。这些目标在 附加构建目标 中有所描述。

以下是一些有用的变量及其在 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 替换的更多信息,请参见 这里。)

所有有条件安装的文档文件和目录都会在 pkg-plist 中以 %%PORTDOCS%% 前缀列出,例如:

%%PORTDOCS%%%%DOCSDIR%%/AUTHORS
%%PORTDOCS%%%%DOCSDIR%%/CONTACT

作为列出文档文件的替代方法,Port 可以将变量 PORTDOCS 设置为文件名和 shell glob 模式的列表,以将其添加到最终的 packing list 中。这些文件名将相对于 DOCSDIR。因此,使用 PORTDOCS 并使用非默认位置存放文档的 Port 必须相应地设置 DOCSDIR。如果目录在 PORTDOCS 中列出或通过该变量的 glob 模式匹配,则将整个包含的文件和目录的子树注册到最终的 packing list 中。如果未设置 DOCS 选项,则列在 PORTDOCS 中的文件和目录将不会被安装或添加到 Port 的 packing list 中。安装文档到 PORTDOCS 如上所示,仍然由 Port 自身决定。典型的 PORTDOCS 使用示例如下:

PORTDOCS=	README.* ChangeLog docs/*

注意

安装到 DATADIREXAMPLESDIR 下的文件对应的 PORTDOCS 变量分别是 PORTDATAPORTEXAMPLES

pkg-message 中的内容会在安装时显示。有关使用 pkg-message 的详细信息,请参见 pkg-message 部分pkg-message 不需要添加到 pkg-plist 中。

5.17.5. PREFIX 下的子目录

尽量让 Port 将文件放置在 PREFIX 的正确子目录下。某些 Port 会将所有内容都放在一个以 Port 名称命名的子目录中,这是不正确的。此外,许多 Port 会将除了二进制文件、头文件和手册页面之外的所有文件都放在 lib 的子目录下,但这与 BSD 的理念并不兼容。许多文件必须被移动到以下这些目录中的一个:etc(设置/配置文件)、libexec(内部启动的可执行文件)、sbin(供超级用户/管理员使用的可执行文件)、info(用于 info 浏览器的文档)或 share(与架构无关的文件)。有关详细信息,请参见 hier(7);适用于 /usr 的规则也适用于 /usr/local。唯一的例外是处理 USENET "news" 的 Port,它们可以将文件放置在 PREFIX/news 目录中。

最后更新于

这有帮助吗?