使用crosstool 制作arm-linux交叉编译链

crosstool是个不错的软件,能够很方便的编译自己的交叉编译环境
目前最新版本crosstool-0.43 在地址 http://kegel.com/crosstool/crosstool-0.43.tar.gz 可以下载。

首先获取工具包,解压后进入其目录

  1. wget http: // kegel.com / crosstool / crosstool -0.43 . tar .gz
  2. tar -xzvf crosstool -0.43 . tar .gz
  3. cd crosstool -0.43

选择自己希望的模板,这儿是以arm9做试验玩,因此选择了 demo-arm9tdmi.sh 做模板。

  1. cat demo-arm9tdmi. sh

可以看到

#!/bin/sh
# This script has one line for each known working toolchain
# for this architecture. Uncomment the one you want.
# Generated by generate-demo.pl from buildlogs/all.dats.txt

set -ex
TARBALLS_DIR=/home/kevin/downloads #下载的软件包存放的地址
RESULT_TOP=/home/kevin/crosstool #交叉编译环境安装在哪里
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES=”c,c++”
export GCC_LANGUAGES

# 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

#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.2.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.2.3-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.2.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.3.6-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.2.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.5-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-3.4.5-glibc-2.3.6-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.2.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.2-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.5.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.5-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.6.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.0.2-glibc-2.3.6-tls.dat` sh all.sh –notest
#eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2.dat` sh all.sh –notest
eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh –notest

echo Done.

其中红色字为自己修改的地方,看最后一个红色的行,表示我们要编译 gcc 4.1.0 的,如果你想要制作某个版本的交叉编译器,就必须要找到对应的dat文件。

  1. cat arm9tdmi.dat

可以看到

KERNELCONFIG=`pwd`/arm.config
TARGET=arm-9tdmi-linux-gnu
GCC_EXTRA_CONFIG=”–with-cpu=arm9tdmi –enable-cxx-flags=-mcpu=arm9tdmi”
TARGET_CFLAGS=”-O”

其中红色的文字可以根据自己的需要做修改,一般是 arm-linux ,符合网上面很多编译情形的。

  1. cat gcc -4.1 .0 -glibc -2.3 .2 -tls.dat

可以看到

BINUTILS_DIR=binutils-2.16.1

GCC_CORE_DIR=gcc-3.3.6
GCC_DIR=gcc-4.1.0
GLIBC_DIR=glibc-2.3.2
LINUX_DIR=linux-2.6.15.4
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2
GDB_DIR=gdb-6.5
GLIBC_EXTRA_CONFIG=”$GLIBC_EXTRA_CONFIG –with-tls –with-__thread –enable-kernel=2.4.18″

通过这个文件可以看到为了生成4.1.0的交叉编译器需要各种不同软件包的版本号,制作不同版本的交叉编译器,配置时需要的软件版本号是非常严格的,将红色的字对应的bz2包下载下来(这些文件我基本都是在 chinaunix 那儿下载的,下载速度很快),放到前面设定的 /home/kevin/downloads目录中。不下载也可以,sh脚本中自己会用wget下载,但是会等很多时间,比自己直接下载多出了很多很多的时 间(具体多多少,自己试验一下就知道了,保证你试了后会很后悔,呵呵^_^)。
然后执行

         ./ demo-arm9tdmi.sh   #可以看到在这个脚本中其实时执行了all.sh,在all.sh中其实就是将我们先前一步步制作交叉编译器的步骤综合

         编译完成后,有目录 /home/kevin/crosstool/gcc-4.1.0-glibc-2.3.2/arm-linux/ 目录比较长,后来分析了一下all.sh脚本,发现可以通过设置PREFIX值来减少结果路径长度,不过编译一遍需要那么长的时间,就没有实际试验.

         最后在~/.bashrc文件的最后加入:        export PATH= $PATH :/ home/ kevin/ crosstool/ gcc-4.1 .0 -glibc-2.3 .2 / arm-linux/ bin

         这样新打开的终端就可以使用 arm-linux-gcc 等命令了。

 

 

在使用crosstool构建工具链的过程中,出现了如下问题,导致arm-linux-gcc没有生成:
   
    > checking version of gcc... 4.0.0, bad
    > checking for gnumake... no
    > checking for gmake... gmake
    > checking version of gmake... 3.80, ok
    > configure: error:
    > *** These critical programs are missing or too old: gcc
    > *** Check the INSTALL file for required versions.

    察看crosstool目录中的contrib/inbox.txt文件,有关于这个问题的邮件描述:

