交叉工具链制作至尊宝典


一些必须知道的基础知识

  • Debian 操作系统 以及 aptitude 命令
  • autoconf and automake
  • 什么是交叉编译,configure 的几个参数 build host target

    build:
    编译代码的机器,的CPU指令集

    host:
    编译生成的东西,的CPU指令集(目标板上的CPU的指令集)

    target:
    编译生成的东西,他编译生成的的东西,的指令集(所以此选项一般不用,大多只有在做交叉工具链时使用)

    0、以Expert mode 安装Debian

    不要升级,确保环境是一个纯净的环境

    1、声明环境变量 

     
    1. export IS_TARGET=arm-linux  
    2. export DIR_SRC=/root/cross_toolchains/src  
    3. export PREFIX=/opt/cross_toolchains/arm  
    4. export CONFIGURE_BASE="../configure --prefix=$PREFIX --with-sysroot=$PREFIX"  

    2、下载制作交叉工具链所必须的的代码

     
    1. binutils  
    2. ftp://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.gz  
     
    1. gcc  
    2. ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.2.tar.gz  
    3. ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.0.1.tar.gz  
    4. http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz  
    5. ftp://ftp.gnu.org/gnu/gcc/gcc-4.6.1/gcc-4.6.1.tar.gz  
     
    1. glibc  
    2. ftp://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz  
    3. ftp://ftp.gnu.org/gnu/glibc/glibc-ports-2.13.tar.gz  
     
    1. linux kernel  
    2. http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.2.tar.bz2  

    3、安装(卸载)必要的的软件包

     
    1. aptitude install build-essential automake bison flex texinfo gawk g\+\+  
    2. aptitude remove mawk  

    4、解压、归档软件包

     
    1. cd $DIR_SRC  
    2. tar -xf binutils-2.21.tar.gz  
    3. tar -xf gmp-5.0.2.tar.gz  
    4. tar -xf mpc-0.9.tar.gz  
    5. tar -xf mpfr-3.0.1.tar.gz  
    6. tar -xf gcc-4.6.1.tar.bz2  
    7. tar -xf glibc-2.14.tar.gz  
    8. tar -xf glibc-ports-2.13.tar.gz  
    9. tar -xf linux-2.6.39.2.tar.bz2  
     
    1. mv gmp-5.0.2 gcc-4.6.1/gmp  
    2. mv mpc-0.9 gcc-4.6.1/mpc  
    3. mv mpfr-3.0.1 gcc-4.6.1/mpfr  
    4. mv glibc-ports-2.13 glibc-2.14/ports  

    5、编译 BINUTILS

     
    1. cd $DIR_SRC  
    2. cd binutils-2.21  
    3. mkdir build  
    4. cd build  
    5. $CONFIGURE_BASE --target=$IS_TARGET --disable-nls --enable-shared --disable-multilib  
     
    1. make configure-host  
    2. make  
    3. make install  
     
    1. export PATH=$PATH:$PREFIX/bin  

    问题:
    编译binutils一般不会遇到什么问题,但是,如果前面步骤3中安装的软件不全会出现问题

    6、建立用于编译C库的GCC

     
    1. cd $DIR_SRC  
    2. cd gcc-4.6.1  
    3. mkdir build   
    4. cd build  
    5. $CONFIGURE_BASE \  
    6. --target=$IS_TARGET \  
    7. --disable-nls \  
    8. --disable-shared \  
    9. --without-headers \  
    10. --with-newlib \  
    11. --enable-languages=c \  
    12. --disable-threads \  
    13. --disable-multilib \  
    14. --disable-decimal-float \  
    15. --disable-libgomp \  
    16. --disable-libmudflap \  
    17. --disable-libssp  
     
    1. make all-gcc all-target-libgcc  
    2. make install-gcc install-target-libgcc  
     
    1. 值得注意的几个configure选项  
    2. --target  
    3. --disable-shared  
    4. --without-headers  
    5. --with-newlib  
    6. --enable-language-c  
    7. --disable-thread  
     
    1. cd $PREFIX/lib/gcc/$IS_TARGET/4.6.1  
    2. ln -s libgcc.a libgcc_eh.a  
     
    1. 有建议修改 gcc/config/t-linux 这个文件  
    2. 增加 -D__gthr_posix_h -Dinhibit_libc 两个宏,但我这里没这样做,是因为:  
    3. 在configure后,编译使用的命令并不是 make 或者是 make all 而是 make all-gcc 和 make all-target-libgcc,所以很多问题不会出现  
    4. -with-newlib,这个选项不会迫使我们必须使用newlib  
     
    1. libgcc.mvars: No such file or directory  
    2. 不能在 GCC 的源代码目录进行configure,必须在另外的目录进行configure make 等工作  
    3. 所以这里在代码所在目录下 mkdir build 并 cd build 再进行 ../configure 等工作  
     
    1. configure: error: C compiler cannot create executables  
    2. 如果使用 make 或 make all 会出现这样的问题,因为我们还未编译出目标指令集的 C 库  
    3. 所以只能先使用 make all-gcc make all-target-libgcc  
     
    1. ../../../../arm-linux/bin/ld: cannot find -lgcc  
    2. ../../../../arm-linux/bin/ld: cannot find -lgcc_eh  
    3. 很多资料都只写了 make all-gcc 而没有写 make all-target-libgcc 这样只建立了gcc,没有建立libgcc.a会出现以上第一个错误  
    4. 如果没手工建立链接文件 libgcc_eh.a 则会出现第二个错误  

    7、配置内核生成必要的头文件

     
    1. cd $DIR_SRC  
    2. cd linux-2.6.39.2  
    3. make ARCH=arm CROSS_COMPILE=$IS_TARGET- menuconfig  
    4. make ARCH=arm CROSS_COMPILE=$IS_TARGET-  
     
    1. mkdir -p $PREFIX/include  
    2. cd $PREFIX/include  
    3. ln -s $DIR_SRC/linux-2.6.39.2/arch/arm/include/asm asm  
    4. ln -s $DIR_SRC/linux-2.6.39.2/include/linux linux  
    5. ln -s $DIR_SRC/linux-2.6.39.2/include/asm-generic asm-generic  
     
    1. 这里并没有将内核的头文件复制到交叉工具链的安装目录  
    2. 编译C库的时候,需要对应的CPU指令集的汇编代码所以做了链接处理  
     
    1. 编译内核在执行 make ARCH=arm CROSS_COMPILE=$IS_TARGET- 时如果出错,是没有关系的,这里只要生成了对应的 version.h autoconf.h就可以了  

    8、编译C库

     
    1. cd $DIR_SRC  
    2. cd glibc-2.9  
    3. mkdir build  
    4. cd build  
     
    1. vi ../configure  
    2. vi ../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S  
    3. vi ../sysdeps/unix/syscall-template.S   
    4. vi ../nptl/allocatestack.c   
    5. vi ../elf/dl-tls.c  
    6. vi ../sysdeps/ieee754/dbl-64/s_fma.c  
    7. vi ../sysdeps/ieee754/dbl-64/s_fmaf.c  
    8.   
    9. 具体的修改,我写在下面(觉得还是要说清楚为什么修改,所以就没用sed命令或是做一些patch文件了,请向下看)  
     
    1. CC=$IS_TARGET-gcc \  
    2. $CONFIGURE_BASE \  
    3. --host=$IS_TARGET \  
    4. -enable-add-ons \  
    5. --with-binutils=$PREFIX/bin \  
    6. --with-headers=$PREFIX/include \  
    7. libc_cv_forced_unwind=yes \  
    8. libc_cv_c_cleanup=yes  
     
    1. 值得注意的几个configure选项  
    2. --host  
    3. --with-headers  
    4. lib_cv_forced_unwind  
    5. lib_cv_c_cleanup  
     
    1. make  
    2. make install   
     
    1. 这里编译的时候并有选择TARGET为EABI,所以在制作交叉工具链时会有很多问题需要修改  
     
    1. *** These critical programs are missing or too old: as ld  
    2. *** Check the INSTALL file for required versions.  
    3. vi ../configure   
    4. 查找  "$AS --version" 将 2.1[3-9] 修改为 2.[1-2][0-9]  
    5. 查询  "$LD --version" 将 2.1[3-9] 修改为 2.[1-2][0-9]  
     
    1. Error: previous CFI entry not closed (missing .cfi_endproc)  
    2. vi ../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S  
    3. ENTRY(__default_sa_restorer) 下增加  
    4. END(__default_sa_restorer)  
    5. ENTRY(__default_rt_sa_restorer) 下增加  
    6. END(__default_rt_sa_restorer)  
     
    1. syscall-template.S:82: Error: CFI instruction used without previous .cfi_startproc  
    2. vi ../sysdeps/unix/syscall-template.S   
    3. 这个问题的修改我也不是十分确定,我是这样来思考的  
    4. 看到 syscall-template.S 中 有 #include <sysdep.h>  
    5. 去查看 ports/sysdeps/unix/sysv/linux/arm/sysdep.h  
    6. 看到如下代码  
    7. #ifdef __ASSEMBLER__  
    8. #undef  PSEUDO  
    9.   
    10. #define PSEUDO(name, syscall_name, args)                                      \  
    11.   .text;                                                                      \  
    12.   ENTRY (name);                                                               \  
    13.     DO_CALL (syscall_name, args);                                             \  
    14.     cmn r0, $4096;  
    15.   
    16. 猜测是__ASSEMBLER__宏未打开,以至于未能找到PSEUD0函数的声明,则将  
    17.   
    18. #define PSEUDO(name, syscall_name, args)                                      \  
    19.   .text;                                                                      \  
    20.   ENTRY (name);                                                               \  
    21.     DO_CALL (syscall_name, args);                                             \  
    22.     cmn r0, $4096;  
    23.   
    24. 这段代码 添加至 ../sysdeps/unix/syscall-template.S 中  
     
    1. LS_DTV_UNALLOCATED  undeclared (first use in this function)  
    2. vi ../nptl/allocatestack.c  
    3. vi ../elf/dl-tls.c   
    4. 这个错误会出现在编译以上两个文件的时候,这个宏的定义我grep了整个glibc的所有代码,没找到ARM相关的声明及定义,按照其他指令集的定义猜测着修改如下  
    5. 在以上两个C文件中增加相应的定义  
    6.   
    7. #define TLS_DTV_UNALLOCATED      ((void *) -1l)  
     
    1. E_TOWARDZERO undeclared (first use in this function)  
    2. E_INEXACT undeclared (first use in this function)  
    3. 以上两个错误会出现在以下两个文件的的编译过程中  
    4. vi ../sysdeps/ieee754/dbl-64/s_fma.c  
    5. vi ../sysdeps/ieee754/dbl-64/s_fmaf.c  
    6. 参考 ports/sysdeps/arm/eabi/bits/fenv.h中的定义  
    7. 在两个文件中添加  
    8. #define FE_TOWARDZERO 0xc00000  
    9. #define FE_INEXACT 16  
     
    1. mawk: scripts/gen-sorted.awk: line 19: regular expression compile failed   
    2. 所以要 aptitude install gawk 所以也顺带着 aptitude remove mawk  
     
    1. configure: error: forced unwind support is required   
    2. configure 中增加配置参数 libc_cv_forced_unwind=yes   
     
    1. error: the compiler must support C cleanup handlin  
    2. configure 中增加配置参数libc_cv_c_cleanup=yes   
     
    1. --enable-add-ons 为 C 库 增加 thread 支持,目前默认使用的是 nptl 所以这里没有去下载 glibc-threads 相关的代码  
     
    1. --with-headers 指定内核头文件所在的目录  
    • 1
    • 2
    • 下一页

    相关内容