交叉工具链制作至尊宝典(二)

本文在前章的基础上,继续深入研究,如何能正确的编译出交叉工具链

关于 --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 参数而导致的,关键是我不知道如何解决!!

下面的脚本中我们将不再使用 --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

 


发布了36 篇原创文章 · 获赞 33 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/turui/article/details/6620951
今日推荐