6.14. GCC-4.3.2

GCC 软件包包含 GNU 编译器,其中有 C 和 C++ 编译器。

预计编译时间: 25 SBU 包括测试组件
所需磁盘空间: 1.1 GB 包括测试组件

6.14.1. 安装 GCC

使用一个 sed 命令来禁止 GCC 安装它自己的 libiberty.a 。我们将使用 Binutils 附带的 libiberty.a 来代替:



sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in


第 5.5 节 “GCC-4.3.2 - 第一遍” 里面应用的 bootstrap 编译中,编译器会有 -fomit-frame-pointer 的标志。非 bootstrap 编译默认是忽略这个标志的,可以应用下面的 sed 命令来确保编译的可靠性:



sed -i 's/^XCFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in


fixincludes 脚本偶尔会因为修改系统的头文件而出错。因为 GCC-4.3.2 和 Glibc-2.8-20080929 是不需要修改的,运行下面的命令可以避免 fixincludes 脚本运行:



sed -i 's@\./fixinc\.sh@-c true@' gcc/Makefile.in


GCC 的安装指南推荐用一个新建的目录来编译它,而不是在源码目录中:



mkdir -v ../gcc-build


cd ../gcc-build


为编译 GCC 做准备:



../gcc-4.3.2/configure --prefix=/usr \


    --libexecdir=/usr/lib --enable-shared \


    --enable-threads=posix --enable-__cxa_atexit \


    --enable-clocale=gnu --enable-languages=c,c++ \


    --disable-bootstrap


给其他语言的建议,这里有一些必要条件并不可用。看 BLFS 说明手册上关于如何编译所有 GCC 支持的语言

编译软件包:



make


[重要]

重要

本节的 GCC 测试套件很重要。在任何情况下都不要省略这一步。

运行测试套件,但遇到错误不停止:



make -k check


要查看测试单元的测试结果,可以运行:



../gcc-4.3.2/contrib/test_summary


如果只想看概要,可以把输出通过管道传递给 grep -A7 Summ

结果可以跟 http://www.linuxfromscratch.org/lfs/build-logs/6.4/ 的内容进行比较。

一些预想不到的错误总是无法避免的。虽然GCC的开发者经常留意这些问题,但是有些还是没有得到解决。通常,libmudflap 测试尤其被认为是有问题的,这是一个 bug (参见 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20003)。除非测试结果给上面 URL 的有很多不同,一般是可以安全继续的。

安装软件包:



make install


有的软件包希望 C PreProcessor (预处理器)安装在 /lib 目录下,为了满足它们的要求,我们创建如下符号链接:



ln -sv ../usr/bin/cpp /lib


许多软件包使用 cc 作为 C 编译器的名字,为了满足它们的要求,创建如下符号链接:



ln -sv gcc /usr/bin/cc


现在,我们的最终工具链已经形成了,我们需要做的就是确保编译、链接按照我们希望的完成。我们可以通过本章前面的简册方法来实现:



echo 'main(){}' > dummy.c


cc dummy.c -v -Wl,--verbose &> dummy.log


readelf -l a.out | grep ': /lib'


如果一切正常,应该不会出错,而且最后一个命令的结果应该是(某些特殊平台上动态连接器的名称可能与此处不同):



[Requesting program interpreter: /lib/ld-linux.so.2]


现在确保我们设置使用正确的开始文件:



grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log


如果一切正常,应该不会出错,而且最后一个命令的结果应该是:



/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../crt1.o succeeded


/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../crti.o succeeded


/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../crtn.o succeeded


验证编译器可以搜索正确的头文件:



grep -B4 '^ /usr/include' dummy.log


如果一切正常返回的结果应该是:



#include <...> search starts here:


 /usr/local/include


 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include


 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include-fixed


 /usr/include


[注意]

注意

As of version 4.3.0, GCC now unconditionally installs the limits.h file into the private include-fixed directory, and that directory is required to be in place.

接下来要做的是验证新的链接器是否在正确的搜索路径内:



grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'


如果一切正常,应该不会出错,而且最后一个命令的结果应该是:



SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")


SEARCH_DIR("/usr/local/lib")


SEARCH_DIR("/lib")


SEARCH_DIR("/usr/lib");


下面,确保我们是否正在使用正确的 libc:



grep "/lib/libc.so.6 " dummy.log


如果一切正常,应该不会出错,而且最后一个命令的结果应该是:



attempt to open /lib/libc.so.6 succeeded


最后,确保 GCC 正在使用正确的动态链接器:



grep found dummy.log


如果一切正常,应该不会出错,而且最后一个命令的结果应该是(某些特殊平台上动态连接器的名称可能与此处不同):



found ld-linux.so.2 at /lib/ld-linux.so.2


如果输出与上面不同或者没有输出,那么就有大问题了。你需要检查一下前面的操作,看看问题出在哪里,并改正过来。在改正之前,不要继续后面的部份,因为没什么意义。大多数情况下,出错都是因为上面的 specs 文件没改对。当然,如果你的平台上动态连接器的名字不是 ld-linux.so.2,上面的结果也会不同。在继续之前要解决所有的问题。

在确定一切正常后,删除测试文件:



rm -v dummy.c a.out dummy.log


6.14.2. GCC 的内容

安装的程序: c++, cc (link to gcc), cpp, g++, gcc, gccbug, and gcov
安装的库: libgcc.a, libgcc_eh.a, libgcc_s.so, libmudflap.{a,so}, libssp.{a,so}, libstdc++.{a,so}, and libsupc++.a

简要描述

c++

C++ 编译器

cc

C 编译器

cpp

C 预处理器。编译器用它来将 #include 和 #define 这类声明在源文件中展开。

g++

C++ 编译器

gcc

C 编译器

gccbug

一个 shell 脚本,帮助创建有价值的 bug 报告。

gcov

覆盖测试工具,用来分析在程序的哪里做优化的效果最好。

libgcc

gcc 的运行时库

libmudflap

包含支持 GCC 指针检查的常规函数功能

libssp

包含支持 GCC 堆栈溢出保护的常规函数功能

libstdc++

准 C++ 库,包含许多常用的函数。

libsupc++

为 C++ 语言提供支持的库函数。


Host by Unixetc