首先简单介绍一下,所谓的搭建交叉编译环境,即安装、配置交叉编译工具链。在该环境下编译出嵌入式Linux系统所需的操作系统、应用程序等,然后再上传到目标机上。
交叉编译工具链是为了编译、链接、处理和调试跨平台体系结构的程序代码。对于交叉开发的工具链来说,在文件名称上加了一个前缀,用来区别本地的工具链。例如,arm-linux-表示是对arm的交叉编译工具链;arm-linux-gcc表示是使用gcc的编译器。除了体系结构相关的编译选项以外,其使用方法与Linux主机上的gcc相同,所以Linux编程技术对于嵌入式同样适用。不过,并不是任何一个版本拿来都能用,各种软件包往往存在版本匹配问题。例如,编译内核时需要使用arm-linux-gcc-4.3.3版本的交叉编译工具链,而使用arm-linux-gcc-3.4.1的交叉编译工具链,则会导致编译失败。
那么gcc和arm-linux-gcc的区别是什么呢?区别就是gcc是linux下的C语言编译器,编译出来的程序在本地执行,而arm-linux-gcc用来在linux下跨平台的C语言编译器,编译出来的程序在目标机(如ARM平台)上执行,嵌入式开发应使用嵌入式交叉编译工具链。
交叉编译器的安装方法,通常交叉编译器的打包发布方式有关:
>> 如果以 deb 包形式发布,则需要用 dpkg 命令进行安装。示例命令:
host$ dpkg -i package.deb
>>如果以 bin 方式打包发布,通常则需要为该文件加上可执行权限,然会运行这个文
件,完成安装。示例命令:
host$ chmod +x package.bin
host$ ./package.bin
>>如果以.tar.bz2 压缩包方式发布,则只需在某个目录下进行解压即可。
host$ tar xjvf package.tar.bz2
以上 3 条命令中,在实际中须将 package 替换为实际文件名称。
由于以 deb 或者 bin 方式发布的工具链对不同版本的操作系统适应性较差,所以大多数
都采用.tar.bz2 这样的压缩包形式发布,下面重点讲述这种工具链的安装方法。
1.下载arm-linux-gcc-3.4.1.tar.bz2到任意的目录下,我把它下载到了我的个人文件夹里 /home/satellite
arm-linux-gcc-3.4.1.tar.bz2 的下载地址如下:
http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2
2. 解压 arm-linux-gcc-3.4.1.tar.bz2
#tar -jxvf arm-linux-gcc-3.4.1.tar.bz2
3. 修改环境变量,把交叉编译器的路径加入到PATH。
方法一:临时设置系统环境变量,是通过 export 命令,将交叉编译器的路径添加到系统 PATH 环境变量中。用法(多个值之间用冒号隔开):
host$ export PATH=$PATH:/交叉编译器路径
紧接前面这个示例,在添加交叉编译器路径前,先查看系统 PATH 的值:
chenxibing@linux-compiler: ~$ echo $PATH
/home/chenxibing/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
添加工具链路径:
$ export PATH=$PATH:/home/ctools/arm-2011.03/bin/
再次查看 PATH 的值:
chenxibing@linux-compiler: ~$ echo $PATH
/home/chenxibing/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: /home/
ctools/arm-2011.03/bin/
可以看到,交叉编译器的路径已经被添加到系统 PATH 变量中。此时在终端输入arm-none-linux-gnueabi-,然后按键盘 TAB 键,可以看到很多 arm-none-linux-gnueabi-开头的
命令被列了出来,说明系统已经能够正确找到交叉编译器了。
chenxibing@linux-compiler: ~$ arm-none-linux-gnueabiarm-none-linux-gnueabi-addr2line arm-none-linux-gnueabi-cpp arm-none-linux-gnueabi-gcov
arm-none-linux-gnueabi-nm arm-none-linux-gnueabi-size arm-none-linux-gnueabi-ar
arm-none-linux-gnueabi-elfedit arm-none-linux-gnueabi-gdb arm-none-linux-gnueabi-objcopy
arm-none-linux-gnueabi-sprite arm-none-linux-gnueabi-as arm-none-linux-gnueabi-g++
arm-none-linux-gnueabi-gdbtui arm-none-linux-gnueabi-objdump arm-none-linux-gnueabi-strings
arm-none-linux-gnueabi-c++ arm-none-linux-gnueabi-gcc arm-none-linux-gnueabi-gprof
arm-none-linux-gnueabi-ranlib arm-none-linux-gnueabi-strip arm-none-linux-gnueabi-c++filt
arm-none-linux-gnueabi-gcc-4.5.2 arm-none-linux-gnueabi-ld arm-none-linux-gnueabi-readelf
这种方法设置环境变量,只能对当前终端有效,关闭终端再次打开将会失效,需要重新设置。
方法二:修改全局配置文件
然后输入“. /etc/profile”(点+空格+文件名),执行 profile 文件,使刚才的改动生效。如果没有书写错误,此时打开终端,输入 arm-none-linux-gnueabi-,然后按键盘 TAB 键,同样可以看到很多 arm-none-linux-gnueabi-开头的命令。
方法三:修改用户配置文件
“/etc/profile”是全局配置文件,会影响登录本机的全部用户。如果不希望影响其他用户,也可以只修改当前用户的配置文件,通常是“~/.bashrc”或者“~/.bash_profile”。
修改方法与修改“/etc/profile”类似,这是无需 sudo,直接 vi 打开即可,在文件末尾增加:
export PATH=$PATH:/home/ctools/arm-2011.03/bin/
与执行“/etc/profile”的方式一样,输入“. .bashrc”或者“. .bash_profile”,执行修改过的文件,使修改生效。如果无误,打开终端,输入 arm-none-linux-gnueabi-,然后按键盘 TAB键,同样可以看到很多 arm-none-linux-gnueabi-开头的命令。
4. 立即使新的环境变量生效,不用重启电脑:
对应方法一:#source /root/.bashrc
对应方法二:# source /etc/profile
5. 检查是否将路径加入到PATH:
# echo $PATH
显示的内容中有/usr/local/arm/bin,说明已经将交叉编译器的路径加入PATH。至此,交叉编译环境安装完成。
6. 测试是否安装成功
# arm-linux-gcc -v
上面的命令会显示arm-linux-gcc信息和版本
7.编译
Hello World程序,测试交叉工具链
写下下面的Hello World程序,保存为
hello.c
#include
int main()
{
printf("Hello World!\n");
return 0;
}
执行下面的命令:
# arm-linux-gcc -o hello hello.c
源程序有错误的话会有提示,没有任何提示的话,就是通过了,就可以下载到ARM目标板上运行了!接着可以输入file hello的命令,查看生成的hello文件的类型,要注意的是生成的可执行文件只能在ARM体系下运行,不能在其于X86的PC机上运行。
但是事情总有例外,很有可能在终端输入
arm-none-linux-gnueabi-gcc 命令后,得到的却是下面的结果:
-bash: ./arm-none-linux-gnueabi-gcc: 没有那个文件或目录
此时请确认:
(1) 在某个目录下确实存在 arm-none-linux-gnueabi-gcc 文件;
(2) 在终端输入 arm-none-linux-gnueabi-,按 TAB 键,能找到 arm-none-linux-gnueabi-*系列命令。
如果这两个条件都确认无误,那么问题就好解决了。这种问题主要发生在 64 位操作系统上,原因在于大多数交叉编译器为了适应性,通常以 32 位发布,而实际系统是 64 位的,存在架构差异,所以不能执行。解决办法很简单,安装 32 位兼容库就好了。在 Ubuntu 12.04 上的安装命令:
$sudo apt-get install ia32-libs
>> 32 兼容库需要从 Ubuntu 的源下载,所以此时主机系统应当能访问互联网。
>> 在 Ubuntu 12.04 64 位下安装 32 位库的名字为 ia32-libs,在其它版本的 Ubuntu名称可能有变