手工制作交叉编译工具
在制作工具开始前先要选好所需要的Binutils、Gcc、glibc等组件的相匹配的版本。当然,它们的版本匹配选择较为复杂,这些组件的维护与发行完全是各自独立的,不同的组件组合在一起时,并不能保证其正常工作,版本之间可能存在冲突或BUG。一般可以参考别人的经验,成功使用某种版本的组合制作出了交叉编译工具,那么这样的组合应该是可以使用的。如果使用的包的组合是没人用过的,那么只能通过不断调试修改进行制作。一开始请使用每个套件最新出来的稳定版本,如果无法建立的话,再一次换成旧的版本(引自[1])。
在制作选择各种组件的版本时参考了Aaron Wong的《Building arm-linux toolchain for ARM/XSCALE 》[2]这篇文章(在尝试了gcc-3.3.2失败之后选用的)除了这些组件,还需要linux的内核,内核的版本与以上这些组件的关系不大,主要是在编译GLIBC时,需要内核头文件的支持,选用内核最好与目标机的系统的内核相一致,以免在目标机运行程序的时候产生冲突。
2.1 制作步骤:
准备工作:下载好所需要的软件包、准备好内核头文件、组织好目录。
编译binutils。这个软件包的编译相对简单,一般不会出现什么问题。
编译辅助gcc编译器。对gcc进行简单配置后,编译gcc,使其不依赖glibc,只对c语言支持,为后面的glibc的编译做准备。
编译glibc库。在这一步,首先将解压的内核头文件进行配置。在上一步的编译过程中,已经生成了arm-linux-gcc这个工具,利用这个工具去编译glibc库。
编译完整的gcc(相对于第二步来说)。完整gcc的编译需要glibc库的支持,在第一步的时候glibc还没有被编译,所以只能简单配置,生成辅助的gcc,而在这一步,glibc库已经编译了,可以使用了,所以,就可以对gcc进行完整的编译了。
编译gdb调试器。调试器与前面的那些软件包是相互独立的,所以放在最后编译。
2.2 工具的制作:
所以选择了配套的软件包是:Binutils-2.16、gcc-3.4.6、 glibc-2.3.6 、glibc-threads-2.3.6 、linux-2.6.11以及一些补丁。打补丁是为了解决编译过程中可能出现的错误。
第一步:
目录组织:在linux下创建一个用户,然后在这个用户下创建一个目录crosstool,在这个目录下一次创建src、kernel、toolchain、patch四个目录。将内核的压缩包放在kernel目录下,将Binutils-2.16、 gcc-3.4.6、 glibc-2.3.6 、glibc-threads-2.3.6放在src目录下下,将下载的相应的补丁放在相应的目录下。
第二步:
编译binutils。现将binutils-2.16.tar.bz2拷到src目录下,运行命令:
jyh@jyh-laptop:~$ cd crosstool/src
jyh@jyh-laptop:~/crosstool/src$tar –jxf binutils-2.16.tar.bz2
jyh@jyh-laptop:~/crosstool/src$mkdir build-binutils
jyh@jyh-laptop:~/crosstool/src$cd build-binutils
jyh@jyh-laptop:~/crosstool/src/build-binutils$../binutils-2.16/configure/
> --prefix=/home/jyh/crosstool/toolchain
jyh@jyh-laptop:~/crosstool/src/build-binutils$make
jyh@jyh-laptop:~/crosstool/src/build-binutils$make install
这一步是对binutils进行编译,这一步相对简单,不会出现什么错误,要注意的是安装的路径。执行完以上的步骤在crosstool下的toolchain下的bin找到可执行文件
jyh@jyh-laptop:~/crosstool/toolchain/bin$ ls
arm-linux-addr2line arm-linux-as arm-linux-ld arm-linux-objcopy arm-linux-ranlib arm-linux-size arm-linux-strip arm-linux-ar arm-linux-c++filt
arm-linux-nm arm-linux-objdump arm-linux-readelf arm-linux-strings
在完成了编译binutils之后进行gcc的第一次编译。但是需要注意的是把生成的这些文件的路径加入进去,在终端执行:export PATH=home/jyh/crosstool/toolchain/bin:${PATH},如若不然,在编译gcc的时候,会出现找不到arm-linux-ar命令的错误。
第三步:
编译gcc:
gcc的编译是需要glibc的支持的,而glibc又需要gcc进行编译,这仿佛是鸡与蛋的关系。解决的方法是先对gcc进行简单的配置然后编译,生成一个只支持c的没有库支持的简单arm-linux-gcc,然后用这个生成的arm-linux-gcc去编译glibc,最后再进行gcc的完全编译。这一步不能只是简单的进行配置、编译,因为没有库的支持,所以,在编译之前得告诉gcc,没有库的支持,这里就需要改变一些文件的内容来达到这个目的。
现将gcc-3.4.6.tar.bz2这个包解压
jyh@jyh-laptop:~/crosstool/src$tar –jxf gcc-3.4.6.tar.bz2
创建一个编译的目录
jyh@jyh-laptop:~/crosstool/src$mkdir build-gcc
然后在gcc-3.4.6这个目录下,找到gcc这个目录,然后一次的目录是/config/arm
在这个目录下找到t-linux文件,打开这个文件并编辑
jyh@jyh-laptop:~/crosstool/src$cd gcc-3.4.6/gcc/config/arm
jyh@jyh-laptop:~/crosstool/src/gcc-3.4.6/gcc/config/arm$gedit t-linux
使用gedit打开这个配置文件
文件的原文如下:
# Just for these, we omit the frame pointer since it makes such a big
# difference. It is then pointless adding debugging.
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
LIBGCC2_DEBUG_CFLAGS = -g0
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
# MULTILIB_OPTIONS = mhard-float/msoft-float
# MULTILIB_DIRNAMES = hard-float soft-float
# If you want to build both APCS variants as multilib options this is how
# to do it.
# MULTILIB_OPTIONS += mapcs-32/mapcs-26
# MULTILIB_DIRNAMES += apcs-32 apcs-26
# EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
# LIBGCC = stmp-multilib
# INSTALL_LIBGCC = install-multilib
我们要做的只是修改两行
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -D__gthr_posix_h -fomit-frame-pointer –fPIC(修改)
T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h(添加)(引自[3])
-Dinhibit_libc -D__gthr_posix_h的意思是禁止使用libc,现在还没用glibc,这样在编译的时候就可以不需要glibc而直接进行编译了。改完这个文件之后,还是不够的。改完这个文件之后,gcc