gcc、make编译
一 arm-linux-gcc 常用参数
https://www.cnblogs.com/zhangpengshou/p/3587751.html
二 arm-linux-objdump常用参数
https://blog.csdn.net/freeplayer/article/details/45133721
三 arm-linux-objcopy常用参数
https://blog.csdn.net/tang_jin_chan/article/details/8675269
四 GCC
1 GCC编译流程:
1. 预处理(Pre-Processing)
2. 编译(Compiling)
3. 汇编(Assembling)
4. 链接(Linking)
2 GCC所支持的后缀名解释
后缀名 | 所对应的语言 | 编译流程 |
.c | C源程序 | 预处理、编译、汇编 |
.C/.cc/.cxx | C++源程序 | 预处理、编译、汇编 |
.m | Objective-C源程序 | 预处理、编译、汇编 |
.i | 已经预处理的c源程序 | 编译、汇编 |
.ii | 已经预处理的c++源程序 | 编译、汇编 |
.s/.S | 汇编语言源程序 | 汇编 |
.h | 预处理文件(头文件) | 预处理 |
.o | 目标文件 | 链接 |
.a/.so | 静态/动态库文件 | 链接 |
3 GCC编译流程分析
3.1 预处理阶段
命令格式: |
gcc -E -o [目标文件] [编译文件] |
注: -E 使编译器在预处理结束时就停止编译 -o 指定GCC输出的结果 |
gcc -E -o hello.i hello.c
//".h"文件是不能进行编译的,所以需要生成".i"文件;<.i文件是经过预处理的c源程序>
//预处理阶段结果:将"hello.h"的内容添加到"hello.i"文件中
/*如果在一个test的文件夹中*/ gcc -E -o test/hello.i test/hello.c
3.2 编译阶段
编译器在预处理结束后进行编译。GCC首先要检测代码的规范性,是否有语法错误等,以确定代码实际要做的工作。检查无误后就开始把代码翻译成汇编语言,GCC的选项‘-S’能使编译器进行完编译后就停止。
gcc -S -o hello.s hello.i
//".s"代表汇编语言源程序,
//编译结果:将"hello.i"代码翻译成"hello.s"的汇编代码
/*如果在一个test的文件夹中*/ gcc -S -o test/test.s test/test.i
3.3 汇编阶段
把编译阶段生成的".s"文件生成为目标文件
gcc -c hello.s -o hello.o
//使用"-c"可以看到由汇编代码转换为".o"的二进制代码
/*如果在一个test的文件夹中*/ gcc -c test/hello.s -o test/hello.o
3.4 链接阶段
编译成功后进入链接阶段,进入链接后生成可执行的文件
gcc hello.o -o hello
运行执行文件,输出结果
./hello
/*如果在一个test的文件夹中*/ gcc test/hello.o -o test/hello //hello为执行文件 ./test/hello //执行执行文件
4 直接生成一个执行文件
gcc test/hello.c -o test/hello
四 make
1 makefile术语
规则:用于说明如何生成一个或多个目标文件
规则格式如下:(-c只产生一个.o的目标文件)
targets :prerequisite
command
目标 依赖 命令
main.o : main.c
gcc -c main.c [命令需要以【Tab】键开始]
解释:目标就是生成一个main.o,依赖于main.c文件,命令就是gcc -c main.c
hello:main.o func1.o func2.o //hello为最终目标的可执行文件 gcc main.o func1.o func2.o -o hello main.o:main.c gcc -c main.c func1.o : func1.c gcc -c func1.c func2.o : func2.c gcc -c func2.c .PHONY :clean clean: rm -f hello main.o func1.o func2.o
2 目标
Makefile中,规则的顺序是很重要的,因为Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。
3 文件名
make命令默认在当前目录下寻址名字为Makefile或makefile的工程文件,当名字不为这两者之一时,可以使用如下方法指定。
make -f 文件名
4 示例
4.1 在test文件夹中创建makefile文件
dongry@d-linux:~$ vim test/makefile //在test文件夹中创建一个makefile文件
4.2 编写makefile文件(haha.o为需编译生成的目标文件,名字随便起)
haha.o : test/test1.c gcc -c test/test1.c -o test/haha.o //开头【tab】键
4.3 进入目标文件夹进行make
4.3.1 进入目标文件夹
dongry@d-linux:~$ cd test
4.3.2 make
dongry@d-linux:~/test$ make gcc -c test1.c -o haha.o //表示成功生成haha.o目标文件
4.3.3 退出当前目录
dongry@d-linux:~/test$ cd ~
dongry@d-linux:~$
5 伪目标
makefile把那些没有任何依赖只有执行动作的目标称为"伪目标"。(phony targets)
.PHONY clean [".PHONY"将"clean"声明为伪目标]
clean :
【Tab】 rm -f main.o func1.o func2.o
6 变量
hello : main.o func1.o func2.o
gcc -c main.o func1.o func2.o -o hello
给hello目标添加一个依赖,如func3.o,如何实现。
方法一:
hello : main.o func1.o func2.o func3.o
gcc -c main.o func1.o func2.o func3.o -o hello
方法二:
obj=main.o func1.o func2.o func3.o
hello : $(obj)
gcc -c $(obj) -o hello
6.1 在makefile系统中存在系统默认的自动化变量
$^:代表所有的依赖文件
$@:代表目标
$<:代表第一个依赖文件
eg:
hello : main.o func1.o func2.o
gcc -c main.o func1.o func2.o -o hello
同:hello :main.o func1.o func2.o
gcc $^ -o $@
7 常用项
makefile中"#"后面的被认为是注释
hello : hello.c
@gcc hello.c -o hello
"@"取消回显 //表示输入make命令后,不出现下面的一行:
gcc -c test1.c -o haha.o //不会出现