本文在前章的基础上,继续深入研究,如何能正确的编译出交叉工具链
关于 --with-sysroot 这个参数,真是一个让人觉得可恨的参数,这个参数会引起一系列的问题,前章中,不得已的在 /opt/cross_toolchains/arm 中建立了两个连接文件
mkdir usr cd usr ln -s ../include include
mkdir -p opt/cross_toolchains cd opt/cross_toolchains ln -s ../../../arm arm
下面的脚本中我们将不再使用 --with-sysroot 这个configure 参数
下面的脚本将编译 arm eabi 的交叉工具链
值得注意的地方是,在编译完 glibc 后的一些处理
cd $PREFIX/arm-none-linux-gnueabi rm lib include -rf ln -s ../lib lib ln -s ../include include上面这段会解决一些看起来很难理解的问题,但我觉得这样做是正确的,因为在最后编译gcc时,需要使用到binutil的一些工具,而binutils的命令安装在bin目录下
与这个bin 同一层的 lib 和 include 目录并不存在,所以会引起编译gcc 中 pthread.h 头文件找不到,链接需要的 c 库 开工代码 ctri.o ctxxx几个 o文件找不到等问题
通过这样处理,可以解决这个问题,并且避免了使用 --with-sysroot 这个恶心的参数(autoconf 做的不够好啊,要么就是 gcc 的 autoconf脚本没写好)
比如这种问题:
arm-none-linux-gnueabi/bin/ld: cannot find crti.o: No such file or directory
自动化脚本如下,使用方法:将脚本保存为 makecross.sh,并且设置权限 chmod a+x makecross.sh,然后执行脚本./makecross.sh,可以看到帮助
后续我会补充上 targe的选择以及检测方法,cpu指令集的选择,uclibc 编译,等相关内容
#!/bin/sh # the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM unset CPU unset MFR unset KERNEL unset OS unset VER_GCC unset DIR_OPT unset DIR_SRC unset PREFIX unset TARGET export CPU=arm export MFR=none export KERNEL=linux #export OS=uclibceabi export OS=gnueabi export VER_GCC=4.6.1 export DIR_OPT=/opt/cross_toolchains export DIR_SRC=/root/cross_toolchains/src export PREFIX=$DIR_OPT/$CPU/$VER_GCC export CONFIGURE_BASE="../configure --prefix=$PREFIX" export TARGET=$CPU-$MFR-$KERNEL-$OS export PATH=$PATH:$PREFIX/bin function do_unzip_single() { cd $DIR_SRC if [ "$1" = "binutils" ];then tar -xf binutils-2.21.tar.gz elif [ "$1" = "gcc" ];then tar -xf gcc-4.6.1.tar.gz tar -xf mpfr-3.0.1.tar.gz tar -xf mpc-0.9.tar.gz tar -xf gmp-5.0.2.tar.gz mv gmp-5.0.2 gcc-4.6.1/gmp mv mpc-0.9 gcc-4.6.1/mpc mv mpfr-3.0.1 gcc-4.6.1/mpfr elif [ "$1" = "glibc" ];then tar -xf glibc-2.13.tar.gz tar -xf glibc-ports-2.13.tar.gz mv glibc-ports-2.13 glibc-2.13/ports elif [ "$1" = "kernel" ];then tar -xf linux-2.6.39.2.tar.bz2 fi } function do_download_single_do() { cd $DIR_SRC if [ ! -e $DIR_SRC/$1 ];then wget $2 fi } function do_download_single() { FILE_NAME="" URL="" if [ "$1" = "binutils" ];then set FILE_NAME=binutils-2.21.tar.gz set URL=ftp://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.gz do_download_single_do $FILE_NAME $URL elif [ "$1" = "gcc" ];then set FILE_NAME=gcc-4.6.1.tar.gz set URL=ftp://ftp.gnu.org/gnu/gcc/gcc-4.6.1/gcc-4.6.1.tar.gz do_download_single_do $FILE_NAME $URL set FILE_NAME=mpfr-3.0.1.tar.gz set URL=ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.0.1.tar.gz do_download_single_do $FILE_NAME $URL set FILE_NAME=mpc-0.9.tar.gz set URL=http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz do_download_single_do $FILE_NAME $URL set FILE_NAME=gmp-5.0.2.tar.gz set URL=ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.2.tar.gz do_download_single_do $FILE_NAME $URL elif [ "$1" = "glibc" ];then set FILE_NAME=glibc-2.13.tar.gz set URL=ftp://ftp.gnu.org/gnu/glibc/glibc-2.13.tar.gz do_download_single_do $FILE_NAME $URL set FILE_NAME=glibc-ports-2.13.tar.gz set URL=ftp://ftp.gnu.org/gnu/glibc/glibc-ports-2.13.tar.gz do_download_single_do $FILE_NAME $URL elif [ "$1" = "kernel" ];then set FILE_NAME=linux-2.6.39.2.tar.bz2 set URL=http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.2.tar.bz2 do_download_single_do $FILE_NAME $URL fi } function do_remove_single() { cd $DIR_SRC # only remove the directory,but not the zip file. if [ "$1" = "binutils" ];then rm -rf binutils-2.21 elif [ "$1" = "gcc" ];then rm -rf gcc-4.6.1 rm -rf mpfr-3.0.1 rm -rf mpc-0.9 rm -rf gmp-5.0.2 elif [ "$1" = "glibc" ];then rm -rf glibc-2.13 rm -rf glibc-ports-2.13 elif [ "$1" = "kernel" ];then rm -rf linux-2.6.39.2 fi } function do_reconstruction_single() { echo "reconstruction single package $1" cd $DIR_SRC do_remove_single $1; do_download_single $1 do_unzip_single $1 } function do_reconstruction() { cd $DIR_SRC if [ "$1" = "all" ] then do_reconstruction_single binutils do_reconstruction_single gcc do_reconstruction_single glibc else do_reconstruction_single $1 fi } function do_build_single_pre() { if [ "$1" = "binutils" ];then cd binutils-2.21 elif [ "$1" = "gcc_first" ];then # glibc need kernel's .h file mkdir -p $PREFIX/include cd $PREFIX/include rm -f asm rm -f linux rm -f asm-generic ln -s $DIR_SRC/linux-2.6.39.2/arch/arm/include/asm asm ln -s $DIR_SRC/linux-2.6.39.2/include/linux linux ln -s $DIR_SRC/linux-2.6.39.2/include/asm-generic asm-generic cd $DIR_SRC cd gcc-4.6.1 elif [ "$1" = "glibc" ];then cd glibc-2.13 echo "/* Value used for dtv entries for which the allocation is delayed. */" >> ports/sysdeps/arm/dl-tls.h echo "#define TLS_DTV_UNALLOCATED ((void *) -1l)" >> ports/sysdeps/arm/dl-tls.h elif [ "$1" = "gcc" ];then cd gcc-4.6.1 elif [ "$1" = "kernel" ];then cd linux-2.6.39.2 fi # create build directory rm -rf build mkdir -p build if [ "$1" = "kernel" ];then rm -rf build fi } function do_build_single_config { # configure if [ "$1" = "binutils" ];then $CONFIGURE_BASE \ --target=$TARGET \ --enable-shared elif [ "$1" = "gcc_first" ];then $CONFIGURE_BASE \ --target=$TARGET \ --disable-shared \ --without-headers \ --with-newlib \ --enable-languages=c \ --disable-threads elif [ "$1" = "glibc" ];then CC=$PREFIX/bin/$TARGET-gcc \ $CONFIGURE_BASE \ --host=$TARGET \ -enable-add-ons \ --with-headers=$PREFIX/include \ --with-binutils=$PREFIX/bin \ libc_cv_forced_unwind=yes \ libc_cv_c_cleanup=yes elif [ "$1" = "gcc" ];then $CONFIGURE_BASE \ --target=$TARGET \ --enable-shared \ --enable-languages=c,c++ \ --enable-c99 \ --enable-long-long \ --enable-__cxa_atexit elif [ "$1" = "kernel" ];then make menuconfig fi } function do_build_single_make() { # make and make install if [ "$1" = "gcc_first" ];then make -j4 all-gcc all-target-libgcc make -j4 install-gcc install-target-libgcc cd $PREFIX/lib/gcc/$TARGET/$VER_GCC rm libgcc_eh.a ln -s libgcc.a libgcc_eh.a elif [ "$1" = "glibc" ];then make -j4 make -j4 install cd $PREFIX/arm-none-linux-gnueabi rm lib include -rf ln -s ../lib lib ln -s ../include include else make -j4 make -j4 install fi } function do_build_single() { cd $DIR_SRC echo "build single package $1" if [ "$1" = "kernel" ];then do_build_single_pre $1 do_build_single_config $1 else do_build_single_pre $1 cd build do_build_single_config $1 do_build_single_make $1 fi } function do_build() { if [ "$1" = "all" ] then do_build_single binutils do_build_single gcc_first do_build_single glibc do_build_single gcc else do_build_single $1 fi } function do_rebuild() { rm -rf $PREFIX/* do_reconstruction $1 do_build $1 } function do_help() { echo "usage:" echo " ./makecross reconstruction binutils" echo " ./makecross reconstruction gcc" echo " ./makecross reconstruction glibc" echo " ./makecross reconstruction all" echo " ./makecross build binutils" echo " ./makecross build gcc_first" echo " ./makecross build glibc" echo " ./makecross build gcc" echo " ./makecross build all" echo " ./makecross rebuild all" } # main entery # to install necessary package # aptitude install build-essential automake bison flex texinfo gawk g\+\+ zip # aptitude remove mawk SOME=`aptitude show build-essential automake bison flex texinfo gawk g\+\+ zip|grep "State: not install"` #echo $SOME if [ ! "$SOME" = "" ];then echo "aptitude install" aptitude install build-essential automake bison flex texinfo gawk g\+\+ zip fi SOME=`aptitude show mawk | grep "State: installed"` if [ ! "$SOME" = "" ];then echo "aptitude remove mawk" aptitude remove mawk fi # about kernel # if there is no kernel headers,then rebuild kernel # include/linux/version.h and include/generated/autoconf.h if [ ! -e $DIR_SRC/linux-2.6.39.2/include/linux/version.h ];then #echo "version" if [ ! -e $DIR_SRC/linux-2.6.39.2/include/generated/autoconf.h ];then echo "reconstruction kernel" do_reconstruction_single $1 fi fi echo "check and rebuild env done." # do command if [ "$1" = "reconstruction" ];then do_reconstruction $2 elif [ "$1" = "build" ];then echo "build" do_build $2 elif [ "$1" = "rebuild" ];then do_rebuild $2 else do_help fi