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 目录中。
最后更新于
这有帮助吗?