Crosstool是由美国人Dan Kegel(毕业于加(利福尼亚)州工学院)开发的一套可以自动编译不同匹配版本gcc和glibc,并作测试的脚本程序。Crosstool最初是为嵌入式系统开发者创建,但也适用于主流开发者比如只是希望他们去快速编译或需要建立程序,可运行在旧版本的Linux操作系统(例如Red Hat的6.2 )。Crosstool是一种便携式的shell脚本。你可以使用它来建立Linux系统配置的编译器是运行在Linux , Mac OS X操作系统, Solaris和Cygwin等。它支持的硬件平台有:alpha, arm, i686, ia64, mips, powerpc, powerpc64, sh4, sparc, sparc64, s390, x86_64等。
在实践之前,我们需要回答这样的问题,为什么要使用交叉编译器?主要原因是嵌入式硬件(目标机)的性能一般都无法满足开发环境的要求,比如主频比较低、内存少、没有硬盘(常用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. |
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文件中添加环境变量
设置完环境变量,也就意味着交叉编译工具链已经构建完成,然后就可以进行测试刚刚建立的工具链,在命令行输入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]# |