FreeBSD Ports 中的 OPTIONS 功能介绍——使用 OPTIONS_SET/OPTIONS_UNSET/NO_DIALOG 进行操作和实践
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
原文:
作者:重村法克
2021-04-04
即使到了 2020 年,依然有“还在编译吗?”的疑问,在如今的 FreeBSD 中,除了基础系统之外,第三方应用的二进制包的使用(安装)已经变得非常普及。事实上,轻松设置并使用的话,二进制包已经足够使用。然而,对于我个人来说,由于需要高度自定义使用,所以无法完全满足于二进制包的需求。因此,整理了一下 FreeBSD Ports 的自定义方法。
关于什么是 Ports(FreeBSD Ports),请参见参考文献。抱歉。
截至 2020 年,由于该方案已经出现了五年多,因此适用于当前所有支持的 FreeBSD 环境。大体上,版本 10 及以上都可以使用。
通过引入 OPTIONS(/usr/ports/Mk/bsd.options.mk
)机制[1],统一了使用 Ports 编译第三方应用时的自定义方法。
引入 OPTIONS 前后的 Makefile 编写方式发生了变化,OPTIONS 引入之前的机制(几乎)已经不再使用[2]。
严格来说,它仍然存在并且在一些情况下被使用,但多用于极其特殊的、黑客式的自定义用途,因此本次讨论将跳过这部分内容。
OPTIONS 是一种控制机制,用于控制每个 Port 中可以自定义的选项的启用与禁用。它提供了以下功能:
定义可自定义的选项(选项名称)
解释这些选项的功能(说明)
默认启用或禁用的值
提供有关行为(如依赖关系、安装方法等)的帮助
Port 维护者通过将这些内容记录在 Makefile 中,允许用户仅通过选择开启或关闭选项来进行自定义。
在编译时会显示一个对话框,允许用户交互式地选择这些自定义项。可以通过以下命令来配置这些选项[3][4]:
命令执行示例
尤其需要注意的是,一旦通过对话框确认了设置后,除非显式地执行 make config
,或者在有新选项添加时,系统不会再次显示对话框。如果想恢复到默认设置,可以使用 make rmconfig
来删除通过对话框设置的内容。
通过在 /etc/make.conf
中进行配置,可以全局定义自定义内容(启用或禁用)。例如,如果不需要 X11,或想要使用 LZ4 作为压缩算法,可以在所有 Ports 中统一设置。
/etc/make.conf 配置示例
在 /etc/make.conf
中,还可以根据 Port 进行个性化设置。例如,虽然通常希望安装文档,但为了避免安装 TeX 等相关组件,可能希望放弃安装文档。在这种情况下,可以通过 ${OPTIONS_NAME}_SET
或 ${OPTIONS_NAME}_UNSET
来定义设置。
/etc/make.conf 配置示例
${OPTIONS_NAME}
是通过执行 make -VOPTIONS_NAME
获取的每个 Port 的字符串。上述示例中,某些变量名可能包含 -
或 +
,但在 Makefile 中不会造成问题。
需要注意的是,OPTIONS 引入时使用的是 UNIQUENAME
,但由于与其他机制冲突,后来改为使用 OPTIONS_NAME
。
在 bsd.options.mk
中,以下设置无论 Port 的默认配置如何,都会被启用:
DOCS
NLS
EXAMPLES
IPV6
即使在 Port 的默认设置中没有启用 DOCS
,但如果对话框选项中包含 DOCS
,则实际会启用该选项。这就是为什么即使 Port 默认没有启用 DOCS
,它仍然被启用的原因。
/etc/make.conf
(${OPTIONS_NAME}_SET_FORCE
/${OPTIONS_NAME}_UNSET_FORCE
)
/etc/make.conf
(OPTIONS_SET_FORCE
/OPTIONS_UNSET_FORCE
)
make config
/etc/make.conf
(${OPTIONS_NAME}_SET
/${OPTIONS_NAME}_UNSET
)
/etc/make.conf
(OPTIONS_SET
/OPTIONS_UNSET
)
bsd.options.mk
Makefile
/Makefile.local
需要注意的是,_SET
在处理后,才会处理 _UNSET
,因此优先级是 _UNSET
> _SET
,即 _UNSET
的效果更强。
也就是说,包管理系统默认是没有进行自定义的,应该是没有显示对话框的情况下直接处理的![6]
实际上确实存在这样的选项。只需在 /etc/make.conf
中添加以下内容,就可以在没有任何对话框显示的情况下(即没有自定义)开始编译所有的 Ports:
/etc/make.conf 配置示例
实际上,这只是跳过了对话框的显示,之前执行过的 make config
的结果,以及前面提到的 OPTIONS_SET
/OPTIONS_UNSET
等设置仍然会生效。因此,这样做并不意味着完全默认,但可以提供与二进制包兼容的操作方式。
它在安装时会将钩子添加到 /etc/make.conf
,并通过 /usr/local/etc/ports.conf
→ /usr/local/libexec/portconf
→ /etc/make.conf
的方式协同工作,使得好像从一开始就在配置文件中写入了这些设置。因此,不应删除 /etc/make.conf
中的钩子。
它的工作方式是将配置文件中的 Port 目录名与当前目录进行比较(通过通配符匹配),如果匹配成功,则会将相应的内容纳入。
例如,在下面的例子中,当在 /usr/ports/databases/sqlite3
目录下执行 /usr/local/libexec/portconf
时,你会看到 |NO_DIALOG=yes
被显示出来。
/usr/local/etc/ports.conf 配置示例
在此示例中,像 SQLite3 这样的配置可以非常细致地进行自定义,但有时可能会引入会导致丧失二进制兼容性的自定义(此时它会默认关闭)。因此,某些 Port 最好避免过度自定义。
在 OPTIONS 的情况下,像 ${OPTIONS_NAME}_SET
和 ${OPTIONS_NAME}_UNSET
这样的选项可以明确地为每个 Port(${OPTIONS_NAME}
)指定 OPTIONS_SET
和 OPTIONS_UNSET
。但是,像 NO_DIALOG
这样的全局设置不能为每个 Port 单独设置。这时,就可以使用 portconf
。
当然,也可以不使用 ${OPTIONS_NAME}_SET
或 ${OPTIONS_NAME}_UNSET
,而是使用 OPTIONS_SET
或 OPTIONS_UNSET
来在 ports.conf
中配置,但在没有安装 portconf
的环境中构建时,这可能会有较大影响。因此,在影响较小的地方使用 portconf
会是更高效的做法。
理解了上述内容之后,你可以通过执行 pkg info -D portconf
来查看配置内容并进行编辑。
当所有 Port 都设置为 NO_DIALOG
且没有自定义时是可以的。如果你想在包的更新速度较慢时通过 Ports 编译来替代,请确保不要进行自定义。
基本上不行。虽然在有限的情况下可能可以通过一些实验来实现,但这需要不断的测试和调整,且未来的兼容性不能保证。自定义后,某些功能是否启用或者禁用,可能导致某些功能缺失或者不可用,这种问题通常是在运行时才会发现(没有二进制兼容性)。这种变化的影响有时比版本升级的影响更大。
这也许有点警告的意味,但对于中间件(尤其是库)类型的 Port 来说,如果“没有必要”进行自定义,对于应用程序类型的 Port 来说,如果“已经存在”,是没有问题的。
SET
与 UNSET
有什么区别?A. 没问题的。你的理解是正确的。虽然这应该解释清楚,但我累了,得休息一下。
2012 年 05 月以降:当然,新的系统引入时,并不是所有的 Ports 都立刻支持,但已经过去 8 年多了。
WITHOUT_X11
等的定制设置不再使用:这些主要的定制选项已经不再使用(严格来说,这是一种错误的用法)。
config
,showconfig
,rmconfig
的功能:config
用来设置,showconfig
用来查看当前设置,rmconfig
用来删除设置。
-recursive
选项:这个选项会递归地处理所有依赖关系。
WITH
和 WITHOUT
选项的作用:通过 WITH
指定的选项会被 SET
,而通过 WITHOUT
指定的选项会被 UNSET
。
关于包管理系统的使用和定制:经过简单调查后,发现没有明确的包管理系统运作信息。基于对使用工具和定制化的预测,个人推测这可能不需要太多定制。
关于日文版和英文版的差异:由于日文版的记录较为过时,请参考英文版,尤其是 pkgng
相关的部分已经完全过时。
make WITH="选项1 选项2..." WITHOUT="选项1 选项2..."
指定的情况^^
是一个工具,允许在 /usr/local/etc/ports.conf
配置文件中记录各个 Port 的自定义设置。
アプリケーションのインストール - packages と ports ^^
Ports Collection の利用 ^^