Gentoo Logo

Gentoo GCC升级指南

内容:

1.  简介

GCC升级

为什么要升级?GCC就如同系统上的其他软件一样,只是更重要一点。当新版本中以前让你烦恼的bug已经修复,你需要的新功能已经引入或者你只是想保持系统更新时,都可以升级GCC。如果前面的情况都不适合你,完全可以推迟升级,只要所用的GCC版本还被Gentoo开发团队所支持。

如果你安装了GCC的一个新的主版本(例如从3.3.6至3.4.5),系统并不会自动切换使用新版本。你必须手动切换,因为迁移过程还需要额外的步骤。如果你决定不切换,Portage就会继续使用旧版本,直到你切换或者从系统里移除旧的编译器。非主版本升级则会自动切换(例如从3.4.5至3.4.6)。

这份指南将给出无缝升级Gentoo系统编译器的必要步骤。一个章节专门讲述了从GCC 3.3升级至3.4libstdc++的问题。另一个章节则是专门为新的GCC主要/非主要版本发布后,使用stage3包首次安装Gentoo的用户准备的。

警告: 注意从GCC-3.4(或3.3)升级到GCC-4.1或更高还需按照一般升级步骤来做,因为GCC-3.4和GCC-4.1使用了稍稍不同的ABI。

2.  一般升级步骤

简介

重要: 如果你在找针对GCC-3.3升级到GCC-3.4的教程,请查阅专门章节

重要: 如果你在找针对新安装系统的GCC升级教程,请查阅专门章节

通常来说,bug修复版本的升级,像3.3.5到3.3.6,是非常安全的——只要emerge新版本,再切换并重建受影响的libtool包就可以了。有些GCC升级破坏了二进制兼容,如此就需要重新编译所有受影响的包。

当谈到手动切换编译器到新版本时,我们曾说这不会自动进行。但也有个例外——比如bug修复升级,从3.3.5升级到3.3.6,如果你没有启用“multislot” USE标记使之共存就会自动切换。而“multislot”默认是禁用的,因为启用这个USE标记对大多数用户来说没有多大好处。

代码 2.1: 升级GCC

# emerge -uav gcc

(请用你的CHOST和所要升级的版本号来替换“i686-pc-linux-gnu-4.1.1”:))
# gcc-config i686-pc-linux-gnu-4.1.1
# env-update && source /etc/profile

如果你打算把gcc从3升级到4(这个例子是从3.4.6升级到4.1.1),需要手动运行fix_libtool_files.sh。
(用你在/etc/make.conf实际设置的CHOST来替换$CHOST)
(用你升级的新版本号代替<gcc-version>)
# /usr/share/gcc-data/$CHOST/<gcc-version>/fix_libtool_files.sh 3.4.6

(重建libtool)
# emerge --oneshot -av libtool

必须利用新的编译器重建工具链以及world,这样才能保持系统的健全状态。

代码 2.2: 重建系统

# emerge -eav system
# emerge -eav world

这时就可以安全地移除旧版本的编译器了。如果你觉得需要,按照以下命令做(像往常一样,用你想要移除的版本代替=sys-devel/gcc-3.4*):

代码 2.3: 移除旧版本的GCC

# emerge -aC =sys-devel/gcc-3.4*

重要: 请注意GCC 4.1及更新的版本只能用来编译2.4.34及更高版本的内核。如果你要编译旧内核,就不要移除旧版的GCC了。

重要: 如果你是从GCC-3.3升级,可以运行emerge --oneshot sys-libs/libstdc++-v3来提供对旧的二进制程序的兼容。

3.  从GCC-3.3升级到3.4

简介

由于C++ ABI的变化,不能从GCC-3.3无缝升级到3.4。libstdc++有一些细节要加以注意。

选择

重要: 如果你是从gcc3.4升级到4.1,请查阅通用升级指引

重要: 如果你是在SPARC机器上升级,由于GCC参数传递ABI的改变,需要参照完整系统重建指南

