对于构建交叉编译器的兴趣完全来源于本科毕业设计。当时因为需要使用交叉编译器,而且查找资料的过程中有很多是关于如何动手构建一个交叉编译器。只不过时间不允许,所以就没有自己动手做。现在才开始,可以说是对之前的一点升华和补充吧,最大的原因是想亲自实验一下。弄了4天(截至到前天就是12日),算是搞定了,记录如下。(目前日期07年8月14日)
第一步:找到合适的参考文献
用baidu和google可以搜到很多构建编译器的资料,但是发现很多人在文章里头讲的东西除了他自己明白之外,估计外人是很难看懂。因为是新手,所以重要的是简洁和可模仿性。在这里推荐两篇文章:
这篇文章的时间很早,应该算是元老级别的,参考价值很大,缺点是现在看来版本有点低,但是绝对是很经典的。
这篇文章是刚出来2个月的不久的,最大的特点是简洁扼要,容易模仿。以至于我怀着感激之情看了作者blog里的相册,天啊,竟然是华工的校友
,从心里感概咱华工人的实在和学习的严谨。本人就是参考这篇文章来完成的。
第二步:开始投入工作
原文如下:(在原文的基础上有补充)
下载需要的文件:
Linux kernel package used: ()linux-2.6.17.tar.gz
GNU compiler sources: ()binutils-2.17.tar.gzgcc-3.4.6.tar.gzglibc-2.3.6.tar.gzglibc-linuxthreads-2.3.6.tar.gz
Patches used: ()33_all_pr15068-fix.patch5090_all_divdi3-asm-fix.patch6200_all_arm-glibc-2.3.6-ioperm.patch6230_all_arm-glibc-2.3.6-socket-no-weak-lias.patchgcc_eh.patch.cross
这里要说的是:
补丁文件中的“gcc_eh.patch.cross”在gentoo上找不到,可以到上面下,文件名是glibc-2.3.6-libgcc_eh-1.patch;
6200_all_arm-glibc-2.3.6-ioperm.patch这个补丁文件在gentoo glibc2.3.6中找到的是6200_all_arm-glibc-2.3.4-ioperm.patch,在gentoo glibc2.3.4中看到的也是6200_all_arm-glibc-2.3.4-ioperm.patch,估计是人的错误或者这个补丁是通用的,既适合2.3.4,也适合2.3.6。,事实证明是后者。
着手编译:
1. PreparationCreate project directory like this:/root/scholar | |--toolchain | |--binutils-2.17.tar.gz | |--gcc-3.4.6.tar.gz | |--glibc-2.3.6.tar.gz | |--glibc-linuxthreads-2.3.6.tar.gz | |--patches | |--33_all_pr15068-fix.patch | |--5090_all_divdi3-asm-fix.patch | |--6200_all_arm-glibc-2.3.6-ioperm.patch | |--6230_all_arm-glibc-2.3.6-socket-no-weak-lias.patch | |--gcc_eh.patch.cross | |--kernel |--linux-2.6.17.tar.gz
export PREFIX=/usr/local/arm/scholar
2. Building binutils-2.17tar -zxvf binutils-2.17.tar.gzcd binutils-2.17mkdir arm-linuxcd arm-linux../configure --target=arm-linux --prefix=$PREFIX --program-prefix=arm-linux-makemake install
PATH=$PATH:/usr/local/arm/scholar/bin(这里作者的原文中没有,该命令的目的是因为后面用到了这里生成的二进制工具,所以必须添加到PATH变量中,否则后面会出错。)
3. Bootstrap GCC (First time compiling GCC without glibc, only pure-C is supported)tar -zxvf gcc-3.4.6.tar.gzpatch -p1 -d gcc-3.4.6 < patches/33_all_pr15068-fix.patch(这样不能打成功,我使用的是绝对路径,总之是成功打上补丁就可以了。这里要补充的是,这个补丁有部分不能打上去,这得靠手动更改相关的文件才可以。)cd gcc-3.4.6vi gcc/config/arm/t-linux (TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h)mkdir arm-linuxcd arm-linux../configure --target=arm-linux --prefix=$PREFIX --program-prefix=arm-linux- --disable-threads --disable-shared --enable-languages=cmakemake install
4. Linux kernel header files (This step creates the arm-specified header files for glibc)tar -zxvf linux-2.6.17.tar.gzcd linux-2.6.17make ARCH=arm CROSS_COMPILE=arm-linux- menuconfigmake include/linux/version.hcp -dR include/linux $PREFIX/arm-linux/include/linux/cp -dR include/asm-generic $PREFIX/arm-linux/include/asm-generic/cp -dR include/asm-arm $PREFIX/arm-linux/include/asm-arm/mv $PREFIX/arm-linux/include/asm-arm $PREFIX/arm-linux/include/asm
5. glibc-2.3.6tar -zxvf glibc-2.3.6.tar.gztar -zxvf glibc-linuxthreads-2.3.6.tar.gz --directory ./glibc-2.3.6patch -p1 -d glibc-2.3.6 < patches/5090_all_divdi3-asm-fix.patchpatch -p1 -d glibc-2.3.6 < patches/6200_all_arm-glibc-2.3.6-ioperm.patchpatch -p1 -d glibc-2.3.6 < patches/6230_all_arm-glibc-2.3.6-socket-no-weak-lias.patchpatch -p1 -d glibc-2.3.6 < patches/gcc_eh.patch.crosscd glibc-2.3.6(这里作者的原文中没有,应该是疏漏)mkdir arm-linuxcd arm-linuxCC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib LD=arm-linux-ld ../configure --target=arm-linux --prefix=$PREFIX/arm-linux --host=arm-linux --enable-add-ons=linuxthreads --enable-shared --with-headers=$PREFIX/arm-linux/includemakemake install
6. gcc-3.4.6 full version (with glibc, support C/C++)cd gcc-3.4.6Change ./gcc/config/arm/t-linux back to originalcd arm-linux../configure --target=arm-linux --prefix=$PREFIX --program-prefix=arm-linux- --enable-multilib --with-headers=$PREFIX/arm-linux/include --enable-languages=c,c++makemake install
自此,整个arm-linux的工具链也就生成了.最后,可以打包发布了
!
小结:
最终得到了交叉编译工具,收获不小。每个步骤中的make命令都是要消耗一个多小时时。当然,编译过程出错的和4个cpu的机器除外
。
不明白的地方还很多,比如补丁程序如何选,在一个补丁目录下有那么多的补丁,一般不少于20个,为什么只选那几个,希望有高手不吝赐教,这年头,猪肉忒贵,送上小猪
。