说明:此文档为顶嵌李亚峰老师所做,仅通过Crosstool工具进行构建。本人在对照文档进行构建是出现了一点小问题,因此将解决方法嵌入其中,供大家参考。如遇到问题欢迎提出。在此感谢李亚峰老师。 第一阶段:工具链编译第一部分;
Crosstool是由美国人Dan Kegel(毕业于加(利福尼亚)州工学院)开发的一套可以自动编译不同匹配版本gcc和glibc,并作测试的脚本程序。Crosstool最初是为嵌入式系统开发者创建,但也适用于主流开发者比如只是希望他们去快速编译或需要建立程序,可运行在旧版本的Linux操作系统(例如Red Hat的6.2 )。Crosstool是一种便携式的shell脚本。你可以使用它来建立Linux系统配置的编译器是运行在Linux , Mac OS X操作系统, Solaris和Cygwin等。它支持的硬件平台有:alpha, arm, i686, ia, mips, powerpc, powerpc, sh4, sparc, sparc, s390, x86_等。
在实践之前,我们需要回答这样的问题,为什么要使用交叉编译器?主要原因是嵌入式硬件(目标机)的性能一般都无法满足开发环境的要求,比如主频比较低、内存少、没有硬盘(常用FLASH作为存储设备)、没有大型显示设备、没有全键盘等。交叉编器通常是采用PC(x86)作为主机来搭建开发环境进行编译,但编译出的软件能够在特定CPU体系架构的目标设备(比如ARM设备)上运行的一套编译工具。
下面将以具体操作步骤来讲述Crosstool构建针对ARM平台的交叉编译器。注:该实验是基于Fedora 10操作系统下进行,其他Linux发行版可能会有所不同。 1.准备资源文件 软件包名称 下载站点
crosstool-0.43.tar.gz http://kegel.com/crosstool/crosstool-0.43.tar.gz binutils-2.15.tar.bz2 http://ftp.gnu.org/gnu/binutils/ gcc-3.4.5.tar.bz2 http://ftp.gnu.org/gnu/gcc glibc-2.3.6.tar.bz2 http://ftp.gnu.org/gnu/glibc
glibc-linuxthreads-2.3.6.tar.bz2 http://ftp.gnu.org/gnu/glibc
linux-2.6.28.2.tar.bz2 http://ftp.kernel.org/pub/linux/kernel/v2.6/
linux-libc-headers-2.6.12.0.tar.bz2 http://ep09.pld-linux.org/~mmazur/linux-libc-headers/ 首先从网上下载上述资源文件:binutils-2.15.tar.bz2,gcc-3.4.5.tar.bz2,glibc-2.3.6.tar.bz2 ,glibc-linuxthreads-2.3.6.tar.bz2,linux-2.6.28.2.tar.bz2和linux-libc-headers-2.6.12.0.tar.bz2。然后将这些工具包文件放在开放主机的/home/mike/
downloads目录(该目录根据个人使用习惯不同可修改)下,最后在/home/mike目录下解压crosstool-0.43.tar.gz,命令如下: # cd /home/mike
# tar -xvzf crosstool-0.43.tar.gz 2建立脚本文件
接着需要建立自己的编译脚本,起名为arm.sh,为了简化编写arm.sh,寻找一个最接近的脚本文件demo-arm.sh作为模版,然后将该脚本的内容复制到arm.sh,修改arm.sh脚本,具体操作如下: # cd crosstool-0.43
# cp demo-arm.sh arm.sh # vi arm.sh
修改后的arm.sh的脚本内容如下: #!/bin/sh set -ex
TARBALLS_DIR=/home/mike/downloads # 定义工具链源码所存放位置。 RESULT_TOP=/opt/crosstool # 定义工具链的安装目录 export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES=\"c,c++\" # 定义支持C, C++语言 export GCC_LANGUAGES # 创建/opt/crosstool目录
mkdir -p $RESULT_TOP
# 编译工具链,该过程需要数小时完成。
eval `cat arm.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest echo Done.
第一阶段:工具链编译第二部分;
#!/bin/sh set -ex
TARBALLS_DIR=/home/mike/downloads # 定义工具链源码所存放位置。
RESULT_TOP=/opt/crosstool # 定义工具链的安装目录 export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES=\"c,c++\" # 定义支持C, C++语言 export GCC_LANGUAGES # 创建/opt/crosstool目录 mkdir -p $RESULT_TOP
# 编译工具链,该过程需要数小时完成。的
eval `cat arm.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest echo Done. 3 建立配置文件
在arm.sh脚本文件中需要注意arm.dat和gcc-3.4.5-glibc-2.3.6.dat两个文件,这两个文件是作为crosstool的编译的配置文件。其中arm.dat文件内容如下,主要用于定义配置文件,定译生成编译工具链的名称以及定义编译选项等。
KERNELCONFIG=`pwd`/arm.config # 内核的配置 TARGET=arm-linux # 编译生成的工具链名称 TARGET_CFLAGS=\"-O\" # 编译选项
gcc-3.4.5-glibc-2.3.6.dat文件内容如下,该文件主要定义编译过程中所需要的库以及它定义的版本,如果当在编译过程中发现有些库不存在时,crosstool会自动在相关网站上下载,该工具在这点上相对非常智能,也非常有用。
BINUTILS_DIR=binutils-2.15 GCC_DIR=gcc-3.4.5 GLIBC_DIR=glibc-2.3.6
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.6 LINUX_DIR=linux-2.6.28.2。、
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0 4 执行脚本
将Crosstool的脚本文件和配置文件准备好之后,开始执行arm.sh脚本来编译交叉变异工具。具体执行命令如下:
# cd crosstool-0.43 # ./arm.sh
经过数小时的漫长编译之后,会在/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/bin目录下生成新的交叉编译工具,其中包括以下内容:
arm-linux-addr2line arm-linux-g++ arm-linux-ld arm-linux-size arm-linux-ar arm-linux-gcc arm-linux-nm arm-linux-strings arm-linux-as arm-linux-gcc-3.4.5 arm-linux-objcopy arm-linux-strip arm-linux-c++ arm-linux-gccbug arm-linux-objdump fix-embedded-paths
arm-linux-c++filt arm-linux-gcov arm-linux-ranlib
arm-linux-cpp arm-linux-gprof arm-linux-readelf 5 添加环境变量
然后将生成的编译工具链路径添加到环境变量PATH上去,添加的方法是在系统~/ .bash_profile文件中添加下面一行在文件的最后,如图所示。 export PATH=/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/bin:$PATH 第一阶段:工具链编译第二部分
图 用Vi编辑器在.bash_profile文件中添加环境变量
在 Linux 管理中,常有需要修改根目录下 .bash_profile 文件,更改环境变量的情况,文件修改后,一般的做法是重新登录,或者重新启动机器,不知道大家是怎么做的,反正我以前是用前面的两个办法中的一个,感觉很不方便。现在发现了一个命令: source .bash_profile 在修改好 .bash_profile 文件后,直接运行这个命令,就可以直接让环境变量的修改生效了。
设置完环境变量,也就意味着交叉编译工具链已经构建完成,然后就可以进行测试刚刚建立的工具链,在命令行输入arm-linux-gcc看是否有输入文件提示,如果有说明交叉编译器已经安装好。 实践出现的问题及解决方法:
问题一:执行.arm.sh出现如下权限错误? [root@localhost crosstool-0.43]# ./arm.sh + TARBALLS_DIR=/home/mike/downloads + RESULT_TOP=/opt/crosstool
+ export TARBALLS_DIR RESULT_TOP + GCC_LANGUAGES=c,c++ + export GCC_LANGUAGES + mkdir -p /opt/crosstool
++ cat arm.dat gcc-3.4.5-glibc-2.3.6.dat
+ eval 'KERNELCONFIG=`pwd`/arm.config' TARGET=arm-linux
'TARGET_CFLAGS=\"-O\"' BINUTILS_DIR=binutils-2.15 GCC_DIR=gcc-3.4.5 GLIBC_DIR=glibc-2.3.6 LINUX_DIR=linux-2.6.28.2
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2 sh all.sh --notest +++ pwd
++ KERNELCONFIG=/home/mike/crosstool-0.43/arm.config ++ TARGET=arm-linux ++ TARGET_CFLAGS=-O
++ BINUTILS_DIR=binutils-2.15 ++ GCC_DIR=gcc-3.4.5 ++ GLIBC_DIR=glibc-2.3.6 ++ LINUX_DIR=linux-2.6.28.2
++ LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0 ++ GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2 ++ sh all.sh --notest
You set both LINUX_DIR and LINUX_SANITIZED_HEADER_DIR - ignoring LINUX_DIR for the build
DEJAGNU not set, so not running any regression tests
GCC_EXTRA_CONFIG not set, so not passing any extra options to gcc's configure script GLIBC_ADDON_OPTIONS not set, so building all glibc add-on's + TOOLCOMBO=gcc-3.4.5-glibc-2.3.6 ++ pwd
+ BUILD_DIR=/home/mike/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6 ++ pwd
+ TOP_DIR=/home/mike/crosstool-0.43 + test -z ''
+ SRC_DIR=/home/mike/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6
+ echo 'SRC_DIR not set, so source tarballs will be unpacked in the build directory' SRC_DIR not set, so source tarballs will be unpacked in the build directory + abort 'Don'\\''t run all.sh or crosstool.sh as root, it'\\''s dangerous' + echo 'Don'\\''t' run all.sh or crosstool.sh as root, 'it'\\''s' dangerous Don't run all.sh or crosstool.sh as root, it's dangerous + exec false
[root@localhost crosstool-0.43]#
解决办法:
[root@localhost crosstool-0.43]# su mike //切换到普通用户mike [mike@localhost crosstool-0.43]$ ./arm.sh + TARBALLS_DIR=/home/mike/downloads + RESULT_TOP=/opt/crosstool
+ export TARBALLS_DIR RESULT_TOP + GCC_LANGUAGES=c,c++ + export GCC_LANGUAGES + mkdir -p /opt/crosstool
++ cat arm.dat gcc-3.4.5-glibc-2.3.6.dat
+ eval 'KERNELCONFIG=`pwd`/arm.config' TARGET=arm-linux
'TARGET_CFLAGS=\"-O\"' BINUTILS_DIR=binutils-2.15 GCC_DIR=gcc-3.4.5 GLIBC_DIR=glibc-2.3.6 LINUX_DIR=linux-2.6.28.2
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2 sh all.sh --notest +++ pwd
++ KERNELCONFIG=/home/mike/crosstool-0.43/arm.config ++ TARGET=arm-linux ++ TARGET_CFLAGS=-O
++ BINUTILS_DIR=binutils-2.15 ++ GCC_DIR=gcc-3.4.5 ++ GLIBC_DIR=glibc-2.3.6 ++ LINUX_DIR=linux-2.6.28.2
++ LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0 ++ GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2 ++ sh all.sh --notest
You set both LINUX_DIR and LINUX_SANITIZED_HEADER_DIR - ignoring LINUX_DIR for the build
DEJAGNU not set, so not running any regression tests
GCC_EXTRA_CONFIG not set, so not passing any extra options to gcc's configure script GLIBC_ADDON_OPTIONS not set, so building all glibc add-on's + TOOLCOMBO=gcc-3.4.5-glibc-2.3.6 ++ pwd
+ BUILD_DIR=/home/mike/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6 ++ pwd
+ TOP_DIR=/home/mike/crosstool-0.43 + test -z ''
+ SRC_DIR=/home/mike/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6
+ echo 'SRC_DIR not set, so source tarballs will be unpacked in the build directory' SRC_DIR not set, so source tarballs will be unpacked in the build directory + test -w /tmp
+ TARBALLS_DIR=/home/mike/downloads + RESULT_TOP=/opt/crosstool
+ PREFIX=/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux + export TOOLCOMBO + export PREFIX + export BUILD_DIR + export SRC_DIR
+ export TARBALLS_DIR + export TOP_DIR + '[' 1 -gt 0 ']' + opt_no_test=1 + shift
+ '[' 0 -gt 0 ']' + test '' = 1
+ test '' = '' + test '' = 1
+ test -d /home/mike/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6 + mkdir -p /home/mike/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6
mkdir: cannot create directory `/home/mike/crosstool-0.43/build': Permission denied [mike@localhost crosstool-0.43]$ su Password:
[root@localhost crosstool-0.43]# ./arm.sh
问题二:S3C2440芯片没有硬件浮点数(hardfloat),很多软件只能采用软件浮点数(softfloat)的编译器编译,恰巧现在高版本的u-boot只能采用支持softfloat的交叉编译器编译,否则会在编译结束前的链接那一步出现不支持softfloat的错误。 解决办法:要解决这个错误的唯一办法就是采用支持softfloat的交叉编译器编译uboot。下面来说一下制作softfloat的具体过程。
和上述制作交叉编译器过程一样,不同之处:1.修改arm.dat内容如下,参考arm-softfloat.dat内容修改。
KERNELCONFIG=`pwd`/arm.config TARGET=arm-softfloat-linux TARGET_CFLAGS=\"-O\"
GCC_EXTRA_CONFIG=\"--with-float=soft\" GLIBC_EXTRA_CONFIG=\"--without-fp\"
编译完之后,会在/opt/crosstool/gcc-3.4.5-glibc-2.3.6/arm-softfloat-linux/bin生成支持softfloat的交叉编译器,如下所示。
arm-softfloat-linux-addr2line arm-softfloat-linux-g++ arm-softfloat-linux-ld arm-softfloat-linux-size arm-softfloat-linux-ar arm-softfloat-linux-gcc arm-softfloat-linux-nm arm-softfloat-linux-strings arm-softfloat-linux-as arm-softfloat-linux-gcc-3.4.5 arm-softfloat-linux-objcopy arm-softfloat-linux-strip arm-softfloat-linux-c++ arm-softfloat-linux-gccbug arm-softfloat-linux-objdump fix-embedded-paths arm-softfloat-linux-c++filt arm-softfloat-linux-gcov arm-softfloat-linux-ranlib arm-softfloat-linux-cpp arm-softfloat-linux-gprof arm-softfloat-linux-readelf
因篇幅问题不能全部显示,请点此查看更多更全内容