目录
gcc编译过程
在进行嵌入式开发的过程中,源文件需要经过编译才能生成可执行文件。 在Windows系统下进行开发时,由于各种集成开发软件的存在,我们只需要点几个按钮即可完成程序的编译流程,这是因为我们使用的各种集成开发环境(比如keil软件)已经将各种编译工具的使用封装好了。 Linux下也有很优秀的集成开发工具,但是更多的时候是直接使用编译工具;即使使用集成开发工具,也需要掌握一些编译选项。 PC机上的编译工具链为 gcc、ld、objcopy、objdump等,它们编译出来的程序是在x86平台上运行的。要编译出能在ARM平台上运行的程序,必须要使用交叉编译工具 xxx-gcc、xxx-ld 等(不同版本的编译器的前缀不一样,比如arm-linux-gcc),下面分别介绍。
gcc的编译过程
一个C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇编(assembly)和链接(linking)这4步才能变成可执行文件。以编译x86架构下的hello.c程序为例: 预处理: gcc -E -o hello.i hello.c 编译: gcc -S -o hello.s hello.i 汇编: gcc -c -o hello.s hello.o 链接: gcc -o hello hello.o 我们通常使用'编译'统称以上的四个步骤。
预处理
预处理过程是使用gcc -E编译选项将.c文件处理为.i文件。 这里简要介绍下预处理过程所做的一些操作: 1、将源文件中包含的头文件展开。 2、删除源文件中所有的注释信息。 3、完成宏定义替换。 4、处理所有的预编译指令如#if、#else、#endif等等。 5、保留#pragma编译指令。 6、添加行号、文件名用于后续调试。 7、生成.i文件。
编译
编译过程是使用gcc -S编译选项将.i文件编译为.s汇编文件。 编译过程所做的一般操作如下: 1、源代码分析、语法分析、目标代码生成、目标代码优化等等。 2、生成汇编代码。 3、汇总符号。 4、最后生成.s汇编文件。
汇编
汇编过程是使用gcc -c编译选项将.s汇编文件转化为.o目标文件。 汇编过程所做的一般操作如下: 1、根据各种平台汇编指令的不同,将汇编指令翻译为二进制形式。 2、合并各个部分,合并符号表。 3、生成.o目标文件。
链接
链接过程是将.o目标文件转化为最后的可执行文件。 链接过程所做的一般操作如下: 1、如果有多个.o文件进行链接就合并多个.o文件,合并符号表,进行符号解析。 2、符号地址重定位。 3、生成可执行文件。
常用的编译选项
常用编译选项 | 描述 |
---|---|
-E | 预处理。 |
-c | 预处理、编译、汇编但是不进行链接操作。 |
-o | 指定输出的文件 |
-I(大写i) | 指定头文件的目录 |
-L | 指定链接时库文件的目录 |
-l(小写L) | 指定链接哪个库文件 |
补充
编译多个文件时和编译单个文件的步骤一样,可以分别将每一个.c源文件编译为.o文件后,最后使用gcc将所有的.o文件链接生成可执行文件。
以上的操作都是在x86架构下使用gcc编译器进行操作的,如果编译的程序是在ARM平台下运行的,则需要使用交叉编译器进行编译,如arm-linux-gnueabihf-gcc、aarch64-linux-gnu-gcc等交叉编译工具,对源文件的处理流程和在x86架构下的一样。