• 沒有找到結果。

用 Crosstool 工具构建交叉工具链

第 2 章 交叉编译工具链的构建

2.2 ARM L INUX 交叉编译工具链的构建

2.2.2 用 Crosstool 工具构建交叉工具链

printf(“Hello,world!\n”);

return 0;

}

通过以下命令进行编译,编译后生成名为 hello 的可执行文件。通过 file 命令可以查看 文件的类型。具体操作如下,当显示以下信息时表明交叉工具链正常安装了,通过以下的编 译生成了 ARM 体系可执行的文件。注意,通过该交叉编译链编译的可知性文件只能在 ARM 体系下执行,不能在基于 X86 的普通 PC 上执行该文件。

# arm-linux-gcc –o hello hello.c

# file hello

hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), for GNU/Linux 2.4.3, dynamically linked (uses shared libs), not stripped

2.2.2 用 Crosstool 工具构建交叉工具链

Crosstool 是一组脚本工具集,构建和测试不同版本的 gcc 和 glibc,用于那些支持 glibc

的许多体系结构。它也是一个开源项目,下载地址是:http://kegel.com/crosstool。用 Crosstool 构建交叉工具链要比上述的分步编译要容易得多,并且也方便许多,对于仅仅为了工作需要 构建交叉编译工具链的读者建议使用此方法。用 Crosstool 工具构建所需资源如表 2.2 所示。

表 2.2 所需资源

安装包 下载地址

crosstool-0.42.tar.gz http://kegel.com/crosstool linux-2.6.10.tar.gz ftp.kernel.org

binutils-2.15.tar.bz2 ftp.gnu.org gcc-3.3.6.tar.gz ftp.gnu.org glibc-2.3.2.tar.gz ftp.gnu.org glibc-linuxthreads-2.3.2.tar.gz ftp.gnu.org linux-libc-headers-2.6.12.0.tar.bz2 ftp.gnu.org

2.2.2.1 准备资源文件

首先从网上下载所需资源文件:linux-2.6.10.tar.gz,binutils-2.15.tar.bz2,gcc-3.3.6.tar.gz,

glibc-2.3.2.tar.gz ,glibc-linuxthreads-2.3.2.tar.gz 和 linux-libc-headers-2.6.12.0.tar.bz2。然后将 这些工具包文件放在新建的/home/mike/downloads 目录下,最后在/home/mike 目录下解压 crosstool-0.42.tar.gz,命令如下:

# cd /home/mike

# tar –xvzf crosstool-0.42.tar.gz

2.2.2.2 建立脚本文件

接着需要建立自己的编译脚本,起名为 arm.sh,为了简化编写 arm.sh,寻找一个最接近 的脚本文件 demo-arm.sh 作为模版,然后将该脚本的内容复制到 arm.sh,修改 arm.sh 脚本,

具体操作如下:

# cd crosstool-0.42

# cp demo-arm.sh arm.sh

# vi arm.sh

修改后的 arm.sh 的脚本内容如下:

#!/bin/sh set -ex

TARBALLS_DIR=/home/mike/downloads # 定义工具链源码所存放位置。

RESULT_TOP=/opt/crosstool # 定义工具链的安装目录 export TARBALLS_DIR RESULT_TOP

GCC_LANGUAGES="c,c++" # 定义支持 C, C++语言 export GCC_LANGUAGES

# 创建/opt/crosstool 目录 mkdir -p $RESULT_TOP

# 编译工具链,该过程需要数小时完成。

eval `cat arm.dat gcc-3.3.6-glibc-2.3.2.dat` sh all.sh --notest echo Done.

2.2.2.3 建立配置文件

在 arm.sh 脚本文件中需要注意 arm.dat 和 gcc-3.3.6-glibc-2.3.2.dat 两个文件,这两个文 件是作为 crosstool 的编译的配置文件。其中 arm.dat 文件内容如下,主要用于定义配置文件,

定译生成编译工具链的名称以及定义编译选项等。

