crosstool是个不错的软件,能够很方便的编译自己的交叉编译环境 目前最新版本crosstool-0.43 在地址 http://kegel.com/crosstool/crosstool-0.43.tar.gz 可以下载。 首先获取工具包,解压后进入其目录 wget http:// kegel.com/ crosstool/ crosstool-0.43 .tar .gz tar -xzvf crosstool-0.43 .tar .gz cd crosstool-0.43 选择自己希望的模板,这儿是以arm9做试验玩,因此选择了 demo-arm9tdmi.sh 做模板。 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文件。 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 ,符合网上面很多编译情形的。 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就留着不要动了。

浙公网安备 33010602011771号