[注意:本文中,“编译gcc”指cross-compile出来一个新的gcc,“gcc编译”或“gcc工作”指"使用gcc编译main.c出来a.out"]
1. gcc需要的一些lib
GMP:A free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating-point numbers.
MPFR:Multiple Precision Floating-Point Reliable Library.
MPC:A C library for the arithmetic of complex numbers with arbitrarily high precision and correct rounding of the result.
2.GMP/MPFR/MPC的源代码目录都放到gcc目录下作为其子目录存在,去除目录版本号
3. lfs文档说需要用它给你的script修改下gcc源代码,其目的是让该gcc工作时使用我们后面编译出来的/tools/lib目录下的dynamic loader(ld-linux.so),而不是标准目录/lib下的。
4. 建立一个不带版本号的gcc链接到gcc-ver.ver.ver,方便执行修改gcc源代码的那个script
5. 在gcc源代码目录下执行下上面说的script。
注意:若执行成功会有一系列文件改名提示出来。
粗看起来script在sources/gcc/config目录下找东西,但实际上gcc源代码目录下有一个gcc/config目录(sources/gcc-v.v.v/gcc/config),所以step4是不需要的。
6. ../configure
--target=$LFS_TGT
--prefix=/tools
--with-glibc-version=2.11
--with-sysroot=$LFS
--with-newlib --without-headers
--with-local-prefix=/tools
--with-native-system-header-dir=/tools/include
--disable-nls
--disable-shared
--disable-multilib
--disable-decimal-float
--disable-threads
--disable-libatomic
--disable-libgomp
--disable-libquadmath
--disable-libssp
--disable-libvtv
--disable-libstdcxx
--enable-languages=c,c++
# 编译出来的gcc在工作时也需要一些自己的lib,比如libgcc.a,libcc1.so
# 她有时会到libgcc.a这样的静态库里提取他需要的公共代码放到a.out中(?)
# 另外一些给自己用的东西在动态库比如libcc1.so里,编译的时候用,编译出的a.out是用不着libcc1.so的。
# 因为我们还没有编译libc,所以使用--without-headers告诉build system不要去找libc下的headers,而是使用gcc源码自带的headers。
# 但是--without-headers会让gcc无法找到一些必要的函数声明比如malloc,
# 所以我们需要--with-newlib,这个选项会定义inhibit_libc,该宏定义有效时,gcc会自己声明必要的函数。see tsystem.h。。
# 这里并不表示我们要用newlib,只是借用这个选项定义inhibit_libc。
# 但这仅仅是让gcc使用自己的函数声明,但不代表gcc有这些函数实现,所以编译出来的gcc仍然是依赖于libc的,可以用ldd检查。
# 另外,--with-newlib还会禁用一些gcc可选功能,但这对我们不重要了。
# 对--with-newlib这个选项原意的理解,未必正确:
# - build机上可能有glibc,但host机上是newlib。
# - 至于target上是什么,这个是由gcc编译选项指定的,和编译gcc没关系。
# 这样编译出来的gcc可以编译kernel,glibc等能够“自成体系”的东西。
# 顺便说下,有一个叫做crosstool ng的项目,可用来制作交叉编译器,
7. 如果你遇到了下列错误,可能是因为没有安装g++:
checking for int64_t underlying type... long long
configure: error: error verifying int64_t uses long long
8. 不要用j参数做make,否则会报error,原因可能是需要先编译前述三个依赖库(也可能不报错,看运气?)。
9. make install