KERNELCONFIG=`pwd`/arm.config # 内核的配置 TARGET=arm-linux- # 编译生成的工具链名称 TARGET_CFLAGS="-O" # 编译选项

gcc-3.3.6-glibc-2.3.2.dat 文件内容如下,该文件主要定义编译过程中所需要的库以及它 定义的版本,如果当在编译过程中发现有些库不存在时,crosstool 会自动在相关网站上下载,

该工具在这点上相对非常智能,也非常有用。

BINUTILS_DIR=binutils-2.15 GCC_DIR=gcc-3.3.6

GLIBC_DIR=glibc-2.3.2

GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2 LINUX_DIR=linux-2.6.10

LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0

2.2.2.4 执行脚本

将 Crosstool 的脚本文件和配置文件准备好之后,开始执行 arm.sh 脚本来编译交叉变异 工具。具体执行命令如下:

# cd crosstool-0.42

# ./arm.sh

经过数小时的漫长编译之后,会在/opt/crosstool 目录下生成新的交叉编译工具,其中包 括以下内容:

arm-linux-addr2line arm-linux-g++ arm-linux-ld arm-linux-size arm-linux-ar arm-linux-gcc arm-linux-nm arm-linux-strings arm-linux-as arm-linux-gcc-3.3.6 arm-linux-objcopy arm-linux-strip arm-linux-c++ arm-linux-gccbug arm-linux-objdump fix-embedded-paths arm-linux-c++filt arm-linux-gcov arm-linux-ranlib

arm-linux-cpp arm-linux-gprof arm-linux-readelf

2.2.2.5 添加环境变量

然后将生成的编译工具链路径添加到环境变量 PATH 上去,添加的方法是在系统/etc/

bashrc 文件中添加下面一行在文件的最后,如图 2.2 所示。

export PATH=/opt/crosstool/gcc-3.3.6-glibc-2.3.2/arm-linux/bin:$PATH

图 2.2 用 Vi 编辑器在 bashrc 文件中添加环境变量

设置完环境变量,也就意味着交叉编译工具链已经构建完成,然后就可以用 2.2.1.8 节 中的方法进行测试刚刚建立的工具链,此处就不用再赘述。

2.3 本章小节

本章讲述的内容非常有实用价值,因为交叉工具链的构建是嵌入式系统开发必不可少的 一部分,也是嵌入式系统开发的基础。本章首先对交叉工具链进行了大体地介绍,然后分别 介绍两种构建交叉工具链的方法:分步构建法和 Crosstool 工具构建法。这两种构建交叉工 具链的方法在实际应用中非常广泛,相信读者通过学习本章的内容可以构建一套自己的交叉 编译工具链。下一章将介绍嵌入式系统的启动程序——Bootloader。

2.4 常见问题

1.编译 boot-trap gcc 时出现如下图 2.3 错误,提示:crti.o: No such file: No such file or directory collect2: ld returned 1 exit status,为什么?

图 2.3:gcc 工具编译出错界面

参考答案:由于在配置时没有选择 --disable-shared 选项,该选项的意思是只编译静态库。

默认选项为--enable-shared,而 libf2c 和 libiberty 不支持共享库。

2.Glibc 里面静态库和共享库有什么区别?

参考答案:应用程序在链接静态库时,会把引用到的数据和代码放到生成的可执行文件中,

程序运行时就不再需要库了。应用程序链接共享库时,连接器不会把引用到的数据和代码放 到可执行文件中,而仅仅做一个标记,当程序运行时,系统会去加载相应的共享库。链接共 享库时,可执行文件的大小会小一些,但运行时依赖于共享库。起动静态库和共享库的方法 分别是在配置时用 –disable-shared 和—enable-shared 选项。

3.本地编译器与交叉编译器的作用?

参考答案:编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环 境下运行的目标代码,这种编译器叫做本地编译器。另外,编译器也可以生成用来在其它平 台上运行的目标代码,这种编译器又叫做交叉编译器。交叉编译器在生成新的硬件平台时非 常有用。