> checking build system type... i686-pc-linux-gnu
> checking host system type... mipsel-unknown-linux-gnu
> checking sysdep dirs... sysdeps/mips/elf sysdeps/unix/sysv/linux/mips
> sysdeps/unix/sysv/linux sysdeps/gnu sysdeps/unix/common
> sysdeps/unix/mman sysdeps/unix/inet sysdeps/unix/sysv sysdeps/unix/mips
> sysdeps/unix sysdeps/posix sysdeps/mips/mipsel sysdeps/mips/fpu
> sysdeps/mips sysdeps/wordsize-32 sysdeps/ieee754/flt-32
> sysdeps/ieee754/dbl-64 sysdeps/ieee754 sysdeps/generic/elf sysdeps/generic
> checking for a BSD-compatible install... /usr/bin/install -c
> checking whether ln -s works... yes
> checking for pwd... /bin/pwd
> checking for mipsel-unknown-linux-gnu-gcc... gcc
> checking version of gcc... 4.0.0, bad
> checking for gnumake... no
> checking for gmake... gmake
> checking version of gmake... 3.80, ok
> configure: error:
> *** These critical programs are missing or too old: gcc
> *** Check the INSTALL file for required versions.
>
I have had the same problem. What I found was that the glibc configure
script was testing for a version of gcc 3.2.* or later. It does not test
for a major number above 3 so the test fails. I do not know where this
test is initiated, but once you have reached that point you can patch
the configure script and run demo-*.sh with the --nounpack option added
to your desired toolchain build.

This patch worked for me:

--- configure.orig      2005-09-19 21:31:45.000000000 -0400
+++ configure   2005-09-19 21:32:13.000000000 -0400
@@ -2274,6 +2274,8 @@
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
     3.[2-9]*)
        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
+    4.*)
+       ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
 
   esac

I hope that this helps. Good Luck.
-Mike Joyce

    其意思就是说,在glibc的configure脚本里会检查gcc的版本,当不是需要的版本就报错, glibc的configure中有如下检查:

if test -z "$CC"; then
  ac_verc_fail=yes
else
  # Found it, now check the version.
  echo "$as_me:$LINENO: checking version of $CC" >&5
echo $ECHO_N "checking version of $CC... $ECHO_C" >&6
  ac_prog_version=`$CC -v 2>&1 | sed -n 's/^.*version /([egcygnustpi-]*[0-9.]*/).*$//1/p'`
  case $ac_prog_version in
    '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
    3.[2-9]* )
       ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
    *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;

  esac
  echo "$as_me:$LINENO: result: $ac_prog_version" >&5
echo "${ECHO_T}$ac_prog_version" >&6
fi
if test $ac_verc_fail = yes; then
  critic_missing="$critic_missing gcc"
fi

    在上面的gcc版本检查中,只使用了模式3.[2-9]*即只支持3.xxx版本的gcc,在crosstool自己的patches目录下有一个 patch:patches/glibc-2.3.3-allow-gcc-4.0-configure.patch,他会在编译glic-2.3.2的 时候给这个configure文件先打补丁所以我们只需要修改对应的补丁文件也就是patches/glibc-2.3.3-allow-gcc-4.0-configure.patch,他会在编译 glic-2.3.2时候自动的将这个补丁打在 glic-2.3.2顶层的configure文件而不需要我们自己手动来打这个补丁 ,那个补丁来修复这个bug,但是这个补丁文件也不是很好,其内容是:


--- glibc-2.3.3/configure.old    Mon Mar 14 12:01:10 2005
+++ glibc-2.3.3/configure    Mon Mar 14 12:02:03 2005
@@ -3899,7 +3899,7 @@
   ac_prog_version=`$CC -v 2>&1 | sed -n 's/^.*version /([egcygnustpi-]*[0-9.]*/).*$//1/p'`
   case $ac_prog_version in
     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
-    3.[2-9]*)
+    3.[2-9]*|4.[01]* )
        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
     即,它只是增加了对4.0xxx或者4.1xxx的支持,还是不够,我现在用的是4.2.1因此还是会出错,因此,修改这个patch,改为3. [2-9]*|4.*) 就可以过去了。

    总之,在编译glibc的时候,其configure脚本对gcc的限定是比较严格的,而且并没有将后来的较新的版本考虑在内,这种严格的检查是我们在 configure是出了错。但是如果我们直接修改glibc原码中的configure文件,又会造成crosstool在用他自己的patches给 glibc的configure打补丁的时候出错,呵呵,还是去修改crosstool的补丁文件吧,glibc就留着不要动了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值