您的位置:首页 > 运维架构 > Linux

arm linux uclibc交叉编译工具链的制作

2013-12-26 11:28 477 查看
原文地址:http://blog.csdn.net/chehlcy/article/details/5456118(本人经过整理修改,并且对可能出现的问题给出解决方案)

制作交叉编译工具链是件麻烦的事情,因为交叉编译ntfsprogs不得已从头做了一遍,现在把流程总结在这里,供以后参考。

原料:binutils,gcc,linux kernel,uclibc

我所用的版本为:

binutils-2.16

gcc-3.4.3

linux-2.6.14

uClibc-0.9.28

基本流程:

1.编译binutils

2.编译不含库的gcc

3.配置编译linux kenerl

4.编译uclibc

5.重新编译gcc得到完整工具链。

详细步骤:

注:以下脚本都是手工再次录入,非copy自原系统,可能存在录入错误
1.binutils的编译

没有什么悬念,编译脚本如下:

#!/bin/sh

./configure --target=arm-linux --prefix=/opt/tools --program-prefix=arm-linux-

make

make install

即可在/opt/tools 下生成arm-linux-ar arm-linux-ld等必须工具
2.编译不含库的gcc

该步骤必须小心配置,因为编译gcc某些功能模块时本身需要C库的支持,只有把这些有依赖的模块屏蔽掉该步骤才能顺利编译,该步骤编译脚本如下:

具体可以参见:http://blog.csdn.net/dragon101788/article/details/17559215第四节

#!/bin/sh

./configure --target=arm-linux /

                 --prefix=/opt/tools /

                 --program-prefix=arm-linux- /

                 --disable-shared   /

                 --disable-threads  /

                 --enable-languages="c" /

                 --with-newlib

make

make install

 

部分书籍说要修改t-linux文件,本人测试只要加上--with-newlib即可避免。
3.配置编译linux kernel

具体可以参见:http://blog.csdn.net/dragon101788/article/details/17559215第五节

该步骤是为了得到C库中的系统头文件,在编译uClibc的时候会指定kernel src的位置,这一步虽然只需配置好内核并将include/asm  链接到asm-arm即可,但为了顺便测试第2步编译的gcc,不妨完整的编译内核。具体配置取决于所使用的内核,此步骤无需罗嗦。

4.配置编译uClibc

在该步骤中需要指定kernel src的位置,个人尝试必须指定为绝对路径,相对路径编译过程会出错,配置过程中需根据系统需要对uClibc进行配置,有时还会出现部分模块编译不通过,此时则需要做相应配置调整。该步骤完成后可生成完整工具链所需的头文件和库文件。

menuconfig设置:
arget Architecture (arm)  --->       

Target Architecture Features and Options  --->

    Target ABI (EABI)  --->                                                                    

           Target Processor Type (Generic Arm)  --->                                                  

           *** Using ELF file format ***                                                              

            Target Processor Endianness (Little Endian)  --->                                          

            [*] Target CPU has a memory management unit (MMU)                                            

           [*]   Do you want to utilize the MMU?                                                            

            [*] Enable floating point number support        

           [*]   Target CPU has a floating point unit (FPU)                

           [ ]   Enable full C99 math library support                                      

            [ ]   Enable C99 Floating-point environment                                          

            (${PREFIX}/${TARGET}/include) Linux kernel header location   

Library Installation Options  ---> 

           ($(RUNTIME_PREFIX)lib) Shared library loader path          

           (/${TARGET}/uClibc) uClibc runtime library directory             :注:此项如若填写,每次编译时会从指定目录寻找ulibc.so,如若没有填写,从默认加载路径,推荐留空

           (/uClibc-dev) uClibc development environment directory     :注:此项如若填写,每次编译时会从指定目录寻找ulibc.so,如若没有填写,从默认加载路径,推荐留空

修改.config中的交叉编译路径 或者修改环境变量CROSS=

CROSS_COMPILER_PREFIX="arm-linux-gnueabi-"

安装时使用命令

make PREFIX=${PWD}/hu/ install

编译完成安装之后将hu目录下所有文件拷贝到${PREFIX}/${TARGET}目录

注:如果menu时使用目录有填写的话安装时会出现在配置目录

编译中可能会遇到的问题:

问题1:

libc/sysdeps/linux/mips/crt1.S: Assembler messages:

libc/sysdeps/linux/mips/crt1.S:117: Warning: No .cprestore pseudo-op used in PIC code

  AS lib/crti.o

  AS lib/crtn.o

/tmp/cc5bCHrL.s: Assembler messages:

/tmp/cc5bCHrL.s: Error: .size expression for _init does not evaluate to a constant

/tmp/cc5bCHrL.s: Error: .size expression for _fini does not evaluate to a constant

make: *** [lib/crtn.o] Error 1

解决方法:

Got the thing resolved as said in the patch by removing the lines

.size _init, .-_init

.size _fini, .-_fini

from uClibc-0.9.31/libc/sysdeps/linux/arm/crtn.S

在uClibc-0.9.31/libc/sysdeps/linux/arm/crtn.S文件中,@注掉这两行

问题2:

错误:651: note: previous declaration of ‘getline’ was here

error: conflicting types for ‘getline’

651: note: previous declaration of ‘getline’ was here
pattern.c: In function ‘getline’:

解决:getline和系统定义的getline()函数冲突。把名字改一下就好了。

5.重新编译GCC

此步骤是为了在已经拥有C库的基础上打开第一遍编译gcc时限定的功能,包括动态链接支持,线程支持等,以及C库的整合。

编译脚本如下:

#!/bin/sh

./configure --target=arm-linux /

                  --prefix=/opt/tools /

                  --program-prefix=arm-linux- /

                  --enable-languages="c"   /

                  --with-headers=../uClibc-0.9.28/build/include /           #注:此处加上编译出现问题

                  --with-libs=../uClibc-0.9.28/build/lib /                          #注:此处加上编译出现问题

 --with-sysroot='${exec_prefix}/xxx' #将xxx替换成prefix的路径,参照http://blog.csdn.net/dragon101788/article/details/17509987sysroot与specs

make

make install

可能会出现问题:

 /home/dragon/usr/arm/dragon-4.8.2/arm-uclibc-linux-gnueabi/bin/ld: cannot find /lib/libc.so.0

/home/dragon/usr/arm/dragon-4.8.2/arm-uclibc-linux-gnueabi/bin/ld: cannot find /lib/uclibc_nonshared.a

/home/dragon/usr/arm/dragon-4.8.2/arm-uclibc-linux-gnueabi/bin/ld: cannot find /lib/ld-uClibc.so.0

collect2: error: ld returned 1 exit status

这进过研究这是uclibc链接中指向了错误的根目录下/lib/libc.so.0

实际是$PREFIX/$TARGET/lib/libc.so的指向,libc.so其实是一个文本文件指向这编译时链接的位置,当编译器移动位置时出现同样的问题,后期可以通过修改这个文件来移动目录,ulibc编译器目录移动时指定一个绝对路径

其中--with-headers指定刚才编译生成的uClibc的头文件,--with-libs指定uClibc的库文件,本例中只支持c程序的编译。

不出意外的话,一个arm-linux的交叉编译工具链就完成了,在这个流程顺利通过的基础上,可以再配置的其它参数以达到性能最优。不过,第一次编译工具链几乎不可能一次成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: