1. 预先编译gcc依赖库:gmp/mpfr/mpc
2. 编译binutils:
lyfan@LAPTOP-2TDO37E5:~/share$ tar Jxf binutils-2.32.tar.xz && cd binutils-2.32 && mkdir build && cd build
lyfan@LAPTOP-2TDO37E5:~/share$ ../configure --build=x86_64-linux-gnu --target=arm-linux-gnueabi --prefix=/home/lyfan/.armgcc11/gcc-4.9.4 --disable-nls --enable-shared \
--disable-multilib --with-gmp=/home/lyfan/Downloads/gcclib/gmp --with-mpfr=/home/lyfan/Downloads/gcclib/mpfr \
--with-mpc=/home/lyfan/Downloads/gcclib/mpc
lyfan@LAPTOP-2TDO37E5:~/share$ make && make install
安装后目标目录文件:
lyfan@LAPTOP-2TDO37E5:~/share$ ls
arm-linux-gnueabi bin share x86_64-linux-gnu
3. 第一次编译gcc:
lyfan@LAPTOP-2TDO37E5:~/share$ tar jxf gcc-4.9.4.tar.bz2 && cd gcc-4.9.4/ && mkdir build && cd build
gcc:
lyfan@LAPTOP-2TDO37E5:~/share$ ../configure --build=x86-linux --host=x86-linux --target=arm-linux-gnueabi --prefix=/home/lyfan/.armgcc11/gcc-4.9.4 \
--with-float=soft --with-cpu=arm920t --with-tune=arm9tdmi --with-gnu-as --with-gnu-ld --disable-nls --disable-decimal-float \
--disable-libgomp --disable-multilib --disable-libmudflap --disable-libssp --disable-shared --disable-threads --disable-libmudflap \
--disable-libstdcxx-pch --disable-libffi --enable-languages=c --without-headers \
--disable-option-checking --disable-libquadmath --disable-libquadmath-support --disable-libstdcxx \
--with-gmp=/home/lyfan/Downloads/gcclib/gmp --with-mpfr=/home/lyfan/Downloads/gcclib/mpfr --with-mpc=/home/lyfan/Downloads/gcclib/mpc
lyfan@LAPTOP-2TDO37E5:~/share$ make all-gcc
lyfan@LAPTOP-2TDO37E5:~/share$ make install-gcc
主要生成lib/libexe目录,stage1 cc1位于libexec/gcc/arm-linux-gnueabi/4.9.4/ 目录下。
lyfan@LAPTOP-2TDO37E5:~/share$ ls
arm-linux-gnueabi bin include lib libexec share x86_64-linux-gnu
lyfan@LAPTOP-2TDO37E5:~/share$ make all-target-libgcc
lyfan@LAPTOP-2TDO37E5:~/share$ make install-target-libgcc
lyfan@LAPTOP-2TDO37E5:~/share$ ls
arm-linux-gnueabi bin include lib libexec share x86_64-linux-gnu
libgcc安装到了lib/gcc/arm-linux-gnueabi/4.9.4/ 目录下。
4. 安装kernel头文件
lyfan@LAPTOP-2TDO37E5:~/share$ cd /home/lyfan/2440/linux-2.6.38.8
lyfan@LAPTOP-2TDO37E5:~/share$ make ARCH=arm headers_install INSTALL_HDR_PATH=/home/lyfan/.armgcc11/gcc-4.9.4/arm-linux-gnueabi
5. glibc:
lyfan@LAPTOP-2TDO37E5:~/share$ tar Jxf glibc-2.22.tar.xz && cd glibc-2.22/ && mkdir build && cd build
为了使Glibc支持NPTL,需要在Glibc编译目录下建立config.cache文件并写入:
lyfan@LAPTOP-2TDO37E5:~/share$ cat > config.cache << EOF
libc_cv_forced_unwind=yes
libc_cv_c_cleanup=yes
libc_cv_arm_tls=yes
libc_cv_gnu99_inline=yes
EOF
其中 libc_cv_arm_tls=yes 可以省略,因为交叉编译环境已经完全了解你要编译的目标体系,所以可以自行检测出来。
lyfan@LAPTOP-2TDO37E5:~/share$ export PATH=$PATH:/home/lyfan/.armgcc11/gcc-4.9.4/bin
BUILD_CC=gcc \
CC=arm-linux-gnueabi-gcc \
AR=arm-linux-gnueabi-ar \
RANLIB=arm-linux-gnueabi-ranlib \
../configure --build=x86-linux --host=arm-linux-gnueabi --prefix=/home/lyfan/.armgcc11/gcc-4.9.4/arm-linux-gnueabi \
--with-headers=/home/lyfan/2440/linux-2.6.38.8/usr/include \
--with-binutils=/home/lyfan/.armgcc11/gcc-4.9.4/bin \
--with-tls --with-__thread --enable-sim --enable-nptl --enable-add-ons --enable-kernel=2.6.32 --disable-profile \
--without-gd --without-cvs --cache-file=config.cache
lyfan@LAPTOP-2TDO37E5:~/share$ make && make install
glibc将会安装到目录:/home/lyfan/.armgcc11/gcc-4.9.4/arm-linux-gnueabi
6. 第二次编译gcc:
lyfan@LAPTOP-2TDO37E5:~/share$ ../configure --build=x86-linux --host=x86-linux --target=arm-linux-gnueabi --prefix=/home/lyfan/.armgcc11/gcc-4.9.4 \
--with-float=soft --with-cpu=arm920t --with-tune=arm9tdmi --with-gnu-as --with-gnu-ld --enable-nls --enable-languages=c,c++ \
--enable-threads=posix --enable-c99 --enable-long-long --enable-shared --enable-__cxa_atexit \
--with-gmp=/home/lyfan/Downloads/gcclib/gmp --with-mpfr=/home/lyfan/Downloads/gcclib/mpfr --with-mpc=/home/lyfan/Downloads/gcclib/mpc
lyfan@LAPTOP-2TDO37E5:~/share$ make && make install
第一遍只编译一个支持c的gcc,原因是要编译出一个支持交叉的c++,必须有一个编译好的用于目标体系平台的glibc,而不是只有glibc的头文件就可以的,好在编译glibc有c支持就够了,所以编译glibc也成了第一遍的gcc唯一的理由和作用。工具链中gcc的第一次和第二次编译都是由主系统的gcc和binutils来完成的(之前没有提及binutils,只是为了理解方便,但实际上编译后是少不了链接过程的,这个过程是要binutils来完成的)。到目前为止只有在编译glibc的时候用到了交叉版本的binutils,其它部分的链接都是由主系统的binutils来完成的。
>>>>>>>>>>>>>>>> tips:
本人编译完成后测试gcc时发现编译含有NAME_MAX宏的.c代码会报错,后经定位发现头文件limits.h定义有NAME_MAX,gcc内置include目录lib/gcc/arm-linux-gnueabi/4.9.4/include-fixed以及glibc include目录下均有limits.h,依赖于# include_next <limits.h>搜索头文件的次序,使用`arm-linux-gnueabi-gcc --print-prog-name=cc1` -v可以查看当前gcc内置的头文件搜索顺序,或者编译是附加-v信息亦可 > echo 'main(){}'| arm-linux-gnueabi-gcc -E -v -
lyfan@DESKTOP-HUGAJRT:~/.bin$ `arm-linux-gnueabi-gcc --print-prog-name=cc1` -v
ignoring nonexistent directory "/home/lyfan/.bin/armgcc4.9.4/lib/gcc/arm-linux-gnueabi/4.9.4/../../../../arm-linux-gnueabi/sys-include"
#include "..." search starts here:
#include <...> search starts here:
/home/lyfan/.bin/armgcc4.9.4/lib/gcc/arm-linux-gnueabi/4.9.4/include
/home/lyfan/.bin/armgcc4.9.4/lib/gcc/arm-linux-gnueabi/4.9.4/include-fixed
/home/lyfan/.bin/armgcc4.9.4/arm-linux-gnueabi/include
End of search list.
发现gcc优先搜索的是gcc内置的include目录,对比其他版本gcc,一般都是glibc include目录优先于gcc内置include-fixed目录进行查找,猜测是编译过程中哪个配置问题或者是当前gcc版本问题导致的,一个解决方法是配置gcc预定义的环境变量C_INCLUDE_PATH,优先级别高于内置的头文件搜索次序:
export C_INCLUDE_PATH=/home/lyfan/.bin/armgcc4.9.4/arm-linux-gnueabi/include
另一种方案是修改gcc处理 incpath的规则,找到gcc源码${gcc_root}/gcc/cppdefault.c文件,调整或修改定义有cpp内置头文件搜索顺序的全局结构体struct default_include cpp_include_defaults[],按照自己需求修改重新编译即可。