6.16. GCC-4.4.3

GCC 软件包包含 GNU 编译器集合,包括 C 和 C++ 编译器。

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

6.16.1. 安装 GCC

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

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

Section 5.10, “GCC-4.4.3 - 第二遍” 中一样, 为了确保一致的编译器编译, 我们使用后面的 sed 命令, 使用-fomit-frame-pointer 编译器标志进行编译:

case `uname -m` in
  i?86) sed -i 's/^T_CFLAGS =$/& -fomit-frame-pointer/' \
        gcc/Makefile.in ;;
esac

fixincludes 脚本偶尔会因为“修改”系统的头文件而出错。因为现在的头文件已知不需要修复, 运行下面的命令可以避免fixincludes 脚本运行:

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

使用 sed 替代来防止一个测试错误:

sed -i 's/getline/get_line/' libiberty/testsuite/test-demangle.c

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

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

为编译 GCC 做准备:

../gcc-4.4.3/configure --prefix=/usr \
    --libexecdir=/usr/lib --enable-shared \
    --enable-threads=posix --enable-__cxa_atexit \
    --enable-clocale=gnu --enable-languages=c,c++ \
    --disable-multilib --disable-bootstrap

注意,对于其他语言,还有一些未知的先决条件。请参考 BLFS 文档关于GCC所支持的所有语言的介绍。

编译这个软件包:

make
[Important]

重要

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

对结果进行检查,但遇到错误不停止:

make -k check

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

../gcc-4.4.3/contrib/test_summary

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

结果可以跟 http://www.linuxfromscratch.org/lfs/build-logs/6.6/http://gcc.gnu.org/ml/gcc-testresults/ 进行比较。

一些预想不到的错误总是无法避免的。 虽然GCC的开发者经常留意这些问题, 但是有些还是没有得到解决。 通常,因为GCC中的一个bug, libmudflap测试尤其被认为是有问题的 (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]

现在确保我们安装使用了正确的 startfiles 文件:

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

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

/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../crt1.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../crti.o succeeded
/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../crtn.o succeeded

由于机器的架构不同,上面的输出可能略有不同,不同点通常是 /usr/lib/gcc 后面的目录名。如果你的机器是64位的,你可能在字符串结尾看到一个名叫lib64 的目录。 这里重要的是,gcc 在 /usr/lib 目录找到所有的三个 crt*.o 文件。

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

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

这个命令应该成功返回以下输出:

#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.4.3/include
 /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include-fixed
 /usr/include

再次注意,你的机器的目录名可能和上面不同,由机器的架构决定。

[Note]

注意

现在,4.3.0版的GCC 要把 limits.h 文件安装到专用的include-fixed 目录, 并且这个目录必须到位。

接下来,确认正在使用带有正确搜索路径的新链接器:

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");

64-bit 系统可能会看到更多的目录。例如,这里是一台 x86_64 机器的输出:

SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");

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

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

如果一切正常,应该不会出错,而且最后一个命令的结果应该是 (在64位宿主系统上,是 lib64 目录):

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

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

grep found dummy.log

如果一切正常,应该不会出错,而且最后一个命令的结果应该是(允许不同平台的动态链接器的名称不同, 并且64位机器上,是lib64目录):

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

如果输出与上面不同或者没有输出,那么就有大问题了。你需要检查一下前面的操作, 看看问题出在哪里,并改正过来。 大多数情况下,出错都是因为上面的 specs 文件没改对。 在继续之前要解决所有的问题。

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

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

6.16.2. GCC 的内容

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

简要描述

c++

The C++ compiler

cc

The C compiler

cpp

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

g++

The C++ compiler

gcc

The C compiler

gccbug

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

gcov

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

libgcc

gcc运行时库

libgcov

在GCC被用来启用profiling 时,这个库会被链接到一个程序中

libgomp

C/C++ 和 Fortran多平台共享存储并行编程的OpenMP API 的GNU 实现

libmudflap

包含支持GCC范围检查函数的程序

libssp

包含支持GCC堆栈保护函数的程序

libstdc++

标准的 C++ 库

libsupc++

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