本地编译:即在当前目标平台下编译出来的程序,并且可以运行在当前平台上;简单理解就是编译和运行环境是一致的。
交叉编译:所谓的交叉(cross)是一个和本地编译相对应的概念,即在当前目标平台下编译出来的程序,是放到别的平台上运行(放在当前平台上运行不了),简单理解就是编译和运行的环境是不一样的。
那有了本地编译,我们为什么还要需要交叉编译呢?给每种平台都搭建一套本地的编译环境不就OK了吗 ? 理想是丰满的,现实是残酷的;
原因:嵌入式系统中的资源太少,各种资源,都相对有限,所以很难进行直接的本地编译;因为编译,开发,都需要相对比较多的CPU,内存,硬盘等资源,而嵌入式开发上的那点资源,只够嵌入式(Linux)系统运行的,没太多剩余的资源供你本地编译。
既然要搭建交叉编译环境,那我们需要怎么做呢?下面我们先看一个GCC编译C语言的流程,如下所示:
从上图可以看到,GCC的编译流程主要分为4步:
1)预处理 ( Pre-Process ) ------如,gcc -E test.c -o test.i
2)编译 ( Compile ) ------如,gcc -S test.i -o test.s
3)汇编 ( Assemble ) ------如,gcc -c test.s -o test.o
4)链接 ( Link ) ------如,gcc test.o -o test
再清楚了GCC编译流程以后,其实交叉编译环境的搭建最主要就是完成上面4个步骤,即将一堆C源文件编译成一个可执行程序的过程;这个过程需要依赖许多工具,最核心的编译器gcc 、汇编器as、 链接器ld等;而as 和 ld 都是包含在binutils 中,因此,简单的说搭建交叉编译环境就是安装相应的gcc + binutils + C运行库(如、glibc、uclibc或eglibc)。下面来看看具体工具主要完成编译过程的哪些任务:
1)gcc(gnu collect compiler):是一组编译工具的总称。它主要完成的工作任务是“预处理”和“编译”,以及提供了与编译器紧密相关的运行库的支持,如libgcc_s.so、libstdc++.so等。
2 )binutils: 提供了一系列用来创建、管理和维护二进制目标文件的工具程序,如汇编(as)、连接(ld)、静态库归档(ar)、反汇编(objdump)、elf结构分析工具(readelf)、无效调试信息和符号的工具(strip)等。通常,binutils与gcc是紧密相集成的,没有binutils的话,gcc是不能正常工作的。
3)C 运行库:glibc = GNU C Library 实现的 C语言标准库(C standard library)是 Linux系统中最底层的API,几乎其它任何的运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现,其实现了常见的C库的函数,支持很多种系统平台,功能很全,但是也相对比较臃肿和庞大;因此在嵌入式开发环境通常采用的是uclibc等小型的C运行库;而 eglibc 是 glibc的一种变体,目标是与glibc兼容,模块化、降低资源和内存的消耗将glibc用于嵌入式系统;
那所谓的交叉编译工具链就是将相关的gcc,binutils、glibc等工具按照先编译后链接等内在逻辑串起来;而由交叉编译工具链组成的综合开发环境就是交叉编译环境;
在了解GCC编译过程以及交叉编译环境的组成,下面我们介绍一款当下用的比较多的制作交叉编译环境的工具,即 crosstool-NG,其是在crosstool的基础上,做了全新的升级,也称下一代crosstool。
crosstool-NG 制作交叉编译工具链的命名规则一般如下:
arch-vendor-kernel-system
arch :即系统架构,即用此交叉编译器编译出来的程序,是运行在哪种CPU上面的,常见的有很多种,比如ARM,X86,MIPS 等等。
vendor :即生成厂家,提供商,表示谁提供的,即谁制作出来这个交叉编译器的,可以自己随便填写的。
kernel :直译为,内核,主要有两类:
Linux
表示:有OS(此处主要指的是Linux )操作系统的环境;简称为,有OS的目标系统:Linux
bare-metal:
表示:无OS(此处主要指的是Linux)操作系统的环境,简称为:无OS系统的:bare-metal,直译为:裸金属;
system :直译为,系统,其实主要表示的是交叉编译器所选择的C运行库,最常见的一些值有,gnu,gnueabi,uclibcgnueabi等等。
crosstool-NG 安装环境:CentOS 7 (x86_64)虚机;
首先,我们需要明白crosstool-ng并不是交叉编译环境的一部分,它只是制作交叉编译环境(或制作交叉编译工具链)的一种工具;因此,在制作交叉编译环境之前,我们需要安装crosstool-ng这个工具,本文将采用源码编译安装的方式获取该工具。
第一步:下载源码,源码链接:http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.23.0.tar.xz,这是当前次新版本(最新版本是1.24.0);
第二步:解压、编译、安装
[root@localhost ~]# cd /zhb
[root@localhost zhb]# ls
crosstool-ng-1.23.0.tar.xz
[root@localhost zhb]# tar xf crosstool-ng-1.23.0.tar.xz
[root@localhost zhb]# ls
crosstool-ng-1.23.0 crosstool-ng-1.23.0.tar.xz
[root@localhost zhb]# cd crosstool-ng-1.23.0
[root@localhost crosstool-1.23.0]# ./configure --prefix=/usr/local/crosstool-1.23.0
[root@localhost crosstool-ng-1.23.0]# make -j8 && make install
注:在执行上面./configure ***生成Makefile 时,会报缺少一些包,大致有以下这些包,先安装这些包再次执行即可,如果还有报错继续安装,总之缺什么包就安装什么包:
yum install gperf bison flex bzip2 texinfo help2man patch ncurses-devel
等待编译完成之后,进入到/usr/local/crosstool-1.23.0目录下执行如下命令:tree -L 2
[root@localhost crosstool-1.23.0]# tree -L 2
.
├── bin
│ └── ct-ng
├── lib
│ └── crosstool-ng-1.23.0
└── share
├── doc
└── man
6 directories, 1 file
我们可以看到bin 目录下已经生成了我们需要的工具ct-ng;
第三步:配置、测试
在.bashrc
最后一行添加,如下所示:
PATH=/usr/local/crosstool-1.23.0/bin:$PATH
重新打开一个终端,执行 ct-ng 命令,出现如下界面表示安装成功;
到这里,我们就完成了安装制作交叉编译环境的工具,即接下来我们需要利用crosstool-ng制作交叉编译环境(或交叉编译工具链);
本文就介绍到这里,如果有写的不对或不周的地方欢迎指正,下篇将具体介绍通过 crosstool-NG 制作交叉编译环境,谢谢阅读~
附:
表:GCC 的常用选项
选项 | 功能描述 |
---|---|
-o | 生成目标文件,可以是.i、.s以及.o文件 |
-E | 只运行C预处理器 |
-c | 通知GCC 取消链接,即只编译生成目标文件,并不做最后的链接 |
-Wall | 生成所有告警信息 |
-w | 不生成任何告警信息 |
-I | 指定头文件的目录路径 |
-L | 指定库文件的目录路径 |
-static | 链接成静态库 |
-g | 包含调试信息 |
-v | 打印编译过程中的命令行和编译器版本等信息 |
-Werror | 把所有警告信息转化成错误信息,并在警告发生时终止编译 |
-O0 | 关闭所有优化选项 |
-O 或O1 | 最基本的优化等级 |
-O2 | -O1的进阶等级,推荐使用的优化等级,编译器会尝试提高代码性能,而不会增加体积和大量占用编译时间 |
-O3 | 最高优化等级,会延长编译时间 |