论坛风格切换切换到宽版
发帖 回复
返回列表  提醒:不能用迅雷等P2P下载,否则下载失败标(二级)的板块,需二级才能下载,没二级不要购买,下载不了
  • 1564阅读
  • 6回复

[资料贡献]全手工制作arm-linux交叉编译工具链 (三个阶段) [复制链接]

上一主题 下一主题
离线fuchch
 

性别:
帅哥
发帖
17
金币
0
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看楼主 倒序阅读 使用道具 0楼 发表于: 2016-10-13
全手工制作arm-linux交叉编译工具链 R}lsnX<  
(Gcc 4.2.1 + Glibc 2.6.1 + Linux 2.6.22.6)《一》 }; f#^gz'  
作者:Garfield Trump pek%08VSEU  
仅仅是本人在学习嵌入式系统时的体会、看法,难免有理解错误,乐意接受阅读本文的各方人士指 ;PjQt=4K  
出错误。 \ gLHi~  
联系方式:Garfield_Trump@yahoo.com :_t}QP"  
本文原理部分主要参考并引用下面网址的文章: S(uf(q|{  
http://www.decell.org/article.asp?id=53 ;_^fk&+  
但因为此文制作的版本太旧,本人没有使用,但经过验证是可以成功制作的。 yQ^($#Yk  
本文制作使用的软件版本主要参照以下网址: z .Y$7bf)  
http://cross-lfs.org/view/clfs-sysroot/arm/ #Sa27$&.>  
但此网址的制作过程有错,Garfield Trump 在本文予以纠正。 aj?a^}X  
《一》环境配置: /)dFK~  
工作站:基于x86体系的个人计算机或其他同类的计算机系统。 f-5:wM&  
目标平台:基于ARM v4I 内核体系结构的SoC系统,本文使用的目标系统是三星公司的S3C2410系列  b^p"|L  
[o.B  
软件环境: x-?{E  
工作站: CMn{LQcC  
目标平台:无相关要求。 "dI;  
《二》概述 YhY:~  
当我们需要从源代码编译出一个能运行在ARM 架构上的程序的时候,我们可以有两种方法。第一种 >2< 8kBF_  
是像我们平常一样,使用相同架构机器上的编译器,编译出运行在同一架构上的程序。在嵌入式系 :%sXO  
统领域,这是较难实现的。嵌入式系统的在设计的时候由于考虑到功耗,体积等要求,性能往往较 t 0-(U\  
弱。在编译一些比较大规模的程序时候,嵌入式系统在编译上耗费的时间,是我们无法忍受的。因 9:e YU =  
此,我们需要使用交叉编译技术 jK' N((Hz  
交叉编译技术,是一种在一个异构平台上编译出目标平台程序的一种技术。理论上来说,交叉工具 XK: 9r{r{  
链可以用在任何两种异构的系统中,例如,我们可以构建出PowerPC-ARM工具链,Sun Sparc-x86工 e'=MQ,EWd  
具链等等。目前交叉工具链一般用于目标平台计算能力较弱,需要其他计算能力较强的平台帮助产 rtL}W__  
生可运行软件的场合。在基于ARM的嵌入式系统开发中,我们一般会使用x86架构的计算机系统作 TOoQZTI  
为工作站,故最为常用的是x86-ARM交叉工具链。 目前市场上存在着各种各样不用的 bd<m%OM""  
x86-ARM交叉工具链,有ARM公司自家在RVDS开发工具中整合的armcc,有Microsoft 9Ffp2NW`;  
在Platform Builder中的armv4I 编译器等。一般来说,这些由商业公司提供的工具链,都不会附有工 C#H:-Q&  
具链相关的源代码和制作方法,灵活性不足,并且它们一般都与整套开发系统捆绑销售使用,成本 @"o@}9=d  
较高。为了更好的理解这种技术和降低成本,获得更好的灵活性,市场上有不少的公司使用国际开 x3u4v~ "-  
源组织GNU开发的工具链作为他们产品开发的工具。本文下面的章节就为大家展示一个完整的 '&sE=.  
GNU工具链构建过程。其中可能涉及到一些GNU Linux系统的基本操作知识,如果大家对此认识不 SL,p36N  
深,请自行查阅相关资料 |U_]vMq  
《三》工具链原理及构建方法 V=lfl1Ev0J  
3.1原理: 5* 0y7K/D  
每一个软件,在编译的过程中,都要经过一系列的处理,才能从源代码变成可执行的目标代码。这 a\%xB >LX  
一系列处理包括:预编译,高级语言编译,汇编,连接及重定位。这一套流程里面用到的每个工具 IXb}AxB f  
和相关的库组成的集合,就称为工具链(tool chain)。以GNU的开发工具GCC为例,它就包括了预 )x]3Zq  
编译器cpp,c编译器gcc,汇编器as,和连接器ld等。在GNU自己对工具链定义中,还加进了一套额 8Th` ]tI  
外的用于处理二进制包的工具包binutils,整个工具链应该是GCC+binutils+Glibc,不过大家后面将会 tqy@iEz+  
看到binutils其实与Glibc无关,它是可以被独立安装的,所以GNU工具链也可以狭义地被理解为 {O+Kw<d  
GCC+Glibc。 J7v|vj I  
一般的情况下,工具链运行的环境和它产生的目标代码的环境是一致的。例如我们在VC中编译一个 '(dz"PL.  
程序,工具链运行在x86平台,产生的也是运行在x86平台上的代码。但实际上,工具链产生的目标 +n7?S~R$  
代码的运行平台是可以跟工具链运行的环境不一致的。这种产生与运行环境不一致的目标代码的工 |,aG%MTL  
具链,称为交叉工具链(cross-compiler tool chain),使用这种工具链的编译过程对应地被称为交叉编 5bA)j!#)|X  
译(cross-compile)。在GNU中,一般在普通工具链名称的前面加上特定的前缀,以表示是什么类型的 JkGnKm9G  
工具链。例如x86-arm的工具链,预编译器是arm-linux-cpp,c编译器arm-linux-gcc等。 !o>H1#2l  
要构建出一个交叉工具链,需要解决三个问题。一是这个工具链必须是可以运行在原工作站平台上 lw :`M2P,  
的。二是我们需要更换一个与目标平台对应的汇编器,使得工具链能产生对应的目标代码,三是要 NNF>Xa`9,  
更换一套与目标平台对应的二进制库,使得工具链在连接时能找到正确的二进制库。 0v]?6wX  
3.2构建方法 z.6$W^  
3.2.1建立binutils |Xw/E)jA  
首先我们建一个目录,作为存放工具链的地方。因为binutils和Glibc头文件的独立性,我们先把他们 vBsP+K  
放到这个目录里面。如示意图1所示 %J8|zKT5t  
示意图1 (新加入内容以下划线标记) <&!v1yR  
3.2.2 建立GCC Stage1 p2N:;lXM  
然后我们使用工作站平台的工具链,编译出一条交叉工具链,通过指定工具链的类型,我们可以控 r)T:7zy  
制该工具链汇编器的输出类型。但此时该工具链指向库依然是工作站平台的二进制库。此阶段称为 >+mD$:L  
GCC Stage1。如示意图2所示 XTd3|Pm  
示意图2(新加入内容以下划线标记) *#TYqCc+g  
3.2.3 建立构建一个目标平台的二进制库 .)+h H y  
接下来我们利用刚刚建立的GCC构建一个目标平台的二进制库。由于二进制库都是自包含的,所以 1pCieTz!PN  
我们无需担心这个二进制库中会调用工作站平台的库进而产生依赖问题。见示意图3 IQ!\w-  
示意图3(新加入内容以下划线标记) ZbT/$\0(6  
3.2.4 建立GCC Stage2 !I\!;b  
最后我们使用工作站平台的工具链重新编译一次GCC,使得GCC指向新编译出来的库,此阶段称为 Nk[2nyeO>  
GCC Stage2。见示意图4 Pub0IIs  
示意图4(新加入内容以下划线标记) h!#:$|Q  
全手工制作arm-linux交叉编译工具链 <jS~ WI@  
(Gcc 4.2.1 + Glibc 2.6.1 + Linux 2.6.22.6)《二》 xP=/N!,#  
作者:Garfield Trump vfNAs>Xg"  
《四》具体实现: fGv#s X  
http://cross-lfs.org/view/clfs-sysroot/arm/index.html |8bq>01~  
在此部分的制作过程主要参考以上网站完成,但其中制作过程有错,在本文中Garfield Trump予以了 Lw'9  
纠正。读者可以事后参看一下。我会在以下篇幅中指出与该网站的不同之处,并说明错在什么地方 !;Jmg  
j&UMjI9[  
建议先看本文,此网站的目录结构比较混乱,而且按该网站所述建立工作目录,一定会出错,是在 f""`cdqAOh  
第二阶段 Gcc zyg:nKQW  
制作中出错,原因是找不到头文件。 {ls+d x/  
4.1 下载所需源码 }P3tn  
http://ftp.gnu.org/gnu/binutils/binutils-2.18.tar.bz2 ?+c`]gO7N  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/binutils-2.18-posix-1.patch GdVhK:<>  
http://ftp.gnu.org/gnu/gcc/gcc-4.2.1/gcc-4.2.1.tar.bz2 {u[V{XIUh  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/gcc-4.2.1-posix-1.patch W- $a Y2  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/gcc-4.2.1-cross_search_paths-1.patch -B$~`2-  
http://ftp.gnu.org/gnu/glibc/glibc-2.6.1.tar.bz2 4gSH(*}  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/glibc-2.6.1-sysdep_cancel-1.patch pr,p=4m{\  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/glibc-2.6.1-localedef_segfault-1.patch 81%8{yn!$"  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/glibc-2.6.1-libgcc_eh-1.patch h7X_S4p/Mg  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/glibc-2.6.1-hppa_nptl-1.patch 0e[d=)XG  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/glibc-2.6.1-cross_hacks-1.patch ^2o dr \  
http://svn.cross-lfs.org/svn/repos/cross-lfs/branches/clfs-sysroot/patches/glibc-2.6.1- IkzTJ%>  
RTLD_SINGLE_THREAD_P-1.patch q@hp.(V  
4.2 设置环境变量 <e%F^#y_  
export TAR=/tar `Y40w#?uW  
//设置源文件压缩包的存放目录路径 dP]1tAO,y  
export TOP=/usr/local/arm L5IbExjV  
//设置目标工具链目录的顶成目录 \uG`|D n  
export CLFS=${TOP}/clfs qpJ{2Q  
//设置编译过程工作目录 ]ALc;lb-}  
export SYSROOT=${TOP}/4.2.1 /?/#B `  
//设置目标工具链的工作目录 : t$l.+B  
export TARGET_PREFIX=${TOP}/4.2.1 N:VX!w  
//设置目标工具链的安装目录 CJaKnz  
注意:这里的SYSROOT 和 TARGET_PREFIX 设成相同。跟http://cross-lfs.org/view/clfssysroot/arm/index.html 上所讲的有所不同,也是该网站出错最严重的地方,因为不但制作过程需要 A\Txb_x  
Linux 内核头文件 跟 glibc 的头文件,而且以后使用这个制作出来的目标交叉编译工具链来编译程序 nsb4S {  
的时候也会用到这些头文件,特别是Linux内核的头文件。所以Garfield *FR$vLGn  
Trump 把SYSROOT 和 TARGET_PREFIX设成相同,以便把头文件直接安装到目标交叉编译工具链的 MYe HS   
工作目录中。 z5Qs @dG  
LINUX_VERSION=2.6.22.6 R)Mt(gFZT_  
//设置 Linux 的版本号 ~Z$bf>[(R7  
BINUTILS_VERSION=2.18 (IbW; bV  
//设置 binutils 的版本号 B6}FIg)  
GLIBC_VERSION=2.6.1  6qo^2  
//设置 glibc 的版本号 D~K;~nI  
GCC_VERSION=4.2.1 ]J2:194  
//设置 目标工具链的版本号 fR-C0"c  
unset CFLAGS //禁用两个环境变量,因为可能导致编译过程出错 ,}D}oo*  
unset CXXFLAGS //默认情况下这两个环境变量为空,但随不同的Linux 平台的不同,或者用户自己之 $\a5&1rl  
前的使用过程中设置了这两个变量设置目标工具链的目标体系,Gcc编译器会根据这个变量来确定目 )<4_:  
标交叉编译工具链是为那个目标体系的cpu编译程序的。 T_<BVM  
export CLFS_TARGET="arm-linux" Cup@TET35  
//设置目标交叉编译工具链的编译器(arm-linux-gcc)的路径,因为在完成第一阶段arm-linux-gcc的 /DS?}I.*]  
编译后,我们将会把它安装到这里,并且使用它来编译出第二阶段 arm-linux-gcc 制作所依赖的动态 9O,,m~B  
链接库 glibc。 Fs/?  
export PATH=${TARGET_PREFIX}/bin:/bin:/usr/bin:$PATH _'x8M  
4.3建立相应工作目录安装Linux 内核头文件 ,je`YEC  
rm -rf ${TOP} "L& k)J  
//清除可能干扰制作过程的目录 1D([@)^  
install -dv ${SYSROOT}/usr/include  ZC^C  
//建立Linux头文件安装目录 ^%oUmwP<$  
install -dv ${TOP}/source K7vw3UwGN  
//建立源码解压目录 vC/[^  
cd ${TOP}/source cJ}QXuuUv  
//进入源码解压目录 (d2@Mz  
cp ${TAR}/linux-${LINUX_VERSION}.tar.gz ~KIDv;HSb[  
./ #$'"cfRxc  
//拷贝源码包到解压目录 &$fbP5uAZ  
gzip -d ./linux-${LINUX_VERSION}.tar.gz &;q<M_<  
//解压Linux 内核源码包 :_dICxaLZT  
tar -xf linux-${LINUX_VERSION}.tar ,i`h x, Rg  
//解包 Linux 内核源码包 eTE2J~\  
rm -rf linux-${LINUX_VERSION}.tar y)J(K*x/$  
//解包完后删除 Linux 内核源码包 h!]"R<QQdu  
cd linux-${LINUX_VERSION} 17UK1Jx,  
//进入Linux 内核源码目录 3=4SGt5m  
make s3c2410_defconfig ARCH=arm o#i ]"  
//设置 Linux 内核源码匹配的cpu 体系 m24v@?*  
//注意:下面一步是Garfield Trump 给予纠正的一步,在官方网站http://cross-lfs.org/view/clfssysroot/arm/index.html下是没有这一步的,会导致后面的编译出错。 ]gd/}m)1  
make include/linux/version.h DR+,Y2!_GT  
//生成Linux 版本头文件。 ~\_T5/I%  
//复制制作目标交叉编译工具链所要的Linux头文件 2 g`[u|  
cp -a include/{asm-generic,linux,mtd,scsi,sound} )BV=|,j  
${SYSROOT}/usr/include <4?*$  
cp -a include/asm-arm ${SYSROOT}/usr/include/asm r:l96^xs  
4.4建立binutils pz}mF D&[  
mkdir -p ${TARGET_PREFIX} ,a(O`##Bn  
//建立目标交叉编译工具链安装目录 ?g  }kb  
cd ${TOP}/source nX x=1*X  
//进入源码解压目录 ;lfWu U%R  
tar -jxf ${TAR}/binutils-${BINUTILS_VERSION}.tar.bz2 !ng\` |8?  
//解压binutils 源码包到此目录 J 3?Dj  
cd binutils-${BINUTILS_VERSION} K r3];(w{  
//进入 binutils 的源码目录 LdTIR]  
patch -Np1 -i ${TAR}/binutils-${BINUTILS_VERSION}-posix-1.patch 71iRG*O  
//给binutils打补丁 |_pl;&;:  
mkdir -p ${TOP}/source/BUILD/binutils-${BINUTILS_VERSION} Sb<\-O14"  
//建立 binutils 的编译目录 7!d$M{0"  
cd ${TOP}/source/BUILD/binutils-${BINUTILS_VERSION} ,nE&Me&#J  
//进入 binutils 的编译目录 E[S':Q  
//设立汇编器的环境变量 }$)&{d G  
AR=ar &:vsc Ol  
AS=as Wvr+y!F  
//对 binutils 进行配置 d(l|hmj4j9  
${TOP}/source/binutils-${BINUTILS_VERSION}/configure zO2{.4  
--prefix=${TARGET_PREFIX} p?Sl}A@`  
--target=${CLFS_TARGET} S%+R#A1  
--with-sysroot=${SYSROOT} K\sbt7~  
--disable-nls u6_jnZGB  
--enable-shared %Dyh:h   
--disable-multilib l P0k:  
make configure-host #S?c ;3-  
//编译 binutils 9s $PrF  
make 0eA5zFU7  
make install //安装 binutils .~<]HAwq  
//复制后续编译所要的 binutils 的头文件 XtW_  
cp -v ${TOP}/source/binutils-${BINUTILS_VERSION}/include/libiberty.h (t74a E pi  
${SYSROOT}/usr/include d^SE)/j  
4.5安装Glibc 的头文件 A}4t9|/K6  
cd ${TOP}/source QN #)F  
//进入源码解压目录 GN%<"I.  
tar -jxf ${TAR}/glibc-${GLIBC_VERSION}.tar.bz2 { y/-:=S)A  
//解压 Glibc 的源码包到此目录 @W)/\AZ3  
//改变源码目录名,为了标识这份源码是为安装头文件而解压、配置、补丁的。http://crosslfs.org/view/clfs-sysroot/arm/index.html 上说的是要我们在编译安装完成每一个阶段后,把用过的源码  ~^7  
包删除,下次用到时再次解压,以免这次的补丁、配置影响下一次的编译。Garfield Trump 则采用改 sX~45u \  
变目录名的方式来实现,目的在于保留这些编译、设置过的源码,以后可以直接用这些编译过的内 s"rg_FoL  
容直接安装,不需要再次编译。因为编译是很耗时的事情。 z@`@I  
mv glibc-${GLIBC_VERSION} glibc-${GLIBC_VERSION}-headers-build 9RcM$[~  
cd glibc-${GLIBC_VERSION}-headers-build >Fh#DmQ  
//进入glibc头文件安装源码目录 |UZOAGiBg  
//下面两行是为了消除在配置glibc时 gcc 对glibc的依赖。因为这里只是为了安装头文件,并不是要配 =+(Q.LmhC  
置、编译、安装 Glibc。 6 5"uD7;  
cp configure{,.orig} &?}1AQAYg  
sed -e 's/3.4/3.[0-9]/g' configure.orig '_E c_F  
> configure 4g'}h`kh  
//解压glibc 的cpu体系支持源码包到glibc 头文件安装源码目录,因为glibc 默认是没有ARM cpu支持的 dk4D+*R  
,GNU组织专门加入了此源码包来解决此问题。 =VCQ*  
tar -jxf ${TAR}/glibc-ports-${GLIBC_VERSION}.tar.bz2 C$ hQN  
//改变cpu 体系支持源码目录为 ports ,因为glibc对所有加入的而外支持包的默认搜索目录为 ports。 KT%{G8Y@M  
mv glibc-ports-${GLIBC_VERSION} ports M%;"c?g  
//建立glibc头文件配置、安装的工作目录 >gGil|I  
mkdir -p ${TOP}/source/BUILD/glibc-${GLIBC_VERSION}-headers-build |P~q/Wff  
//进入glibc头文件配置、安装的工作目录 Avd *~  
cd ${TOP}/source/BUILD/glibc-${GLIBC_VERSION}-headers-build UC;=)  
//以下三步是为了把glibc头文件配置成支持 NPTL(linux 的新线程标准)而设立的必须条件,并把这 }(cY|  
些条件写入缓存文件(可以从下面的配置选项 --cache-file=config.cache看出) 2moIgJ   
echo "libc_cv_forced_unwind=yes" $ %;jk  
> config.cache mQnL<0_<f  
echo "libc_cv_c_cleanup=yes" W%H]Uyt  
>> config.cache 1::LN(`<  
echo "libc_cv_arm_tls=yes" \@:j  
>> config.cache i)8gCDc  
CC=gcc //指定配置使用的编译器 GM77Z.Y  
//配置glibc ;6zPiaDQ  
${TOP}/source/glibc-${GLIBC_VERSION}-headers-build/configure  "YD.=s  
--prefix=/usr Ki63Ox^O  
--host=${CLFS_TARGET} TL]bY'%  
--with-headers=${SYSROOT}/usr/include p&m ^IWD  
--cache-file=config.cache ~Q_F~0y  
make install-headers install_root=${SYSROOT} oB3q AP  
//安装 glibc头文件 \E~Q1eAJT  
cp -v bits/stdio_lim.h ${SYSROOT}/usr/include/bits p^Agh  
//复制编译后续编译所要的头文件 k|l5"&K~.  
//建立必要的地头文件,内容为空,因为这个头文件在第一阶段Gcc 编译安装时要被 check 到,但这 %-k(&T3&  
是后面编译安装目标机的glibc时才被生成安装的。 QWQ!Ak  
touch ${SYSROOT}/usr/include/gnu/stubs.h ^YqbjL  
//拷贝建立支持NPTL编译器所必须的头文件 4^`PiRGt  
cp --reply=yes ${TOP}/source/glibc-${GLIBC_VERSION}-headersbuild/ports/sysdeps/unix/sysv/linux/arm/nptl/bits/pthreadtypes.h J/= +r0c  
${SYSROOT}/usr/include/bits V3 qT<}y|  
4.6 编译安装第一阶段 arm-linux-gcc a\>+=mua  
cd ${TOP}/source t+jIHo  
//进入源码解压目录 u9 %;{:]h  
tar -jxf ${TAR}/gcc-${GCC_VERSION}.tar.bz2 G IK u  
//解压gcc源码 $>|?k$(x  
//改变源码目录,为了标识这是第一阶段用的gcc源码,目的前面说过了。 ~U/8 @gR  
mv gcc-${GCC_VERSION} gcc-${GCC_VERSION}-stage1 Pb3EnNqYbM  
cd gcc-${GCC_VERSION}-stage1 ,R8n,az  
//进入第一阶段源码目录 e{:86C!d)  
//打上支持posix 标准的补丁,新的线程标准NPTL是符合posix标准的。 :82?'aR  
patch -Np1 -i ${TAR}/gcc-${GCC_VERSION}-posix-1.patch ^z38<L=z"  
//打上交叉编译gcc搜索头文件路径的补丁 sN;(/O  
patch -Np1 -i ${TAR}/gcc-${GCC_VERSION}-cross_search_paths-1.patch xP42xv9U  
cd ${TOP}/source x Ridc^  
//进入源码解压目录 }Z^FEd"y  
mkdir -p BUILD/gcc-${GCC_VERSION}-stage1 _ \_3s  
//建立编译第一阶段gcc的工作目录 :l4^iSf  
cd BUILD/gcc-${GCC_VERSION}-stage1 MkkA{p  
//进入编译第一阶段gcc 的工作目录 #&}%70R)  
//配置第一阶段gcc。 <` #,AVH  
${TOP}/source/gcc-${GCC_VERSION}-stage1/configure =z+-l5Gu"  
--prefix=${TARGET_PREFIX} i'U,S`L6>  
--host=i686-pc-linux-gnu fmtuFr^a1  
--target=${CLFS_TARGET} tsB.oDMP  
--disable-multilib G,+xT}@wu  
--with-sysroot=${SYSROOT} -6(h@F%E  
--disable-nls bb*c+XN0  
--disable-shared }{P&idkv  
--enable-languages=c nR(#F9  
注意配置选项--enable-languages=c 和--disable-shared!!!因为这一阶段的gcc |}l@w +N3  
制作时,还没有生成其给目标机编译程序时所依赖的动态库,所以要—disable-shared,因此第一阶 22l|!B%o  
段的gcc是个静态的arm-linux-gcc。之所以只用了--enable-languages=c,而后面生成第二阶段的armlinux-gcc却用了--enable-languages=c,c++,是因为我们这一阶段的arm-linux-gcc是为了生成制作第二阶 U+:S7z@j?  
段arm-linux-gcc所依赖的glibc动态函数库而制作,编译glibc只需要arm-linux-gcc,并不需要arm-linuxg++。加上c++也是没错的。 `' dX/d  
make all-gcc //编译第一阶段gcc Bk\*0B  
make install-gcc //安装第一阶段gcc Sr4dY`V*:z  
4.7 编译安装交叉编译工具链(第二阶段arm-linux-gcc)所依赖的glibc K!pxDW}  
cd ${TOP}/source ?IL! X-xx  
//进入源码解压目录 &z7N\n  
tar -jxf ${TAR}/glibc-${GLIBC_VERSION}.tar.bz2 @hE7r-}]  
//解压glibc源码 B)_!F`9  
cd glibc-${GLIBC_VERSION} l=Vowx.$2f  
//进入源码目录  "Nk`RsW  
//解压glibc 的cpu体系支持源码包到glibc 头文件安装源码目录,因为glibc 默认是没有ARM cpu支持的 ?FkQe~FN{  
,GNU组织专门加入了此源码包来解决此问题。 #p11D= @[  
tar -jxf ${TAR}/glibc-ports-${GLIBC_VERSION}.tar.bz2 %:yHMEG]'  
//改变cpu 体系支持源码目录为 ports ,因为glibc对所有加入的而外支持包的默认搜索目录为 ports。 *?EjYI  
mv glibc-ports-${GLIBC_VERSION} ports -U/I'RDLEz  
//以下四步均为给glibc打补丁,至于是什么补丁,自己到http://cross-lfs.org/view/clfssysroot/arm/index.html看!! T2c_vY   
patch -Np1 -i ${TAR}/glibc-2.6.1-libgcc_eh-1.patch |6\FI?  
patch -Np1 -i ${TAR}/glibc-2.6.1-localedef_segfault-1.patch }dV9%0s!  
patch -Np1 -i ${TAR}/glibc-2.6.1-cross_hacks-1.patch AJJ%gxqGq  
patch -Np1 -i ${TAR}/glibc-2.6.1-RTLD_SINGLE_THREAD_P-1.patch ,Y78Q  
mkdir -p ${TOP}/source/BUILD/glibc-${GLIBC_VERSION} >\^N\&  
//建立配置、编译、安装glibc的工作目录 4WBo ZJ  
cd ${TOP}/source/BUILD/glibc-${GLIBC_VERSION} ,U} 5  
//进入配置、编译、安装glibc的工作目录 JKEXYE  
//以下三步是为了把glibc头文件配置成支持 NPTL(linux 的新线程标准)而设立的必须条件,并把这 X3&SL~&>g  
些条件写入缓存文件(可以从下面的配置选项 --cache-file=config.cache看出) *y":@T  
echo "libc_cv_forced_unwind=yes" /6Jy'"+'0  
> config.cache A8A:@-e8A  
echo "libc_cv_c_cleanup=yes" F$"MFdc[  
>> config.cache b |o`Q7Hj  
echo "libc_cv_arm_tls=yes" -(%ar%~Zd  
>> config.cache ifgr<QlG  
//指定配置使用的编译器为gcc,即本机的gcc 6Zl.Lh  
BUILD_CC="gcc" USHlb#*  
//指定编译glibc时使用第一阶段的交叉gcc,即上面生成的arm-linux-gcc YUP%K!k  
CC="${CLFS_TARGET}-gcc" UH1S_:6  
//指定汇编glibc时使用的汇编器为arm-linux-ar,即在制作binutils 时生成的交叉汇编器 URmAI8fq*M  
AR="${CLFS_TARGET}-ar" [qjAq@@N#q  
//这里我也不清楚,从环境变量命名看应该是编译时所用到的库吧!!! #w%a m`+  
RANLIB="${CLFS_TARGET}-ranlib" YokZar2a0  
//配置交叉编译工具链所依赖的动态库glibc S4aHce5PXA  
${TOP}/source/glibc-${GLIBC_VERSION}/configure =2vMw]  
--prefix=/usr 3<~2"@J  
--libexecdir=/usr/lib/glibc ,_5YaX:<4  
--host=${CLFS_TARGET} jx5[bUp4u  
--build=i686-pc-linux-gnu {8*d;[X50  
--disable-profile !?us[f=g%  
--enable-add-ons o\=i0HR9  
--with-tls :DJ7d  
--enable-kernel=2.6.0 b[&,%Sm+6  
--with-__thread U`8^N.Snrp  
--with-binutils=${TARGET_PREFIX}/bin I ]WeZ,E  
--with-headers=${SYSROOT}/usr/include P(YG@  
--cache-file=config.cache "Wn?8vR  
make //编译交叉编译工具链所依赖的动态库glibc q|]0on~ ]  
make install install_root=${SYSROOT} +{=_|3(  
//安装交叉编译工具链所依赖的动态库 n.)[MC}  
//以下的步骤是配置交叉编译工具链在使用动态库时所用的时区,语言。这里不多说了,照做就是 /v;)H#;  
了!!! EZwdx  
make localedata/install-locales -'p@ lk  
mkdir -pv ${SYSROOT}/usr/lib/locale "o5gQTwb  
export I18NPATH=${PWD}/localedata A 4W  
export GCONV_PATH=${PWD}/iconvdata ~QEXB*X-g'  
export LOCALEDEF="${PWD}/locale/localedef-native --alias-file=../intl/locale.alias" nTlv'_Y(  
cd ${TOP}/source/glibc-${GLIBC_VERSION}/localedata z kX-"}$8  
${LOCALEDEF} |au qj2  
-i locales/de_DE l3Bxi1k[C  
-f charmaps/ISO-8859-1 afP&+ 5t@O  
--prefix=${SYSROOT} de_DE wMPw/a;  
${LOCALEDEF} ==jw3_W  
-i locales/de_DE@euro gA 6h5F)_  
-f charmaps/ISO-8859-15 0@FM^ejA#  
--prefix=${SYSROOT} de_DE@euro cf[u%{ 6Y  
${LOCALEDEF} ("J V:u.L+  
-i locales/en_HK ^ yukn*L  
-f charmaps/ISO-8859-1 sG1]A:_<C  
--prefix=${SYSROOT} en_HK 4gkV]" H!  
${LOCALEDEF} T m@1q!G  
-i locales/en_PH V.gY1   
-f charmaps/ISO-8859-1 &6^W% r  
--prefix=${SYSROOT} en_PH PVkN3J  
${LOCALEDEF} -C'X4C+  
-i locales/en_US FskJyB[  
-f charmaps/ISO-8859-1 :rs\ydDUF  
--prefix=${SYSROOT} en_US .dKRIFo  
${LOCALEDEF} FG5c:Ep  
-i locales/es_MX )Y,?r[4{  
-f charmaps/ISO-8859-1 `2mbF ^-4  
--prefix=${SYSROOT} es_MX xjhAAM  
${LOCALEDEF} %}ApO{  
-i locales/fa_IR gM5p1?E  
-f charmaps/UTF-8 P7k$^n  
--prefix=${SYSROOT} fa_IR Y7t{4P  
${LOCALEDEF} };|PFWs  
-i locales/fr_FR _hyxKrm' 6  
-f charmaps/ISO-8859-1 , w'$T)  
--prefix=${SYSROOT} fr_FR C8W`Oly:]  
${LOCALEDEF} gUszMhHX  
-i locales/fr_FR@euro ,fG_'3wb  
-f charmaps/ISO-8859-15 S. F=$z.%  
--prefix=${SYSROOT} fr_FR@euro  ~!d)J  
${LOCALEDEF} Nb!6YY=Ez-  
-i locales/it_IT #HuA(``[d  
-f charmaps/ISO-8859-1 UrcN?  
--prefix=${SYSROOT} it_IT nC!^,c  
${LOCALEDEF} G* ~*2>~  
-i locales/ja_JP HJ1\FO9\  
-f charmaps/EUC-JP T!xy^n]}  
--prefix=${SYSROOT} ja_JP '-]BSU  
unset I18NPATH GCONV_PATH LOCALEDEF .nF  
/************************ 下面是配置动态库的使用环境文件 照做!!!******************/ Fx99"3`3  
cat > ${SYSROOT}/etc/nsswitch.conf &aAo:pj  
<< Vv)E41  
"EOF" S@G{|.)2  
# Begin /etc/nsswitch.conf a={qA4N  
passwd: files "X(=  
group: files B{UoNm@  
shadow: files I nK)O ';  
hosts: files dns ftU5 A@(T  
networks: files %PdYv _5  
protocols: files r\ Yur  
services: files f uN XY-;  
ethers: files $z,DcO.vz  
rpc: files Ru')X{]25  
# End /etc/nsswitch.conf  <IDzv'  
EOF g?AqC  
TZDIR="${SYSROOT}/usr/share/zoneinfo" HeifFJn  
${SYSROOT}/usr/bin/tzselect k\<Ln w  
cp -v --reply=yes ;,-Vapz  
--remove-destination ${SYSROOT}/usr/share/zoneinfo/America/New_York eL?si!ZL^  
${SYSROOT}/etc/localtime qq_,"~  
cat > ${SYSROOT}/etc/ld.so.conf \Y[)bo6s  
<< Hpg;?xAT  
"EOF" Y <k,E  
# Begin /etc/ld.so.conf :QL p`s  
/usr/local/lib M*6@1.n  
/opt/lib N_Ld,J%g  
# End /etc/ld.so.conf [=F |^KL  
EOF ;/q6^Nk3A  
4.8 第二阶段的gcc 制作。 v!h-h&p O7  
即制作依赖上一阶段生成的glibc ({nSs5)$  
的arm-linux-gcc等一系列交叉编译工具,统称交叉编译工具链。这里已经是交叉编译工具链生成的最 [IBk-opap  
后一步了,恭喜你!!! KmOa^vY1.T  
cd ${TOP}/source 5 t?2B]  
//进入源码解压目录 V"jnrNs3  
tar -jxf ${TAR}/gcc-${GCC_VERSION}.tar.bz2 B]F7t4Y!  
//解压gcc源代码 l4reG:uYG  
//改名源码目录,为了标识这是编译第二阶段的gcc 所用的源码 R./6Q1  
mv gcc-${GCC_VERSION} gcc-${GCC_VERSION}-stage2 h:sG23@=  
cd gcc-${GCC_VERSION}-stage2 `80Hxp@  
//进入源码目录 Iw7r}G  
//打上支持posix 标准的补丁,新的线程标准NPTL是符合posix标准的。 f:&OOD o  
patch -Np1 -i ${TAR}/gcc-${GCC_VERSION}-posix-1.patch gK\7^95  
//打上交叉编译gcc搜索头文件路径的补丁 azc:C  
patch -Np1 -i ${TAR}/gcc-${GCC_VERSION}-cross_search_paths-1.patch ~'.yhPo g  
cd ${TOP}/source r+p jv_R  
//进入源码解压目录 8vW`E_n  
mkdir -p BUILD/gcc-${GCC_VERSION}-stage2 bu&y w~  
//建立第二阶段gcc的编译工作目录 xF|*N<9(</  
cd BUILD/gcc-${GCC_VERSION}-stage2 {leG~[d  
//进入第二阶段gcc的编译工作目录 jUSr t)o03  
//配置第二阶段交叉编译工具链 v nC&1  
${TOP}/source/gcc-${GCC_VERSION}-stage2/configure i4rF~'h@  
--prefix=${TARGET_PREFIX} l8Qi^<i/  
--host=i686-pc-linux-gnu :?k=Yr  
--target=${CLFS_TARGET} S Tk#hhx  
--disable-multilib 2<@!m @  
--with-sysroot=${SYSROOT} Y{tuaBzD  
--disable-nls V <pjR@  
--enable-shared kk+8NwM1  
--enable-languages=c,c++ ZhaOH5{9  
--enable-__cxa_atexit (k&aD2PH  
--enable-c99 !OgoV22  
--enable-long-long hAyPaS#  
--enable-threads=posix |R/50axI  
make all-gcc //编译第二阶段交叉编译工具链 TN`:T.B  
make install-gcc install_root=${TARGET_PREFIX} ,`@|C Z-4A  
//安装交叉编译工具链 Z"+!ayA7D  
《五》疑难解答: cSk}53  
5.1 第一阶段gcc 跟第二阶段 gcc ,一个是静态一个是动态,那么是在哪里指定了第二阶段gcc是跟动 MV \zwH  
态函数库关联,而且是关联到哪个动态库,怎样关联到我们制作出来的动态库呢? <5~>.DuE  
答: @ RBwT  
1、比较两次的配置参数 6|}mTG^  
Gcc stage1: 7*"LW  
configure --prefix=${TARGET_PREFIX} --host=i686-pc-linux-gnu --target=${CLFS_TARGET} --disablemultilib N@0scfO6<  
--with-sysroot=${SYSROOT} --disable-nls x)L@x Q  
--disable-shared --enable-languages=c #sZes  
Gcc stage2: P,_E 4y  
configure --prefix=${TARGET_PREFIX} --host=i686-pc-linux-gnu --target=${CLFS_TARGET} --disablemultilib J[wXG6M  
--with-sysroot=${SYSROOT} --disable-nls 5-^twXC&  
--enable-shared --enable-languages=c,c++ --enable-__cxa_atexit --enable-c99 --enable-long-long --enablethreads=posix ayp}TYh*  
2、因为指定了--with-sysroot=${SYSROOT} 那么编译时就会以该目录为系统根目录作为动态共享函数 \]%U?`A  
库目录、头文件存放目录的顶层搜索目录。如果--enable-shared G].KJ5,y  
就会在该目录下搜索lib目录、usr/lib目录下的动态共享函数库文件,并在该目录下搜索include 目录、 }L9j`17  
/usr/include目录中的头文件。这样只要我们把我们制作的glibc指定安装到${SYSROOT},制作出来的 @CF4:NNHw  
交叉编译器就会关联到我们的glibc,并且在以后使用这个交叉编译器编译程序时,编译器就会到 _AYF'o-Cm  
${SYSROOT}下关联我们制做的动态函数库,查找用户程序所使用的Linux内核头文件。但如果使用-- {H2i+"cF  
disable-shared参数,就不会去搜索一切${SYSROOT}下的动态函数库文件夹,来关联动态函数库文件 54w-yY  
了。   \/v$$1p2  


评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

一般

差劲

性别:
帅哥
发帖
14148
金币
14671
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 1楼 发表于: 2016-10-13
       辛苦了


离线吖勉

性别:
帅哥
发帖
303
金币
1
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 2楼 发表于: 2016-10-13
谢谢分享liao


离线desig

性别:
人妖
发帖
2209
金币
446
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 3楼 发表于: 2016-10-13
这个好,支持钻研



性别:
帅哥
发帖
1784
金币
2294
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 4楼 发表于: 2016-10-14
看看,学习下!


离线medymat

性别:
人妖
发帖
28
金币
10
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 5楼 发表于: 2016-10-14
学习中,感谢分享。


在线tiny2010

性别:
人妖
发帖
7095
金币
8986
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看该作者 6楼 发表于: 2020-11-26
  


快速回复
限150 字节
 
上一个 下一个