接着我们就要准备开始编译GCC(不要以为我这里漏掉了glibc-2.4的headers这部分,这样安排正是为了说明glibc-2.4的headers部分为什么要在编译GCC之前处理),我们来看一下它的编译参数
../gcc-4.1.1/configure --prefix=${CLFS}/cross-tools \
--host=${CLFS_HOST} --target=${CLFS_TARGET} --disable-multilib \
--with-sysroot=${CLFS} --disable-nls --disable-shared \
--enable-languages=c
从参数上理解就是,gcc将被安装到${CLFS}/cross-tools,而且只编译c语言部分,同时将${CLFS}所定义的目录作为根目录(--with-sysroot)
这里有必要解释一下一个比较重要的概念就是“交叉编译”,交叉编译简单的讲就是在一种体系的机器上编译出运行于另一种体系的代码(两种体系也可以是相同的,但通常是以不同的体系来说明),如下图:
网管论坛bbs_bitsCN_com
这里很重要的一个部分就是编译器和链接器,这二者在这里对应的是GCC和binutils,它们即要运行于当前体系的系统下,又要能生成和处理目标体系的文件,因此称它们为交叉编译工具链。
这里比较重要的是GCC(并不是binutils不重要,只是我们重点要说明的是GCC),那么GCC是如何进行编译的呢?
这个问题要说清楚的话可以写一本书了,这里我只是从CLFS的角度来说明这个问题。GCC要编译出其它体系的代码,除了需要要编译的程序的源代码外还需要符合该体系的头文件,这里最重要的就是内核的头文件和glibc的头文件,所以作为交叉编译用的GCC,除了在编译其它程序的时候用到头文件,其自身也必须“了解”这些头文件,它必须掌握目标体系的全部细节,这已经由Linux的内核头文件给出了,另一点需要注意的是,GCC不仅可以用来在Linux 下用,也可以用在其它支持的系统上,比如BSD,而C库也不局限于glibc,有可能是其它的C库,比如uclibc,所以要能够生成在目标体系的目标系统下运行的二进制代码,那么就必须对这一切都要了解,所以在编译GCC的时候必须有目标体系及目标系统相对应的头文件,这就解释了为什么要在编译GCC之前要先编译一个glibc-2.4的头文件部分。
下面来图解这段内容
网管联盟bitsCN_com

现在我们回过头来,编译glibc-2.4符合目标系统的头文件,这部分我感觉也是各个体系差异比较大的部分,所以我们这里参考CLFS2.0第一个完成的体系ARM来说明(我只说重点,全部内容可以参考手册说明)
tar -jxvf ../glibc-ports-2.4.tar.bz2
mv -v glibc-ports-2.4 ports
这部分实际上是为了glibc能够支持arm而安装的,标准的glibc并不支持ARM等几个体系,而glibc-ports就是为了补充这部分的支持而出现的(这里必须将其改为ports,否则编译无法找到)。
echo "libc_cv_forced_unwind=yes" > config.cache
网管有家www.bitscn.net echo "libc_cv_c_cleanup=yes" >> config.cache
echo "libc_cv_arm_tls=yes" >> config.cache
这部分实际上是强制指定一些编译时候的参数,因为目前还没有交叉编译用的GCC,所以用主系统做./configure的时候有些参数会设置一些不正确的参数,因此这里强制声明是非常必要的,到工具链中第一遍的GCC完成后就可以正确设置这些参数了,所以再编译glibc就可以不用指定这些参数。
echo "install_root=${CLFS}" > configparms
这个就是为了指定安装目录,方便以后用make install直接装到${CLFS}目录下,其实不要这句也没问题,后面的make install改为make install_root=${CLFS} install-headers就可以了。
CC=gcc ../glibc-2.4/configure --prefix=/usr \
--host=${CLFS_TARGET} --build=${CLFS_HOST} \
--with-headers=${CLFS}/usr/include --cache-file=config.cache
这个编译参数说明gcc用的是主系统的gcc,这里需要注意的是--prefix=/usr虽然指定的是/usr目录,但实际上最后安装到的是$ {install_root}/usr下,如果没有指定install_root,那自然是安装到了/usr,而因为前面指定了install_root 的目录,实际上最后安装到了${CLFS}/usr下,这里还需要注意的是--host和--build的指定(--host=$ {CLFS_TARGET} --build=${CLFS_HOST}),对比前面编译的binutils的参数(--host=${CLFS_HOST} --target=${CLFS_TARGET}),和后面GCC的参数(--host=${CLFS_HOST} --target=${CLFS_TARGET}),看到没有:
网管联盟bitsCN@com glibc-2.4 :--host=
${CLFS_TARGET} --build=${CLFS_HOST}
binutils :--host=
${CLFS_HOST} --target=${CLFS_TARGET}
gcc :--host=
${CLFS_HOST} --target=${CLFS_TARGET}
网管u家u.bitsCN.com