预计所需编译时间: 11.0 SBU 预计所需硬盘空间: 274 MB |
测试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++ |
新配置参数的意思是:
--enable-threads=posix:使c++异常能处理多线程代码。
--enable-__cxa_atexit:使用 __cxa_atexit来代替 atexit,用来记录本地和全局的的C++ destructors,这是为了完全符合标准的规定。它还会影响到C++ ABI,因此生成的C++共享库,在其他的Linux发行版上也能使用。
--enable-clocale=gnu: 本参数确保C++库在任何情况下都使用正确的locale模块。如果配置脚本查找到de_DE这个locale,它就会使用正确的gnu模块。然而,有的人没有安装de_DE,就有可能创建出ABI不兼容的C++库文件,这是因为错误的使用了generic作为locale模块。
--enable-languages=c,c++: 本参数编译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补丁。