全部博文(584)
分类: LINUX
2009-12-31 15:28:41
注:本文基于Debian测试成功
1.crosstool要求不能在root用户下运行脚本,因此在下载好源码包之后就切换到普通用户模式下,拷贝源码包到相应目录进行修改.
2.脚本中对于编译成功后生成的交叉编译工具链的存放目录,一定要选择普通用户有权限访问的目录,否则中途会由于没有权限而停止.
3.crosstool依赖的一些包,有些是系统默认没有安装的,在我的Debian系统中,bison和flex默认是没有安装的,编译报错我才安装上,因此最好能够在开始编译之前安装这些软件包(Debian的第一张关盘中就有).
4.linux内核版本的选择.
参考网上的一篇文章,如下所述:
Linux内核头文件
编译Glibc必须要有linux内核头文件。最初人们直接使用内核源码包中的头文件(/usr/include目录下),后来由于内核开发者强烈反对这种做法,于是出现了linux-libc-headers项目,以为Linux头文件维护一个稳定版本的API。最近该项目已经停止发展(该项目提供的最新版本的“纯净的”头文件版本是2.6.12.0);从2.6.18版本开始,内核开发组负责维护一份统一的、“纯净的”内核头文件,获取编译glibc所需的头文件只需要使用命令”make headers_install”即可。
Linux内核版本选择
为目标系统选择一个Linux内核版本,除了要考虑实际应用的需求之外,还要考虑到与交叉编译工具链的匹配、内核新特性等诸多方面。
例如,建立交叉编译工具链时使用2.6.22.6版本的内核头文件来编译Glibc,那么使用这个Glibc编译得到的应用程序可以用于2.6.22.6以及以前版本的linux系统,这是其向后兼容(backwards compatability)特性决定的——那么最早可以用于哪个版本的Linux系统呢?这是在编译Glibc时使用—enable-kernel选项传递给configure脚本来限制的,例如--enable-kernel=2.6.14,就表示运行应用程序的Linux系统内核版本至少要求为2.6.14。这个应用程序可否用于2.6.22.6以上版本的Linux系统呢?原则上也是可以的,只要更高版本的Linux系统配置为向后兼容,不过,即使这个应用程序可以运行在高版本的内核系统上,也不会支持高版本系统的新特性。
那么目标系统的Linux内核版本与交叉编译工具的匹配要考虑哪些方面呢?这其实没有一个公认的标准,其匹配性也受错综复杂的内在因素的影响。一般而言,内核没有发生重大变化的条件下,可以使用建立toolchain所用内核版本(2.6.22.6)及其之前的一些版本,也可能可用于后续的几个版本(没有保证)——这是因为随着内核版本的更新,会有越来越多的新特性添加进来,甚至会丢弃一些旧的特性。例如,ARM EABI就需要内核本身对它的支持,另外,本文所编译的Glibc也需要NPTL的内核支持;而Linux 2.6.16是第一个具有上述所有特性的内核发行版,因此,与本文的toolchain匹配性较好的内核版本应该是介于2.6.16和2.6.22.6之间。
5.关于编译步骤与说明
(1) 建立自己的crosstool目录,并拷贝必要的文件。
#assuming $PWD=~/downloads/crosstool-0.42 mkdir ~/crosstool #build our own crosstool directory cp -v demo-arm-iwmmxt.sh ~/crosstool mkdir demo-script mv demo* demo-script/ #we do not need other demo-*sh scripts cp -av *.sh ~/crosstool #copy all.sh,crosstool.sh,... to our own directory cp -av *.c ~/crosstool #copy fix-embedded-paths.c,... to our own directory #you can skip this step if you do not need it cp config.guess ~/crosstool #we need config.guess to get the value for $BUILD |
(2) 编辑cpu.dat和gcc-glibc.dat文件。
显然我们还缺少这两个核心文件来传递必要的参数,我们将这两个文件分别命名为arm-iwmmxt-eabi.dat和latest.dat。编辑arm-iwmmxt-eabi.dat文件如下:
TARGET=arm-iwmmxt-linux-gnueabi TARGET_CFLAGS="-O" GCC_EXTRA_CONFIG="--with-float=soft --with-cpu=iwmmxt --with-arch=iwmmxt --enable-cxx-flags=-msoft-float" GLIBC_EXTRA_CONFIG="--without-fp --disable-libunwind-exceptions" GLIBC_EXTRA_CC_ARGS="-finline-limit=10000" USE_SYSROOT=1 |
注意,TARGET的名字并不是随意的,必须以arm开头而不能是pxa27x等其他字符串开头,因为crosstool会根据TARGET的名字来解析$ARCH的值。gcc的configure文件也要根据TARGET名字来进行裁决,如果要编译新的ARM EABI标准的toolchain,TARGET名字应该以arm*-*-linux-gnueabi形式出现。这里设置USE_SYSROOT是要按新的组织形式来安排目标系统根目录的库文件。
编辑latest.dat如下:
BINUTILS_DIR=binutils-2.18 GCC_DIR=gcc-4.2.1 LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.22.6 GLIBC_DIR=glibc-2.6.1 GLIBCPORTS_FILENAME=glibc-ports-2.6.1 GLIBC_ADDON_OPTIONS=ports,nptl |
(3) 将demo-arm-iwmmxt.sh重命名为arm-iwmmxt-eabi.sh,并编辑如下:
#!/bin/sh set -ex TARBALLS_DIR=$HOME/crosstool/downloads RESULT_TOP=/opt/crosstool GCC_LANGUAGES="c,c++" export GCC_LANGUAGES PARALLELMFLAGS=-j3 export PARALLELMFLAGS # Really, you should do the mkdir before running this, # and chown /opt/crosstool to yourself so you don''''t need to run as root. mkdir -p $RESULT_TOP # Build the toolchain. Takes a couple hours and a couple gigabytes. time eval `cat arm-iwmmxt-eabi.dat latest.dat` sh all.sh --notest echo Done. |
(4) 修改all.sh。
① 注释掉getandpatch.sh的调用部分。因为我们是手工下载源码包并打补丁的,只要把处理好的源代码放到相应目录下即可,不需要getandpatch.sh自动下载源码包。
if test "$opt_no_unpack" = ""; then if test "$opt_builduserland" = "1"; then # Ah, nobody would want to change this :-) PTXDIST_DIR=ptxdist-testing-20031113 export PTXDIST_DIR fi # Download and patch ##################commented out by aaron############## # if test -d "$BUILD_DIR"; then # Remove in background # mv $BUILD_DIR $BUILD_DIR.del.$$ # rm -rf $BUILD_DIR.del.$$ & # fi # mkdir -p $BUILD_DIR # sh getandpatch.sh ####################################################### fi |
② 根据个人喜好修改PREFIX的值:
# Arbitrary locations for the input and output of the build. # Change or override these to your taste. #################commented out by aaron######################## #TARBALLS_DIR=${TARBALLS_DIR-$TOP_DIR/tarballs} #RESULT_TOP=${RESULT_TOP-$TOP_DIR/result} ############################################################### ####################modified by aaron########################## #PREFIX=${PREFIX-$RESULT_TOP/$TOOLCOMBO/$TARGET} PREFIX=$RESULT_TOP |
设置“PREFIX=$RESULT_TOP=/opt/crosstool”可使目标系统的根目录更“浅”,这是因为crosstool.sh中设置了SYSROOT=${PREFIX}/${TARGET}/sys-root,于是相当于有$SYSROOT=/opt/crosstool/arm-iwmmxt-linux-gnueabi/sys-root。
③ 禁止自动进行目录清理:
if test "$opt_no_build" = ""; then # Build ###################commented out by aaron################ # if [ -d "$PREFIX" ]; then # Remove in background for speed # mv "$PREFIX" "$PREFIX.del.$$" # rm -rf "$PREFIX.del.$$" & # fi # mkdir -p $PREFIX # mkdir -p $BUILD_DIR ########################################################## cd $BUILD_DIR |
由于arm-iwmmxt-eabi.sh中调用all.sh时没有传递--nobuild参数,因此上面被注释掉的语句会清除旧的$BUILD_DIR,建立一个新的干净的$BUILD_DIR,然后再调用crosstool.sh建立toolchain。
另一方面,由于我们是要手工将源码包处理好放到SRC_DIR的,又因为没有给出SRC_DIR的值,all.sh认为SRC_DIR=$BUILD_DIR,这样实际上要求我们把源码包放到BUILD_DIR下,于是上面的语句恰好把我们的SRC_DIR连同其中处理好的源码包一起删除了。所以要把上面的语句注释掉。
[说明]另外一种简单解决方法是,在arm-iwmmxt-eabi.sh中调用all.sh时传递—nobuild参数,然后把手工处理好的源码包都放到SRC_DIR(实际上也就是相同的BUILD_DIR下),这样就不必注释掉上面的语句了。
④ 其他注释:
# sh testhello.sh #commented out by aaron |
(5) 修改crosstool.sh。
① 修正内核头文件的安装。
cp -r include/linux $HEADERDIR cp -r include/asm-${ARCH} $HEADERDIR/asm ################added by aaron######################### cp -r include/asm-generic $HEADERDIR/asm-generic cd $BUILD_DIR |
按照原来的脚本,会漏拷include/asm-generic目录,导致编译时找不到头文件而报错退出。
② 禁止修改GCC_HOST。
# if host is cygwin and this is not a canadian build, modify GCC_HOST ########################commented out by aaron################################ #case "$GCC_HOST,$CANADIAN_BUILD," in #*cygwin*,?*,) ;; #*) GCC_HOST=`echo $GCC_HOST | sed s/-/-host_/` ;; #esac ############################################################################## |
本来有GCC_HOST=`./config.guess`=i686-pc-linux-gnu,上面的语句会将其更改为GCC_HOST=i686-host_pc-linux-gnu,导致在编译时找不到主机的CC而出错。
(6) 源码包处理与目录组织
接下来要按上面脚本中的目录设置来组织源码包并建立相应目录。
(1) 必须手动建立的目录: RESULT_TOP=/opt/crosstool(见arm-iwmmxt-eabi.dat),以及BUILD_DIR=`pwd`/build/$TARGET/$TOOLCOMBO (见all.sh) = ~/crosstool/build/arm-iwmmxt-linux-gnueabi/gcc-4.2.1-glibc-2.6.1。
mkdir -p ~/crosstool/build/arm-iwmmxt-linux-gnueabi/gcc-4.2.1-glibc-2.6.1 sudo mkdir /opt/crosstool sudo chown -Rv aaronwong /opt/crosstool |
注意,用root用户建立交叉编译工具是不安全的,应该用普通用户登录;因此必须要改变安装目录/opt/crosstool的所有者,以让普通用户(笔者是aaronwong)拥有该目录的读写权限。
(2) 源码包处理:将所有的源码包放到$BUILD_DIR目录下,并解压缩,打补丁。最后的各源码包目录名应该与latest.dat中设定的一致。以linux內核头文件安装为例:
tar xvf linux-headers-2.6.22.6-09032007.tar.bz2 cd linux-headers-2.6.22.6 install -dv ../linux-libc-headers-2.6.22.6 cp -av include/{asm-generic,asm-arm,linux,mtd,scsi,sound} ../linux-libc-headers-2.6.22.6 |
(7)开始自动安装
经过前面的定制之后,只要在终端下输入命令”sh arm-iwmmxt-eabi.sh”,计算机就开始自动编译安装toolchain,大约40 – 90分钟便可完成(视主机系统的配置而定)。
[提示] 2.3节仅是笔者根据需要对crosstool所作的定制,采用手动下载源码包并打补丁的方法,建立支持PXA27x处理器iWMMX技术的符合ARM EABI标准的toolchain。读者可以在理解crosstool工作机制的前提下,根据自己的实际情况作相应的定