如果你从gcc3.3升级到3.4,有两种办法来升级系统。第一种方法更快并要求使用gentoolkit包中的revdep-rebuild工具。第二种方法是从头编译整个系统以使新GCC的特性能得以利用。用哪种方法取决于你自己。通常第一种方法就足够了。

如果你从gcc 3.3升级到4.1,就不能用基于revdep-rebuild的方法了,老实去重建整个系统

使用revdep-rebuild

这个方法要求先安装gentoolkit。然后再升级GCC并切换到新版本。我们也要重建libtool包以保证toolchain处于正常状态。

代码 3.1: 安装gentoolkit并升级GCC

# emerge -an gentoolkit
# emerge -uav gcc
(请用你的CHOST和所要升级的版本号来替换“i686-pc-linux-gnu-3.4.5”:))
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(重建libtool)
# emerge --oneshot -av libtool

现在我们来看看revdep-rebuild想要重建哪些包,然后再真正地去重建。这要点时间,耐心点。

代码 3.2: 使用revdep-rebuild

# revdep-rebuild --library libstdc++.so.5 -- -p -v
# revdep-rebuild --library libstdc++.so.5

注意: 你可能会遇到包不存在、被屏蔽或者过时的问题。如果确实是这样,可以使用revdep-rebuild--package-names选项。这样可以根据包的名称来重新编译软件包,而不必精确到具体的软件包版本。

需要在卸载系统里的GCC 3.3之前安装sys-libs/libstdc++-v3以提供对旧的二进制C++程序和revdep-rebuild漏掉的软件包的兼容性。

代码 3.3: 安装libstdc++-v3并清理

# emerge --oneshot sys-libs/libstdc++-v3
# emerge -aC =sys-devel/gcc-3.3*

使用emerge -e

这种方法慢得多,需要重新编译整个系统以确保所有软件都用新编译器重新编译过,因此也更安全。首先,你要升级GCC和libtool然后切换到新的编译器。

代码 3.4: 升级GCC

# emerge -uav gcc
(请用你的CHOST和所要升级的版本号来替换“i686-pc-linux-gnu-3.4.5”:))
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

如果你是从gcc 3升级到4(例如这个例子里从3.3.6升级到4.1.1),需要手动运行fix_libtool_files.sh。
(用你在/etc/make.conf实际设置的CHOST来替换$CHOST)
(用你升级的新版本号代替<gcc-version>)
# /usr/share/gcc-data/$CHOST/<gcc-version>/fix_libtool_files.sh 3.3.6

(重建libtool)
# emerge --oneshot -av libtool

需要安装sys-libs/libstdc++-v3来提供对旧的二进制C++程序的兼容性。

代码 3.5: 安装libstdc++-v3

# emerge --oneshot sys-libs/libstdc++-v3

现在我们开始重建system,然后是world。这要很长时间,由所安装的软件包数量决定。同时也将重建整个toolchain,更新toolchain和每个软件包的系统支持文件。这能够保证所有软件包都能够被新的工具链重新编译,包括工具链本身。

代码 3.6: 重建system和world

# emerge -e system
# emerge -e world

这时候移除旧版本的GCC是安全的:

代码 3.7: 清理

# emerge -aC =sys-devel/gcc-3.3*

4.  在第一次安装的系统上升级GCC

简介

在刚从stage3 tarball安装的系统上做GCC升级是件简单的事。全新安装的优势是没有过多的软件链接到旧版GCC。下面的例子是从GCC-3.3升级到3.4。如果从其它版本的GCC升级某些步骤会有不同。例如,下面的revdep-rebuild所用的库名和安装libstdc++-v3的要求是由GCC 3.3决定的。

如果用户还没有制定系统,升级GCC到新版本只需少许几步。如果是GCC-3.3到3.4的升级,用户会有两种选择。然而,不像GCC-3.3升级到3.4,这里的方法要简单得多,因为两种方法都差不多。第一种方法更快,其中利用了gentoolkit中的revdep-rebuild工具,类似于前面提到的步骤。使用revdep-rebuild只重新编译直接链接到GCC库的软件包。第二种方法要花更长的时间把整个新安装的系统用新的GCC编译一遍。第二种方法不是必需的,只是为了文档的完整而顺带提及。

