安装 GCC-3.3.2 - 第二遍

预计所需编译时间:      11.0 SBU
预计所需硬盘空间:      274 MB

再次安装 GCC

测试GCC和Binutils的工具已经安装好了(Tcl, Expect 和 DejaGnu)。我们可以重新编译GCC和Binutils,把它们连接到新的Glibc上,并测试它们的正确性。要注意一件事,这些测试套件受 pseudo 终端(PTYs)的影响很大,这些终端是由主系统提供的,通过 devpts 文件系统实现。你可以用下面的方法,来测试主系统中PTY是否设置正常:

expect -c "spawn ls"

如果你得到下面的回答:

The system has no more ptys.  Ask your system administrator to create more.

说明主系统的PTY没设置好。这种情况下,运行GCC和Binutils的测试套件就没什么意义了。你需要先解决主系统中的PTY设置问题。参见 LFS Wiki(http://wiki.linuxfromscratch.org/).

现在我们要编译C和C++编译器,因此要在同一目录下解压所有的三个GCC压缩包(-core, -g++, 和 -testsuite),它们会释放到名为gcc-3.3.2/的同一子目录中。

首先纠正一个问题,并做一些调整:

patch -Np1 -i ../gcc-3.3.2-no_fixincludes-1.patch
patch -Np1 -i ../gcc-3.3.2-specs-1.patch

第一个补丁禁止GCC中"fixincludes"脚本的运行。我们前面提到过一些,这里再深入地看看这个脚本的作用。在通常情况下,GCC的fixincludes脚本会搜索你的系统头文件目录,找出需要修正的头文件。比如,它可能找出主系统的glibc头文件需要修正,就把修正后的文件放到GCC的头文件目录里。随后,在第六章里,我们安装过新的glibc后,gcc的头文件目录会排在glibc头文件目录的前面,结果就是gcc使用的头文件是从主系统里来的glibc头文件,而不是我们新安装的那个。这可能会造成不兼容。

后一个补丁修改gcc的缺省动态连接器ld-linux.so.2的位置,还把/usr/include从GCC的头文件搜索路径里删掉。在安装前打补丁,可以保证新的动态连接器在编译gcc的时候就用上。也就是说,随后的所有临时程序都会连接到新的glibc上。

重要: 这两个补丁 非常重要,为了成功编译,千万别忘了运用它们。

再次创建专用的编译目录:

mkdir ../gcc-build
cd ../gcc-build

在开始编译前,别忘了去掉任何优化相关的环境变量。

现在为编译GCC做准备:

../gcc-3.3.2/configure --prefix=/tools \
    --with-local-prefix=/tools \
    --enable-clocale=gnu --enable-shared \
    --enable-threads=posix --enable-__cxa_atexit \
    --enable-languages=c,c++

新配置参数的意思是:

编译软件包:

make

现在没必要用bootstrap作为make的目标,因为这里gcc是用相同版本的gcc来编译的,其实连源码都一模一样,就是在第一遍的时候安装的那个。

注: 要说明的是,这里运行测试套件,并没有第六章里运行它那么重要。

运行测试套件:

make -k check

-k 参数是让测试套件即使遇到错误,也继续运行,直到完成。GCC 的测试套件非常详细,所以基本上是肯定会出错的。要看测试结果,用下面的命令:

../gcc-3.3.2/contrib/test_summary | more

你可以把自己的结果与gcc-testresults邮件列表上贴出来的比较一下。比如,GCC-3.3.2 在i686-pc-linux-gnu平台上的结果,见:http://gcc.gnu.org/ml/gcc-testresults/2003-10/msg00803.html.

注意,结果里包含:

* 1 XPASS (unexpected pass) for g++
* 1 FAIL (unexpected failure) for gcc
* 26 XPASS's for libstdc++

g++ 的 unexpected pass(没料到的通过)是因为使用了--enable-__cxa_atexit. 很明显,不是所有平台的C库都支持 "__cxa_atexit",所以这个测试没指望能通过的。

libstdc++的26个unexpected passe是因为使用了--enable-clocale=gnu,这只对于 Glibc 2.2.5以上的系统才适用。GNU C库的locale支持比其它“通用”模块要好得多,如果你使用的是Newlibc,Sun-libc或其他libc,就是用的"generic"模块了。libstdc++的测试套件是针对通用模块的,所以没想到这里能通过。

Unexpected failures(未料到的失败)一般也是难免的。GCC 开发者也知道,但还没修正。简单地说,如果你的结果和上面的结果差得不是很多,那就可以放心的继续安装后面的软件包了。

最后安装软件包:

make install

注: 这里强烈建议再执行一次我们前面进行过的合理性检查。参见the 节 called "锁定(Locking in)" Glibc。如果结果是错误的,你很可能是忘了运用上面的Specs补丁。