在GNU 系统中,每个目标平台都有一个明确的格式,这些信息用于在构建过程中识别要用的不同工具的正确版本,因此,在一个特定目标机下运行gcc 时,gcc 便在目录路径中查找包含目标规范的应用程序路径,GNU 的目标规范格式为CPU-PLATFORM-OS。 例如x86/i386目标机名为“i686-pc-linux-gnu”,通常gcc、gdb 所编译链接生成的可执行文件只能在PC 机上运行,而要想编译生成可在ARM 处理器的嵌入式目标中运行,则要用基于ARM 平台的交叉工具链。 这里将其目标平台名改为“arm-linux-gnu”,比如arrn-linux-gcc、arm-linux-gdb 等。
以前,arm-linux-gcc 这样的交叉编译工具需要每个项目组自己编译建立,能成功地编译一套交叉开发工具链(即建立起交叉开发环境)很不容易。 而现在随着开源思路的发展,网上有着很多针对ARM、MIPS、PowerPc 等各种处理器的交叉开发工具链下载。 这里,为了让读者对交叉开发工具链能更好地理解,下面分步详细介绍构建交叉开发工具链的整个过程。
(1)下载源代码
到相关的网站下载包括binutils、gcc、glibc(如ftb.gnu.org)和Linux(如ftb.kernel.org)内核的源代码。 注意: glibc 和内核源代码的版本必须与目标机上实际使用的版本保持一致。
(2)建立环境变量
声明以下环境变量的目的是在之后的编译工具库时用到,方便输入,尤其是可以降低输错路径的风险。 其代码如下:
(3)配置、安装binutils
binutils 是GNU 工具之一,它包括链接器、汇编器和其他用于目标文件和档案的工具。 它是二进制代码的维护工具。 安装binutils 工具包含的程序有addr2line、ar、as、c + +filt、gprof、ld、mm、objcopy、ranlib、readelf、size、strings、strip、libiberty、libbfd 和lib opcodes。
首先,运行configure 文件,对binutils 进行配置:
#... /binutils-*.**/configure-target=$TARGET-prefix=$ PREFIX
其中,-target= arm-linux 参数指定目标机类型; -prefix=$ PREFIX 参数指定可执行文件的安装路径。
然后,执行make install:
#make
#make install
(4)配置Linux 内核头文件
编译器需要通过系统内核的头文件来获得目标平台所支持的系统函数调用所需要的信息。 对于Linux 内核,最好的方法是下载一个合适的内核,然后复制获得头文件。
首先,执行make mrproper 进行清理工作。 接下来执行make config ARCH=arm(或Make menuconfig/xconfig ARCH=arm)进行配置:
#make ARCH=arm CROSS_COMPILE=arm-linux-menuconfig
其中,ARCH =arm 表示是以ARM 为体系结构;CROSS_COMPILE =arm-linux-表示是以arm-linux 为前缀的交叉编译器。
注意:一定要在命令行中使用ARCH=arm 指定CPU 架构,因为缺省架构为主机CPU 架构,这一步需要根据目标机的实际情况进行详细的配置。
配置完成之后,需要将内核头文件复制到安装目录:
Cp-dR include/asm-arm $ PREFIX/arm-linux/include/asm
Cp-dR include/linux $ PREFIX/arm-linux/include/linux
(5)第一次编译gcc
完成此过程需要执行三个步骤。(www.xing528.com)
1)修改t-linux 下的内容
由于是第一次安装ARM 交又编译工具,没有支持libc 库头文件,所以在gcc/config/arm/t-linux 文件中给变量TARGET_LiBgcc2_CFLAGS 添加操作参数选项-Dinhibit_libc 和D_gthrposix_h 来屏蔽使用头文件,否则一般默认会使用/usr/include 头文件。
#gedit gcc/config/arm/t-linux
将TARGET_LIBgcc2_CFLAGS=-fomit-frame-pointer-fPIC 改为TARGET_LIBgcc2_CFLAGS=-fomit-frame-pointer-fPIC-Dinhibit_libc-D_gthr_posix_h。
2)配置gcc
使用如下命令对gcc 进行配置:
其中,-prefix= $ PREFIX 参数,指定安装路径;-target = arm-linux 参数,指定目标机类型;-disable-threads 参数,表示去掉threads 功能,该功能需要glibc 的支持;-disable-shared 参数,表示只进行静态库编译,不支持共享库编译;-enable-languages = c 参数,表示只支持C语言。
3)编译、安装gcc
使用如下命令安装gcc:
执行完这一步后,将生成一个最简的gcc。 由于编译整个gcc 是需要目标机的glibc 库的,它现在还不存在,因此,需要首先生成一个最简的gcc,它只需要具备编译目标机glbc 库的能力即可。
(6)交叉编译glib
这一步骤生成的代码是针对目标机CPU 的,因此,它属于一个交叉编译过程,该过程要用到Linux 内核头文件,默认路径为$PREFIX/arm/linux/sys-linux,因而需要在$PREFIX/armlinux 中建立一个名为“sys-linux”的软链接,使其内核头文件所在的include 目录,或者也可以在接下来要执行的configure 命令中使用-with-headers 参数指定Linux 内核头文件的实际路径。 具体操作如下:
首先,设置configure 的运行参数(因为是交叉编译,所以要将编译器变量CC 设为armlinux gcc);CC =arm-linux-gcc. /configure-prefix =$ PREFIX/arm-linux-host =$ TARGET-enable-add-ons-with-headers=$TARGET_PREFIX/include
其中,CC =arm-linux-gcc 是将CC 变量设成刚编译完的gcc,用它来编译glibc;$ PREFIX/arm-linux 定义了一个目录,用于安装一些与目标机器无关的数据文件:-enable-add-ons 告知glibc 用linuxthreads 包:-with-headers 告知glibc linux 内核头文件的目录位置。
接下来就是编译、安装glibc。 使用的命令为:
#make
#make install
(7)第二次编译gcc
由于第一次安装的gcc 没有交叉glibc 支持,现在已经安装了glibc,所以需要重新编译来支持glibc。 具体操作如下:
到此为止,整个交叉开发工具链就完全生成了。
注意事项:
①在第一次编译gcc 时,可能会出现找不到stdio.h 的错误,解决办法是修改gcc/config/arm/t-linux 文件,在TARGET_LIBgcc2_CFLAGS 变量的设定中增加-Dinhibit-libc 和D_ gthr_posix_h。
②对与2.3.2 版本的glibc 库,编译linuxthread/sysdeps/pthread/sigaction. c 时可能出错,需要通过补丁glibc-2.3.2-arm.patch 解决,执行patch-pl<gibc2.3.2arm.patch。
③第二次编译gcc 时,可能会出现libc. so 的错误,这时需要利用文本编辑器手动修改libc.so。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。