26.6.从源代码更新 FreeBSD
与二进制更新相比,通过从源代码编译来更新 FreeBSD 具有一些优势。可以用不同的参数来编译代码,以利用特定的硬件。基本系统的某些部分可以用非默认的配置来编译,或者完全丢弃不需要或不想要的地方。与安装二进制更新相比,编译过程需要更长的时间来更新系统,但可完全定制,以产生自定义的 FreeBSD 版本。
这是对通过从源代码编译来更新 FreeBSD 的典型步骤的快速参考。后面的章节会更详细地介绍这个过程。
警告# etcupdate extract ①# etcupdate diff ②② 在自举后检查差异。修剪任何不再需要的本地修改,以减少在未来更新中发生冲突的机会。
更新和编译# git pull /usr/src ①check /usr/src/UPDATING ②# cd /usr/src ③# make -j4 buildworld ④# make -j4 kernel ⑤# shutdown -r now ⑥# etcupdate -p ⑦# cd /usr/src ⑧# make installworld ⑨# etcupdate -B ⑩# shutdown -r now ⑪② 检查 /usr/src/UPDATING,看看在从源代码编译之前或之后是否需要任何手动步骤。③ 切换到源代码目录。④ 编译世界(除了内核以外的一切)。⑤ 编译和安装内核。这等同于make buildkernel installkernel
。⑥ 重新启动系统到新的内核。⑦ 在安装世界之前,更新和合并 /etc/ 中所需要的配置文件。⑧ 切换到源代码目录。⑨ 安装世界。⑩ 更新和合并 /etc/ 中的配置文件。⑪ 重新启动系统以使用新编译的世界和内核。
阅读 /usr/src/UPDATING。在更新之前或之后必须执行的任何手动步骤在这个文件中都有说明。
FreeBSD 的源代码位于 /usr/src/。更新此源代码的首选方法是通过 Git 版本控制系统。验证源代码是否在版本控制之下:
# cd /usr/src
# git remote --v
origin https://git.freebsd.org/src.git (fetch)
origin https://git.freebsd.org/src.git (push)
# git pull /usr/src
如果目录最近没有被更新,更新过程可能需要一些时间。在它完成后,源代码是最新的,可以开始下一节所述的编译过程。
注意获得源代码:如果输出显示fatal: not a git repository
,说明那里的文件缺失或是用不同的方法安装的。需要重新检出该源代码。表 19. FreeBSD 版本和仓库的分支
uname -r 输出 | 仓库路径 | 说明 |
X.Y-RELEASE | releng/ X.Y | RELEASE 版只附带有关键的安全和错误修复补丁。建议大多数用户使用该分支。 |
X.Y-STABLE | stable/ X | RELEASE 版加上该分支上的所有额外开发。STABLE 指的是应用程序二进制接口(ABI)没有改变,因此为早期版本编译的软件仍然可以运行。例如,在 FreeBSD 10.1 上编译的软件仍然可以在后来编译的 FreeBSD 10-STABLE 上运行。STABLE 分支偶尔会有可能影响用户的错误或不兼容,尽管这些通常会很快被修复。 |
X-CURRENT | main | 最新的未发布的 FreeBSD 开发版本。CURRENT 分支可能会有重大的错误或不兼容,因此只推荐给高级用户。 |
# uname -r13.2-RELEASE# mv /usr/src /usr/src.bak ①# git clone --branch releng/13.2 https://git.FreeBSD.org/src.git /usr/src ②① 把旧的目录移开。如果这个目录中没有本地的修改,就可以删除它。
世界,即除了内核以外的所有操作系统,都被编译了。这样做首先是为了提供最新的工具来编译内核。然后是内核本身的编译。
# cd /usr/src
# make buildworld
# make buildkernel
编译后的代码被写到 /usr/obj。
这些是基本步骤。下面将介绍控制编译的其他选项。
某些版本的 FreeBSD 联编系统会将先前编译的代码留在临时对象目录 /usr/obj 中。这可以通过避免重新编译没有变化的代码来加快以后的联编速度。要强制编译所有内容,可以在开始联编前使用
cleanworld
:# make cleanworld
在多核处理器上增加编译作业的数量可以提高编译速度。用
sysctl hw.ncpu
来确定核心数。处理器各不相同,不同版本的 FreeBSD 所使用的联编系统也各不相同,因此测试是唯一可以确定不同数量的作业对联编速度有何影响的方法。作为一个开始,可以考虑核心数的一半到两倍之间的数值。作业数量是用 -j
指定的。例 42. 增加编译作业的数量用四项作业来编译世界和内核:# make -j4 buildworld buildkernel
如果源代码有变化,必须完成
buildworld
。除此之外,可以在任何时候运行 buildkernel
来编译内核。要想只编译内核:# cd /usr/src
# make buildkernel
标准的 FreeBSD 内核基于一个叫做 GENERIC 的 内核配置文件。GENERIC 内核包括最常用的设备驱动和选项。有时,建立一个定制内核是有用的或必要的,可以添加或删除设备驱动程序或选项以适应特定的需要。
例如,有人在开发一台内存严重受限的小型嵌入式计算机时,可以删除不需要的设备驱动程序或选项,使内核略微缩小。
内核配置文件位于 /usr/src/sys/arch/conf/,其中 arch 是
uname -m
的输出。在大多数计算机上,它是 amd64
,给出的配置文件目录是 /usr/src/sys/amd64/conf/。技巧/usr/src 可以被删除或重新创建,所以最好把定制的内核配置文件放在一个单独的目录下,比如 /root。将内核配置文件链接到 conf 目录中。如果该目录被删除或覆盖,内核配置文件可以被重新链接到新目录中。
通过复制配置文件 GENERIC 可以创建一个自定义的配置文件。在这个例子中,新的定制内核是用于存储服务器的,所以被命名为 STORAGESERVER:
# cp /usr/src/sys/amd64/conf/GENERIC /root/STORAGESERVER
# cd /usr/src/sys/amd64/conf
# ln -s /root/STORAGESERVER .
定制的内核是通过在命令行上设置
KERNCONF
到内核配置文件来编译的:# make buildkernel KERNCONF=STORAGESERVER
在
buildworld
和 buildkernel
的步骤完成后,安装新的内核和世界:# cd /usr/src
# make installkernel
# shutdown -r now
# cd /usr/src
# make installworld
# shutdown -r now
如果编译了定制内核,
KERNCONF
也必须被设置为使用新的定制内核:# cd /usr/src
# make installkernel KERNCONF=STORAGESERVER
# shutdown -r now
# cd /usr/src
# make installworld
# shutdown -r now
最后几项任务完成了更新。任何修改过的配置文件都将与新版本合并,过时的库被定位并删除,然后系统被重新启动。
etcupdate(8) 是一个管理更新文件的工具,这些文件没有作为安装世界的一部分被更新,比如位于 /etc/ 的文件。它通过对这些文件的修改与本地版本进行三方合并来管理更新。与 mergemaster(8) 的交互式提示相比,它还被设计为尽量减少用户的干预。
注意# etcupdate diff该命令允许用户审计配置的变化。
# etcupdate resolve
警告# etcupdate extract ①# etcupdate diff ②② 在启动后检查差异。修剪任何不再需要的本地修改,以减少在未来更新中发生冲突的机会。
mergemaster(8) 提供了一种将对系统配置文件的修改与这些文件的新版本进行合并的方法。mergemaster(8) 是替代的 etcupdate(8) 的首选方法。使用
-Ui
,mergemaster(8) 可自动更新未被用户修改的文件,并安装尚未存在的新文件:# mergemaster -Ui
一些过时的文件或目录在更新后可能仍然存在。可以找到这些文件:
# make check-old
并删除:
# make delete-old
一些过时的库也可能保留下来。这些可以用以下方法检测:
# make check-old-libs
并删除:
# make delete-old-libs
当库被删除后,仍然使用这些旧库的程序将停止工作。这些程序必须在删除旧库后重新编译或替换。
技巧当知道所有的旧文件或目录都可以安全删除时,可以通过在命令中设置BATCH_DELETE_OLD_FILES
来避免按y
和回车键
来删除每个文件。比如说:# make BATCH_DELETE_OLD_FILES=yes delete-old-libs
更新后的最后一步是重新启动计算机,以便所有的变化都生效。
# shutdown -r now