5.17.安装文件
最后更新于
最后更新于
重要
install
阶段对最终用户非常重要,因为它将文件添加到他们的系统中。Port Makefile 中的*-install
目标运行的所有附加命令应回显到屏幕上。不要 使用@
或.SILENT
来隐藏这些命令。
INSTALL_*
宏使用 bsd.port.mk 提供的宏来确保在 Port 的 *-install
目标中正确设置文件的权限。通过相应的条目(例如 @(owner,group,)
、@owner<span> </span>owner
和 @group<span> </span>group
)在 pkg-plist 中直接设置所有权。这些操作符在被重写之前有效,或者直到 pkg-plist 的结尾为止,因此请记得在不再需要时重置它们。默认的所有权是 root:wheel
。有关更多信息,请参见 。
INSTALL_PROGRAM
是安装二进制可执行文件的命令。
INSTALL_SCRIPT
是安装可执行脚本的命令。
INSTALL_LIB
是安装共享库(但不是静态库)的命令。
INSTALL_KLD
是安装内核可加载模块的命令。有些架构不喜欢将模块去除符号表,因此请使用此命令,而不是 INSTALL_PROGRAM
。
INSTALL_DATA
是安装可共享数据(包括静态库)的命令。
INSTALL_MAN
是安装手册页和其他文档的命令(它不进行压缩)。
这些变量会被设置为 命令,并根据不同情况使用相应的标志。
重要
不要使用
INSTALL_LIB
来安装静态库,因为去除符号表会使它们变得无用。请改用INSTALL_DATA
。
已安装的二进制文件应该去除符号表。除非绝对必要,否则不要手动去除符号表。INSTALL_PROGRAM
宏会同时安装并去除二进制文件的符号表。INSTALL_LIB
宏对共享库也执行相同的操作。
当必须去除符号表,但不希望使用 INSTALL_PROGRAM
或 INSTALL_LIB
宏时,可以使用 ${STRIP_CMD}
来去除程序或共享库的符号表。这通常是在 post-install
目标中执行。例如:
当需要去除多个文件的符号表时:
重要
当定义了
WITH_DEBUG
时,elf 文件 不得 被去除符号表。如果某些软件在其
LDFLAGS
中添加了-s
,则在这种情况下,要么在设置了WITH_DEBUG
时删除-s
,要么无条件地删除它,并在post-install
中使用STRIP_CMD
。
针对这种情况,有两个宏。使用这些宏的优点是,它们能确保目标文件的正确所有权和权限。第一个宏,COPYTREE_BIN
,会将所有安装的文件设置为可执行,因此适用于安装到 PREFIX/bin 目录下。第二个宏,COPYTREE_SHARE
,不会为文件设置可执行权限,因此适合安装到 PREFIX/share 目标目录下。
此示例会将供应商分发文件中的 examples 目录的内容安装到 Port 的适当示例位置。
这个示例会将夏季月份的数据安装到 DATADIR 下的 summer 子目录。
可以通过 COPYTREE_*
宏的第三个参数传递额外的 find
参数。例如,要安装来自第一个示例的所有文件,但排除 Makefile,可以使用以下命令:
如果软件有除标准 man 页面和 info 页面之外的其他文档,并且对用户有用,可以将其安装到 DOCSDIR
下。这可以像前面的示例一样,在 post-install
目标中进行。
为 Port 创建一个新目录。该目录名为 DOCSDIR
,通常等于 PORTNAME
。但是,如果用户可能希望同时安装不同版本的 Port,则可以使用整个 PKGNAME
。
以下是一些有用的变量及其在 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
选项控制。
所有有条件安装的文档文件和目录都会在 pkg-plist 中以 %%PORTDOCS%%
前缀列出,例如:
作为列出文档文件的替代方法,Port 可以将变量 PORTDOCS
设置为文件名和 shell glob 模式的列表,以将其添加到最终的 packing list 中。这些文件名将相对于 DOCSDIR
。因此,使用 PORTDOCS
并使用非默认位置存放文档的 Port 必须相应地设置 DOCSDIR
。如果目录在 PORTDOCS
中列出或通过该变量的 glob 模式匹配,则将整个包含的文件和目录的子树注册到最终的 packing list 中。如果未设置 DOCS
选项,则列在 PORTDOCS
中的文件和目录将不会被安装或添加到 Port 的 packing list 中。安装文档到 PORTDOCS
如上所示,仍然由 Port 自身决定。典型的 PORTDOCS
使用示例如下:
注意
安装到
DATADIR
和EXAMPLESDIR
下的文件对应的PORTDOCS
变量分别是PORTDATA
和PORTEXAMPLES
。
PREFIX
下的子目录使用 命令可以确定文件是否已去除符号表。二进制文件会被 报告为 stripped
或 not stripped
。此外, 将检测到已去除符号表的程序,并平稳退出。
框架提供的变量(如 STRIP_CMD
、INSTALL_PROGRAM
、INSTALL_LIB
等)和 会自动处理这个问题。
有时,需要安装大量文件,并保持其层次结构不变。例如,将整个目录树从 WRKSRC
复制到 PREFIX
下的目标目录。请注意,PREFIX
、EXAMPLESDIR
、DATADIR
以及其他路径变量必须始终以 STAGEDIR
为前缀,以遵循 staging 机制(参见 )。
这些宏不会将已安装的文件自动添加到 pkg-plist 中。必须手动添加它们。对于可选文档(PORTDOCS
,参见 )和示例(PORTEXAMPLES
),必须在 pkg-plist 中的条目前加上 %%PORTDOCS%%
或 %%PORTEXAMPLES%%
前缀。
由于只有在 pkg-plist 中列出的文件才会被安装,因此始终将文档安装到 STAGEDIR
是安全的(参见 )。因此,.if
块仅在安装的文件足够大,可能导致显著的 I/O 开销时才需要。
另一方面,如果 Port 中有 DOCS 选项,则应在 post-install-DOCS-on
目标中安装文档。这些目标在 中有所描述。
这些变量会被导出到 PLIST_SUB
中。如果可能,它们的值会作为相对 PREFIX 的路径出现在那里。也就是说,share/doc/PORTNAME 将默认替换 %%DOCSDIR%%
,以此类推。(有关 pkg-plist 替换的更多信息,请参见 。)
pkg-message 中的内容会在安装时显示。有关使用 pkg-message 的详细信息,请参见 。pkg-message 不需要添加到 pkg-plist 中。
尽量让 Port 将文件放置在 PREFIX
的正确子目录下。某些 Port 会将所有内容都放在一个以 Port 名称命名的子目录中,这是不正确的。此外,许多 Port 会将除了二进制文件、头文件和手册页面之外的所有文件都放在 lib 的子目录下,但这与 BSD 的理念并不兼容。许多文件必须被移动到以下这些目录中的一个:etc(设置/配置文件)、libexec(内部启动的可执行文件)、sbin(供超级用户/管理员使用的可执行文件)、info(用于 info 浏览器的文档)或 share(与架构无关的文件)。有关详细信息,请参见 ;适用于 /usr 的规则也适用于 /usr/local。唯一的例外是处理 USENET "news" 的 Port,它们可以将文件放置在 PREFIX/news 目录中。