5.17.安装文件
重要
install阶段对最终用户非常重要,因为它将文件添加到他们的系统中。Port Makefile 中的*-install目标运行的所有附加命令应回显到屏幕上。不要 使用@或.SILENT来隐藏这些命令。
5.17.1. INSTALL_* 宏
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_PROGRAM 或 INSTALL_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) 报告为 stripped 或 not stripped。此外,strip(1) 将检测到已去除符号表的程序,并平稳退出。
重要
当定义了
WITH_DEBUG时,elf 文件 不得 被去除符号表。框架提供的变量(如
STRIP_CMD、INSTALL_PROGRAM、INSTALL_LIB等)和USES会自动处理这个问题。如果某些软件在其
LDFLAGS中添加了-s,则在这种情况下,要么在设置了WITH_DEBUG时删除-s,要么无条件地删除它,并在post-install中使用STRIP_CMD。
5.17.3. 安装整个文件树
有时,需要安装大量文件,并保持其层次结构不变。例如,将整个目录树从 WRKSRC 复制到 PREFIX 下的目标目录。请注意,PREFIX、EXAMPLESDIR、DATADIR 以及其他路径变量必须始终以 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/*注意
安装到
DATADIR和EXAMPLESDIR下的文件对应的PORTDOCS变量分别是PORTDATA和PORTEXAMPLES。pkg-message 中的内容会在安装时显示。有关使用 pkg-message 的详细信息,请参见 pkg-message 部分。pkg-message 不需要添加到 pkg-plist 中。
5.17.5. PREFIX 下的子目录
PREFIX 下的子目录尽量让 Port 将文件放置在 PREFIX 的正确子目录下。某些 Port 会将所有内容都放在一个以 Port 名称命名的子目录中,这是不正确的。此外,许多 Port 会将除了二进制文件、头文件和手册页面之外的所有文件都放在 lib 的子目录下,但这与 BSD 的理念并不兼容。许多文件必须被移动到以下这些目录中的一个:etc(设置/配置文件)、libexec(内部启动的可执行文件)、sbin(供超级用户/管理员使用的可执行文件)、info(用于 info 浏览器的文档)或 share(与架构无关的文件)。有关详细信息,请参见 hier(7);适用于 /usr 的规则也适用于 /usr/local。唯一的例外是处理 USENET "news" 的 Port,它们可以将文件放置在 PREFIX/news 目录中。
最后更新于
这有帮助吗?