第一步是两种方法共有的,每个人都要照着做。

代码 4.1: 升级GCC

# emerge -uav gcc
(请用你的CHOST和所要升级的版本号来替换“i686-pc-linux-gnu-3.4.5”:))
# gcc-config i686-pc-linux-gnu-3.4.5
# source /etc/profile

(重建libtool)
# emerge --oneshot -av libtool

需要安装sys-libs/libstdc++-v3来提供对旧的二进制C++程序的兼容性。

代码 4.2: 安装libstdc++-v3

# emerge --oneshot sys-libs/libstdc++-v3

使用revdep-rebuild

这种方法要先安装gentoolkit。然后运行revdep-rebuild扫描所安装软件中需要重新编译的部分,再重新编译他们。

代码 4.3: 安装gentoolkit并运行revdep-rebuild

# emerge -an gentoolkit
# revdep-rebuild --library libstdc++.so.5 -- -p -v
# revdep-rebuild --library libstdc++.so.5

注意: 你可能会遇到包不存在、被屏蔽或者过时的问题。如果确实是这样,可以使用revdep-rebuild--package-names选项。这样可以根据包的名称来重新编译软件包,而不精确到具体的软件包版本。

使用emerge -e

这个方法比较慢,将编译system目标以保证所有东西都用新的编译器编译过。这不是必需的,但如果你同时改动了CFLAGS或者make.conf中其他影响系统编译的变量,这么做是很正确的。

既然在初始化安装后做过了,我们就不需要重新编译world,等到升级的时候自然会做。当然,你也可以在升级system的时候顺带升级world,以保证所有的软件包都被升级过。

代码 4.4: 重建系统

# emerge -e system

清理

这时候移除旧版本的GCC是安全的。用你要升级的实际版本代替YOUR-NEW-GCC-VERSION

代码 4.5: 清理

# emerge -aC "<sys-devel/gcc-YOUR-NEW-GCC-VERSION"

5.  常见误区

在升级的时候禁用distcc很重要。混用不同版本的编译器出错。升级也不需要ccache,因为所有的缓存目标都将失效。

必需使用相同版本的GCC来编译内核和相关模块。一旦用新的GCC重新编译了world,外部模块(如app-emulation/qemu-softmmu)就会无法载入。这时就要用新版的GCC重新编译内核来修复这个问题。

如果你在SPARC机器上升级,务必在重新编译world后运行silo -f来避免可能发生的问题。

常见错误信息

如果你的系统抱怨libtool: link: `/usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.6/libstdc++.la' is not a valid libtool archive,请运行/usr/share/gcc-data/$CHOST/<gcc-version>/fix_libtool_files.sh 3.3.6 (用出错信息中的版本号代替“3.3.6”,$CHOST和<gcc-version>也要一并替换)。

如果你见到error: /usr/bin/gcc-config: line 632: /etc/env.d/gcc/i686-pc-linux-gnu-3.3.5: No such file or directory,可以试试删除/etc/env.d/gcc/config-i686-pc-linux-gnu然后在source /etc/profile后再运行gcc-config。只能在你没有设置交叉编译器时才能这样做。

如果有包在emerge -e systememerge -e world时失败,可以用emerge --resume继续下去。如果一个包反复失败,可以用emerge --resume --skipfirst跳过。不要开两个以上emerge实例,否则会错过摘要信息。

如果你在升级编译器的时候得到错误信息spec failure: unrecognized spec option,试试切换回默认的编译器,清除GCC_SPECS变量再升级GCC。

代码 5.1: 重置主要配置

# gcc-config 1
# source /etc/profile
# unset GCC_SPECS
# emerge -uav gcc


打印

更新于2008年 7月 19日

本翻译的原始版本已经不再被维护

总结: 这份文档给出了升级GCC的全过程。

Wernfried Haas
作者

Jan Kundrát
作者

Mark Loeser
编辑

Joshua Saddler
编辑

黄曦
译者

Le Zhang
审校

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.