目录
一、GCC常见的编译步骤
1、编译的一般步骤
- 预处理(对宏进行处理):处理 # 开头的头文件,生成 .i 文件(预处理器cpp)
- 编译(从源代码到汇编语言):编译器将 .i 文本文件 翻译成 .s 文件,.s文本文件包含一个汇编语言程序,为不同高级语言的不同编译器提供通用语言输出
- 汇编(从会汇编语言到机器语言):将 .s 文件翻译成机器语言指令,把这些指令打包成为一种可以重定位目标程序的格式,并将结果保存在对应的 .o 文件。.o 文件是一个二进制文件,它的字节编码为机器语言指令而不是字节,所以在文本编辑器中打开会呈现一堆乱码。(汇编器as)
- 链接(生成最后的可执行文件):将所有 .o 文件并入在一起,并且生成可执行目标文件。(链接器ld)
2、编译步骤对应的选项
选项 | 含义 |
---|---|
-E | 预处理 (只预处理,不编译、不汇编、不链接) |
-S | 编译(只编译,不汇编、不链接) |
-c | 编译与汇编(不链接) |
-o <file> | 包含整个步骤(预处理、编译、汇编、链接)、并且输出对应可执行文件file |
二、GCC常用编译选项
1、编译必加选项
选项 | 含义 |
---|---|
-Wall | 打开警告选项 |
-g | 允许程序在调试器控制下运行,并且生成调试信息 (在对应错误地方的程序进行展开显示) (后面还可以指定输出对应格式的调试信息 如:-gdwarf-2) |
2、库与路径相关选项
选项 | 含义 |
---|---|
-I(大写的i) | 对应头文件搜索路径 |
-L | 对应库文件搜索路径 |
-l(小写的L) | 对应的库文件(若对应的库文件名字为libxxx.a, 则为 -lxxx) |
-lc | 在标准C库中搜索原文件没有提供的函数 |
-lm | 使用math库 |
-lnosys | 使用libnosys.a库 |
3、c语言标准与使用语言选项
选项 | 含义 |
---|---|
-ansi | 禁止那些与 ANSI/ISO 标准冲突的 GNU 扩展特性 |
-std | 指定使用的C标准(如:-std=gnu11 即:c11与gnu的拓展) |
-x <language> | 指明后面的文件所使用的<language>(如: -x assembler-with-cpp) |
4、预处理
选项 | 含义 |
---|---|
-D<Name> | 在命令行中定义处理宏(相当于在源文件中 #define Name) |
-D<Name> = NUM | 给对应宏赋值 |
5、文件关联信息
选项 | 含义 |
---|---|
-M | 生成文件关联的信息。包含目标文件所依赖的所有源代码 |
-MD | 与-M一样,但是将信息导入到 .d 文件中 |
-MM | 与-M相似,但是 忽略#include<header> 造成的依赖(官方库) |
-MMD | 与-MM一样,但是将信息导入到 .d 文件中 |
-MF "file" | 当使用了 -M 或者 -MM 选项时,则把依赖关系写入名为 file 的文件中。若同时也使用了 -MD 或 -MMD,-MF 将覆写输出的依赖文件的名称 。 |
-MP | 生成的依赖文件里面,依赖规则中的所有 .h 依赖项都会在该文件中生成一个伪目标,其不依赖任何其他依赖项(防止未更新makefile去匹配新的依赖而导致的错误) |
6、代码优化与编译优化
常见的代码优化:
(1)公共子表达式消除:使用变量保存计算过的值,再用该变量进行运算。
如:x = cos(v)*(1+sin(u/2)) + sin(w)*(1-sin(u/2)) 变成:
t = sin(u/2)
x = cos(v)*(1+t) + sin(w)*(1-t)(2)函数内嵌(内联函数):当调用函数的时间与该函数运行时间相差不多的情况下,就要考虑内联了。
选项 | 含义 |
---|---|
-O0 | 没有优化 |
-O1 | 默认优化 |
-O2 | 第2级别优化(优化运行速度) |
-O3 | 第3级别优化(优化运行速度,优化级别最高) |
-Os | 尽可能降低 生成目标文件的大小(体积优化) |
-Og | 该标识会精心挑选部分与-g选项不冲突的优化选项,当然就能提供合理的优化水平,同时产生较好的可调试信息和对语言标准的遵循程度 |
7 、参数传递
选项 | 含义 |
---|---|
-Wl(小写L) | 表示将后面的参数传递给链接器ld (多个选项的传递通过逗号进行分隔) (如:-Wl,--gc-sections) |
-Wa | 表示将后面的参数选项传递给汇编器as (多个选项的传递通过逗号进行分隔) (如:-Wa,-a,-ad) |
三、ARM GCC相关内容
1、ARM GCC 相关内容介绍
- arm-none-eabi 相关工具介绍
2、arm-none-eabi-gcc相关选项
选项 | 含义 |
---|---|
-mcpu=cortex-m4 | cotex-m4 内核 |
-thumb | thumb指令集(arm指令集的一个子集) |
-mfpu=fpv4-sp-d16 | 使用浮点运算单元(其中fpv4-sp-d16为浮点运算单元的名字) |
-mfloat-abi=hard | 使用 硬件 浮点运算单元 |
-ffuction-sections | 将每个函数编译到对应的段中(配合--gc-section使用,可以减小代码大小) |
-fdata-sections | 将每个数据编译到对应的段中(配合--gc-section使用,可以减小代码大小) |
-Wa | 将后面的选项参数传递给汇编器as(多个选项的传递通过逗号进行分隔。如: -Wa,-a,-alms=xxx.lst) |
选项 | 含义 |
---|---|
-T | 对应链接器脚本(如:STM32F407VGTx_FLASH.ld) |
-Wl(小写L) | 表示将后面的参数传递给链接器ld(多个选项的传递通过逗号进行分隔。如: -Wl,-Map=xxxx.map,--cref) |
-Map | 让链接器ld生成对应的map文件(如:-Map= xxx.map) 【Map文件的作用在下面介绍】 |
--cref | 生成交叉引用列表(每个符号出自哪个目标文件,如果还有指定-Map,则会添加到map文件中。否则,打印到标准输出) |
--gc-sections | 删除未使用的部分 |
-specs | 使用什么标准库 (如:-specs=nano.specs 使用nano的C库) |
注:
map文件的主要作用:
- 程序各区段的寻址是否正确
- 程序各区段的size,即目前存储器的使用量
- 程序中各个symbol的地址
- 各个symbol在存储器中的顺序关系(在调试中很有用)
- 各个程序文件的存储用量