一旦 FreeBSD 特定版本(如: FreeBSD-STABLE 或 FreeBSD-CURRENT)的本地源代码树完成同步, 就可以使用这些源代码树重新编译系统。
无需强调操作 之前 应进行备份的重要性, 尽管重新编译系统是一件简单的事情, 但难免会有一些出现在源代码里的问题而导致系统无法正常运行的情况。
创建并校验备份, 并制作一个可引导的安装介质。 您可能永远不会用到它, 但安全第一嘛!
FreeBSD-STABLE 和 FreeBSD-CURRENT 分支, 从实质上都属于 开发阶段 。 为 FreeBSD 贡献者也都是人, 难免会犯错。
这些错误可能没什么危害, 只会让系统生成新的错误警告。 也可能是灾难性的, 可能导致系统无法启动或破坏文件系统。
当问题发生时, 发送一封 “注意 (heads up)” 开头的邮件到相关邮件列表, 并描述问题, 并写上受影响的系统。 当问题解决以后再发送一封 “已解决 (all clear)” 开头的声明邮件。
如果使用 FreeBSD-STABLE 或 FreeBSD-CURRENT 而又不订阅 FreeBSD-STABLE 邮件列表 或 FreeBSD-CURRENT 邮件列表 的用户, 那么完全是自找麻烦。
make world
命令: 一些比较早期的文档推荐使用 make world
命令完成这项工作。
然而, 这个命令会跳过很多重要的步骤,
建议只有在您知道自己在做什么的时候才这样做。 绝大部分情况下,
请不要胡乱使用 make world
命令,
您应该使用以下介绍的方式。
更新系统之前, 请先阅读 /usr/src/UPDATING
文件,
以便了解重新编译 world 之前需要了解哪些事情或注意事项,
然后再执行以下步骤。
这里假定从一个包含旧编译器、 旧内核、旧 world 和旧配置文件的较早 FreeBSD 版本上的升级步骤。 “World” 包含了核心系统二进制文件, 库和程序文件。 编译器是 “world” 的一部分, 但也有一些需要特别注意的问题。
此外, 我们还假定您已获得最新版本的源代码。 如果你还没来得及更新源代码, 请参照 Section 23.6, “同步源代码” 获取同步到最新版本的详细帮助。
从源代码更新系统的步骤有时会比初看上去更麻烦一些, 另一方面, FreeBSD 开发者有时又不得不修改推荐更新步骤, 特别是当出现无法避免的依赖关系的时候。 本节余下部分将介绍目前推荐的更新步骤及其原因。
所有成功的更新操作都必须解决以下这些问题:
旧编译器可能有 bug, 无法编译新内核。 因此, 新内核应该用新编译器构建, 这意味着新内核在构建之前, 新编译器必须先行构建, 但并不意味着在构建新内核之前, 新编译器必须先 安装 。
新 world 可能依赖新内核的某些功能。 因此, 新 world 安装之前, 新内核必须先安装。
这两个问题就是为什么需要按照 buildworld
、
buildkernel
、
installkernel
,
installworld
的顺序来更新的原因,
除此之外还有:
新内核可能无法在旧 world 中正常运行, 因此新 world 必须在新内核安装完成后尽快更新。
一些配置文件需要在安装新 world 之前完成更新, 一些配置文件的更新则会导致旧 world 不能正常工作。 因此, 通常需要两次不同的配置文件更新步骤。
多数情况下, 更新步骤只会替换或增加文件而不会删除现有的旧文件。 某些时候这可能会导致其他问题。 因此, 有时安装操作会指明必须在操作某些步骤前删除这些文件。 未来, 这可能会实现自动化, 也可能无法实现。
由于这些问题的存在, 一般会建议以下更新步骤。 请注意, 对于特定的更新步骤可能需要一些额外的步骤, 但这些核心步骤应该会在很长一段时间保持不变的:
make
buildworld
这个步骤首先会编译新编译器及相关必需工具, 然后使用新编译器来编译新 world 。
编译成果会存放在 /usr/obj
目录。
make
buildkernel
这个步骤将会使用 /usr/obj
中的
新 编译器。 以防止编译器与新内核不匹配的问题。
make
installkernel
将新内核和内核模块安装到磁盘, 以便系统能从新内核启动。
重启进入单用户模式。
单用户模式能尽量减少更新时正在运行的软件导致的问题。 此外, 它也能使新内核配合旧 world 时尽量少出问题。
mergemaster
-p
这个步骤会进行安装新 world 前所需的配置文件更新工作。
例如, 它可能会添加新用户组或用户名的密码数据库到系统中。
这通常是自上次更新后增加了新用户组或特殊系统用户之后才需要做的,
因为 installworld
会需要这些用户或用户组才能完成工作。
make
installworld
从 /usr/obj
中拷贝 world 副本。 这个步骤之后,
您的磁盘上的系统, 包括内核和 world 都将是新的了。
mergemaster
再次更新剩下的配置文件, 现在您磁盘的新 world 更新完成。
make
delete-old
这个步骤目标将是删除旧的(过时的)文件。
这点很重要, 因为有时它们会导致一些问题,
例如, 旧 utmp.h
文件如果存在,
在安装某些需要新的 utmpx.h
文件的 ports 就会出现问题。
重启。
重启计算机, 现在将加载新内核, 新 world 和新配置文件。
make
delete-old-libs
删除所有过时的库, 以避免与新库的发生冲突。 确保所有的 ports 重建之前, 已删除旧库文件。
注意, 如果您正从一个主要 FreeBSD 发行版的分支升级, 例如, 从 9.0 升级到 9.1 ,
则上述步骤可能就没那么必要了, 因为它不太可能遇到严重的编译器、 内核、
用户空间程序和配置文件不匹配的情况不匹配的情况。
旧的 make world
命令可能能完成编译, 并按照新内核,
并有可能正常完成这种次要版本的升级工作。
但是, 在大主版本升级时, 不按前面所介绍的步骤进行升级则很有可能需要一些问题。
值得一提的是, 很多升级过程可能需要额外的附加步骤,
例如, 重命名或删除 installworld 之前的一些特定文件。
仔细阅读 /usr/src/UPDATING
文件,
特别是它结尾部分推荐的升级步骤。
由于这个过程是不断演化的过程中, 开发者可能会发现某些不能完全避免的不匹配方面的问题。 不过幸运的是, 目前这个推荐升级步骤应该会在很长的时间内保持不变。
总之, 目前推荐的从源代码升级 FreeBSD 的步骤是:
#
cd /usr/src
#
make buildworld
#
make buildkernel
#
make installkernel
#
shutdown -r now
有时, 能需要额外执行一次 mergemaster -p
命令,
才能完成 buildworld
步骤。
这些特殊情况一般都会在 UPDATING
中做说明。
一般情况下, 可以简单的跳过这一步,
只要不是一个大跨度的 FreeBSD 版本升级。
在 installkernel
完成后,
需要重启进入单用户模式(loader 加载器提示符后输入
boot -s
)。
如果使用 UFS 文件系统, 运行:
#
mount -u /
#
mount -a -t ufs
如果使用的是 ZFS 文件系统 (假设 zpool 存储池名为 zroot), 则运行:
#
zfs set readonly=off zroot
#
zfs mount -a
然后运行:
#
adjkerntz -i
#
mergemaster -p
#
cd /usr/src
#
make installworld
#
mergemaster
#
make delete-old
#
reboot
#
make delete-old-libs
以上步骤只是升级步骤的简要说明, 所要清楚了解每一步, 尤其是希望自定义内核配置, 就更应该阅读以下内容。
在执行任何更新操作之前, 请务必阅读
/usr/src/UPDATING
文件。
这个文件包含了更新可能存在的潜在问题的重要信息,
或可能指定了某些命令的执行顺序。
如果 UPDATING
中出现的内容与本文相冲突,
请按 UPDATING
中的内容执行。
阅读 UPDATING
并不能替代的订阅适当的邮件列表。
它们并非相互排斥的, 而是相互相成的。
make(1) 可用的参数可以在 make.conf(5)
和 /usr/share/examples/etc/make.conf
中找到。
这些参数可以添加到 /etc/make.conf
文件中,
以控制 make(1) 的运行及其编译程序的方式。
请注意, 默认参数照顾到了性能与安全性, 变更默认参数值可能会产生严重后果,
但也可能会达到意想不到的效果。
/etc/make.conf
中的参数会影响到
make(1) 的每次执行, 包括 Ports Collection ,
用户自己写的 C 语言程序以及重新编译 FreeBSD 操作系统。
/etc/src.conf
文件控制从源代码构建操作系统的相关参数。
与 /etc/make.conf
不同,
/etc/src.conf
仅控制构建 FreeBSD 操作系统本身。
有关这个文件的更多信息, 请参考 src.conf(5) 。 有时,
禁用那些看起来很不是必要的内核模块或编译选项也能有意想不到的效果。
/etc
目录中包含了大部分系统配置文件及系统启动脚本,
这些文件可能会因为 FreeBSD 版本的不同而有所差别。
一些配置文件日常运行时都要经常用到, 比如,
/etc/group
文件。
有时作为安装过程的一部分, make installworld
会要求事先建立某些特定的用户或用户组, 在升级前它们可能并不存在,
因此 make buildworld
会先检查它们是否已存在。
解决的办法是在构建前 (pre-buildworld) 使用个带 -p
参数运行 mergemaster(8) 命令。
它只会更新在 buildworld
和
installworld
过程起关键性作用的文件。
您可以这样检测哪些文件是被重命名或删除了的用户组所拥有的:
#
find / -group GID -print
该命令将会显示所有 GID
用户组所拥有的所有文件,
这里的用户组名称可以是字母组名或数字 ID 。
您可能会考虑在单用户模式下编译系统。 重新安装涉及很多重要的系统文件, 包括所有基本系统的二进制文件、 库文件, 头文件等等。 在正在运行中的系统(尤其是大量用户在线时)更新将是自寻烦恼的行为。
另一种方法是在多用户模式编译系统, 然后切换到单用户模式进行安装。
如果使用这种方法, 可以在编译完成后, 以下命令,
这将会直接切换为单用户模式, 然后执行
installkernel
或
installworld
命令即可:
从正在运行的系统进入单用户模式使用:
#
shutdown now
也可以重启系统, 然后在 boot 提示符下, 选择 “single user” 选项。 单用户模式启动完毕后会得到一个 shell 提示符, 执行:
#
fsck -p
#
mount -u /
#
mount -a -t ufs
#
swapon -a
这将会检查文件系统, 重新以读/写方式挂载 /
,
根据 /etc/fstab
里的记录挂载所有 UFS 文件系统,
最后启用交换分区。
如果您的 CMOS 时钟设置的是本地时间而不是 GMT (就是 date(1) 命令不能报告正确的时间和地区), 您可能还需要执行以下命令:
#
adjkerntz -i
这样就可以确保了本地时区设置正确了。
随着系统重新构建的进行, 编译结果默认会放到 /usr/obj
中, 目录里的结构会对应 /usr/src
里的目录结构。
为了加快 make buildworld
过程,
并避免可能出现的依赖性问题, 如果这个目录已存在, 请删除它。
在 /usr/obj
中的某些文件可能设置了不可更改标志,
删除前必须先使用 chflags(1) 取消这些标志。
#
cd /usr/obj
#
chflags -R noschg *
#
rm -rf *
将 make(1) 输出日志保存这将是一个好主意。 如果出现错误, 可以将该错误消息的副本可以发送到 FreeBSD 邮件列表。
这样做最简单的方法是使用 script(1) 命令,
带上一个保存所有输出的文件名的参数即可。 这一方法应该在重新编译系统之前执行,
编译完成后输入 exit
退出。
#
script /var/tmp/mw.out
Script started, output file is /var/tmp/mw.out#
make TARGET
… compile, compile, compile …#
exit
Script done, …
不要 将输出日志保存到 /tmp
目录,
这个目录可能会在下次启动的时候被清空, 比较稳妥的是保存到
/var/tmp
目录或
root
用户主目录中。
进入 /usr/src
目录:
#
cd /usr/src
使用 make(1) 重新编译 world , 会从 Makefile
(描述如何构建 FreeBSD ,及其构建顺序的文件)中读取构建指令。
命令一般如下格式:
#
make -x -DVARIABLE target
示例中, -
参数会传递给
make(1) 。 更多可用参数, 请参考 make(1) 联机手册。x
-D
会传递一个变量给
变量值
Makefile
。 这些变量会控制
Makefile
的行为。
这与设置 /etc/make.conf
变量一样,
只是提供了另一种设置方法。
#
make -DNO_PROFILE target
如上指定不编译先定库 (profiled libraries) 则等同于在
NO_PROFILE= true # Avoid compiling profiled libraries
/etc/make.conf
里的设置。
target
告诉 make(1) 该执行什么。
每个 Makefile
都定义了许多不同的 “targets” ,
然后由您决定使用哪个 target , 并产生对应结果。
在 Makefile
中列出的 targets ,并不是都需要使用,
targets 的目的是将重新编译系统的过程分成几个子步骤。
大多数情况下都没必要向 make(1) 传递参数, 因此命令看起来像是这样:
#
make target
这里的 target
是众多编译选项中的一个。
一般情况下, 第一个 target 都应该是 buildworld
。
正如名字所暗示的, buildworld
就是在
/usr/obj
下构建一个全新的系统, 然后使用
installworld
将新系统安装到计算机上。
使用独立的选项有两个优点。 首先, 它允许您 “独立” 的构建系统,
而不会影响系统的任何一个部件, 正因如此,
buildworld
可以大胆的在多用户模式下的计算机上执行,
而不用担心用不良影响, 不过依旧推荐您在单用户模式执行
installworld
命令。
其次, 它允许您使用 NFS 升级网络上的多台计算机。 如果您有
A
, B
和
C
三台计算机需要升级, 那么您可以在
A
计算机执行 make buildworld
和
make installworld
命令。
B
和 C
计算机通过 NFS 方式
挂载 A
计算机上的 /usr/src
和
/usr/obj
目录。
运行 make installworld
命令, 将编译成果安装到
B
和 C
计算机上。
尽管 world
target 依旧存在,
强烈建议您不要再使用它。
相反的, 推荐使用:
#
make buildworld
我们可以指定 -j
参数, 强制 make
启动多个并发进程。 对于有多个 CPU 的计算机而言, 这样有助于发挥计算机性能。
不过多数情况下, 编译过程的主要瓶颈在 I/O 上,而不是不是 CPU ,
但它依旧对单个 CPU 的计算机有好处。
在常见的单 CPU 的计算机上, 使用:
#
make -j4 buildworld
这样 make(1) 就能同时启动运行 4 个进程。 根据邮件列表中的统计测试报告, 这样做通常能提供最佳的性能。
如果您的计算机配置了多颗 CPU , 并使用 SMP 内核, 也可以试试 6 到10 的数值, 看看它们是如何高速完成编译的。
要充分利用新系统, 您应该重新编译内核。 这是很有必然的, 因为特定的内存结构已经发生了改变, 像 ps(1) 和 top(1) 这样的程序可能无法正常工作, 除非内核与源代码树的版本是一样的。
要做到这一点最简单, 最安全的方式是构建和安装一个基于
GENERIC
配置文件的内核。 虽然
GENERIC
可能没有包含所有系统所需的设备驱动,
但它包含启动到系统启动到单用户模式所需的所有内容。
这是一个很好的测试新系统是否正常工作的方法。
从 GENERIC
启动, 校验完系统后,
就可以建立您自己的自定义内核了。
在 FreeBSD 上, 在构建新内核前完成 build world 是非常重要的。
如果您想构建一个自定义内核, 并且这个配置文件已经创建完成,
只需要指定内核名称 KERNCONF=MYKERNEL
:
#
cd /usr/src
#
make buildkernel KERNCONF=MYKERNEL
#
make installkernel KERNCONF=MYKERNEL
如果您已把 kern.securelevel
调高到 1 或 以上 , 而且还设置了
noschg
或相似标志到您的二进制内核上,
你可能会发现需要切换到单用户模式执行
installkernel
。
否则, 这两个命令在多用户模式下执行应该也不会有问题。 请参阅
init(8) 以了解更多关于 kern.securelevel
的信息;
参阅 chflags(1) 了解更多不同文件标志的信息。
接下来, 我们使用 installworld
来安装新系统二进制文件:
#
cd /usr/src
#
make installworld
在 make buildworld
时跟随的编译参数,
在 make installworld
时也必须跟随,
当然除 -j
参数外,
它不能用在 installworld
上。
就像这样时:
#
make -DNO_PROFILE buildworld
安装时您也必须这样:
#
make -DNO_PROFILE installworld
否则,该命令将试图安装在 make buildworld
阶段没有建立的先定库。
重构的 world 将不会更新下某些目录, 如 /etc
,
/var
和 /usr
目录下的新的或有变更的文件。
更新这些目录中的文件的最简单的方法是使用在 mergemaster(8) 。
为了避免出错, 请务必先备份 /etc
目录。
mergemaster(8) 工具是一个 Bourne 脚本,
用于检测 /etc
和源代码中的
/usr/src/etc
中的配置文件的差异。
这是保持系统中配置文件与源代码保持同步的一种首选方式。
首先, mergemaster
会建立一个临时的根环境,
在 /
下, 放置各种系统配置文件。 然后,
这些文件会和系统中已按照的文件做对比, 并使用 diff(1) 格式显示出来,
使用 +
表示添加或修改的行, 使用 -
表示完全删除或被替换成了新行。
查阅 diff(1) 联机手册以了解更多有关 diff(1)
的语法和文件不同点是怎么显示的。
mergemaster(8) 会给您显示每个文件的不同处, 这样您就可以选择是删除新文件 (相对临时文件), 是以未改状态安装临时文件, 是以当前安装的文件合并临时文件, 还是再看一次 diff(1) 结果。
选择删除临时文件将让 mergemaster(8) 保留当前文件, 并删除新版本文件。 不建议使用这个选项, 除非您有不变更当前文件的理由。 任何时候, 当需要帮助时, 可以在 mergemaster(8) 提示符里输入 ? , 您将得到帮助。 如果选择跳过这个文件, 将会在其他文件处理完后进行。
选择使用未修改临时文件将会使用新文件替换当前文件。 对于大多数未修改的文件, 这是最好的选择。
选择合并文件将会打开一个文本编辑器, 里面是两个文件的内容。 文件将并排在出现在屏幕上, 从它们中间选择需要部分合并为最终文件。 当两个文件比较时, 使用 l 键选择左边内容, 使用 r 键选择右边内容, 最终文件就是这两部分文件组成的, 然后就可以用它安装。 这个选项通常用于用户修改过的配置文件。
选择再次查看 diff(1) 结果将再次显示文件差异, 就像 mergemaster(8) 之前提示的一样。
最后, 在 mergemaster(8) 完成系统文件处理后, 它还会提示其他问题。 重建密码文件, 并在最后提示您是否删除余下的临时文件。
如果希望手动执行更新, 请不要直接将 /usr/src/etc
下的文件覆盖到 /etc
下, 因为有些文件是需要
“安装” 后才能工作的。 事实上, 并 不是
简单的把 /usr/src/etc
拷贝到 /etc
,
有些文件 /etc
中有, /usr/src/etc
却并不存在的。
如果您使用的是 mergemaster(8) (推荐), 您可以直接跳到 下一节 。
手工合并文件最简单的方法是将文件安装到一个新目录, 然后寻找它们的不同之处。
/etc
: 建议先复制现有的 /etc
到安全的地方, 就像这样:
#
cp -Rp /etc /etc.old
其中 -R
参数会递归复制所有文件,
-p
参数会保留文件时间和属主等等。
创建一个临时目录将新的 /etc
文件和相关文件安装到里面:
#
mkdir /var/tmp/root
#
cd /usr/src/etc
#
make DESTDIR=/var/tmp/root distrib-dirs distribution
这将建立必要的目录结构并安装文件。
在 /var/tmp/root
目录中, 会有很多子目录是空的,
要删除它们最简单的方法是:
#
cd /var/tmp/root
#
find -d . -type d | xargs rmdir 2>/dev/null
这样将会删除所有空目录, 同时将有关非空目录的警告信息重定向到
/dev/null
设备。
/var/tmp/root
现在包含了应放在
/
某个位置的文件。 通过这些文件,
比对系统中已存的文件有何差异。
/var/tmp/root
目录下有些 “.” 开头的文件,
可能需要 ls -a
才能看得到它们。
比较文件的最简单的方法是使用 diff(1) :
#
diff /etc/shells /var/tmp/root/etc/shells
这个命令将会显示现有的 /etc/shells
和
新 /var/tmp/root/etc/shells
文件的差异。
这个差异决定了您是合并还是直接替换就旧文件。
/var/tmp/root
),
这样您可以轻松比较两个版本的不同:: 频繁重建系统意味着必须频繁更新 /etc
,
而这可能会有些烦。
为了加快这一进程, 可以使用以下过程来保留最后一套被合并的
/etc
文件的副本。
像通常那样建立 world 。当更新 /etc
及其相关目录时,
可以在目标目录基础上加一个当前日期到名称里:
#
mkdir /var/tmp/root-20130214
#
cd /usr/src/etc
#
make DESTDIR=/var/tmp/root-20130214 \ distrib-dirs distribution
在这个目录的基础上进行合并工作, 当合并完成时, 请 不要 删除这个目录。
下载源代码的最新版本和修改后, 按照第一步,
创建一个反映新日期的目录, 例如使用
/var/tmp/root-20130221
。
使用 diff(1) 查看这段相隔的时间里两个目录之间的递归差异:
#
cd /var/tmp
#
diff -r root-20130214 root-20130221
通常, 这组差异比起 /var/tmp/root-20130221/etc
与 /etc
之间的差异要明显小很多,
也就更容易把这些变更合并到 /etc
中去。
完成后, 就可以删除较早的 /var/tmp/root-*
目录:
#
rm -rf /var/tmp/root-20130214
每次需要合并 /etc
,
都重复这个流程就可以了。
使用 date(1) 自动生成目录名称:
#
mkdir /var/tmp/root-`date "+%Y%m%d"`
由于 FreeBSD 的开发周期里, 偶尔会有些文件或内容会过时的情况。
这可能因为这个功能在其他地方实现, 或库版本号变更,
也可能是完全从系统中移除等等。 在更新系统时, 包括旧文件,
旧库文件, 旧目录, 它们都应该被从系统中移除,
这是有好处的, 这样可以保证系统稳定,
同时减少了不必要的磁盘空间及备份空间的浪费, 另外,
如果旧库或文件存在安全或稳定性问题, 系统更新它们可以保证安全,
同时防止因旧库导致的崩溃。
过时的文件, 目录, 库文件都会在
/usr/src/ObsoleteFiles.inc
中列出。
接下来, 将介绍如何删除这些文件。
在 make installworld
和
mergemaster
命令完成后,
可以使用以下命令检测过时的文件和库文件:
#
cd /usr/src
#
make check-old
如果检测到任何过时的文件, 则可以使用以下的命令移除:
#
make delete-old
参阅 /usr/src/Makefile
可以了解更多其他
targets 的功能。
当删除每一个文件之前都会出现一个确认提示。
要跳过提示, 让系统自动删除这些文件,
可以设置 BATCH_DELETE_OLD_FILES
变量, 就像这样:
#
make -DBATCH_DELETE_OLD_FILES delete-old
也可以使用 yes
命令配合管道实现类似目的:
#
yes|make delete-old
删除过时的文件可能会破坏现有的依赖于这些过时的文件的应用程序。
尤其对于删除旧库文件这种情况, 多数情况下,
在重新编译所有依赖旧库的 ports 程序之后,
make delete-old-libs
删除那些过时的文件。
通用检测共享库依赖的工具 sysutils/libchk 和 sysutils/bsdadminscripts 可以通过 Ports Collection 安装。
过时的共享库与新共享库可能发生冲突, 会导致类似的警告消息:
/usr/bin/ld: warning: libz.so.4, needed by /usr/local/lib/libtiff.so, may conflict with libz.so.5 /usr/bin/ld: warning: librpcsvc.so.4, needed by /usr/local/lib/libXext.so, may conflict with librpcsvc.so.5
为了解决这类问题, 需要确定是哪个 port 安装了这个库文件:
#
pkg_info -W /usr/local/lib/libtiff.so
/usr/local/lib/libtiff.so was installed by package tiff-3.9.4#
pkg_info -W /usr/local/lib/libXext.so
/usr/local/lib/libXext.so was installed by package libXext-1.1.1,1
然后卸载, 重新编译和安装的该 port 。 可以使用 ports-mgmt/portmaster 工具自动化完成此过程。 在确认所有 ports 都已经重建, 并不再有需要依赖旧库的情况后, 执行以下命令删除它们:
#
make delete-old-libs
你现在应该已经成功升级了 FreeBSD 。 恭喜。
如果进展不顺利, 很容易重建系统的某一部分。
例如, 在升级或合并 /etc
时不小心删除了
/etc/magic
, 这将会导致 file(1) 停止工作,
这种情况下, 可以执行以下命令进行修复:
#
cd /usr/src/usr.bin/file
#
make all install
23.7.16.1. | 是否每个变更都需要重新编译 world ? |
这不好说, 主要看是什么性质的变更。 比如: 如果 svn 更新了以下文件:
这样就没必要重建 整个 world 。
只需要进入相应的子目录, 运行 每天天结束的时候, 你就可以开始编译。 也有些用户会让变更累积两个星期后再重新编译 world 。 您也可以只重新编译变更过的部分, 不过那样你得确认能找出所有依赖关系。 这取决与您希望什么样的升级频率, 以及是否是跟踪 FreeBSD-STABLE 或 FreeBSD-CURRENT 。 | |
23.7.16.2. | |
这通常表明硬件出错。 (重新)构建 world 是高压测试硬件的有效方式, 常常表现为编译器由于内存错误莫名其妙的终止了。 一个确信的指示器是如果重新开始 make , 并且整个过程中会死在不同的点上。 对于这种情况, 可以更换机器的某个部件, 检测是哪一部分硬件出问题了。 | |
23.7.16.3. | 完成后可以删除 |
简单的说, 可以。 在 高级用户可以指定 | |
23.7.16.4. | 构建过程中断可以恢复吗? |
这取决于您在出问题前整个过程进行到哪一步了。 一般来说, 如果您已经处于最后一个阶段, 则可以相当安全使用: … fix the problem … 这样就不会取消先前的 如果您看到这样的消息: -------------------------------------------------------------- Building everything.. -------------------------------------------------------------- 如果 如果没有显示这条消息, 或者你不能确定, 则重新开始构建要比继续构建而导致失败的好。 | |
23.7.16.5. | 我怎样才能加速构建 world ? |
| |
23.7.16.6. | 如果出错, 我该怎么办? |
请确保系统没有先前构建任何残留:
是的, 然后, 使用 如果问题仍然存在, 请发送错误信息和 |
本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读
文档,如不能解决再联系
<questions@FreeBSD.org>.
关于本文档的问题请发信联系
<doc@FreeBSD.org>.