基础知识
gcc编译过程
- C源文件到可执行文件共经历了4个过程。在使用GCC编译程序时,编译过程可以被细分为四个阶段,包括预处理、编译、汇编、链接。
-
预处理
在预处理阶段,编译器主要是加载头文件,宏替换,条件编译的作用,一般处理带"#"的语句gcc -E main.c > main.i
-
编译
在编译过程中,编译器主要是进行语法检查,在确认所有的指令都符合语法规则之后,将其翻译成中间代码或是汇编代码。gcc -S main.i -o main.s
-
汇编
汇编阶段主要是把编译阶段产生的.s文件转成二进制目标码gcc -c main.s -o main.o
-
链接
在成功汇编后就进入了链接阶段,链接就是将目标文件、启动代码、库文件链接成可执行文件的过程,这个文件可被加载或拷贝到内存里执行。gcc main.o -o main
一步到位
gcc main.c -o main
make工程管理工具
- make工程管理工具:帮助我们实现项目的自动编译
- 在c语言中,只有源文件才会参与编译。如果某些源文件做了修改,整个项目都需要重新编译的做法很笨,但是make工具很聪明,它可以帮我们自动判断,哪些文件做了修改,就编译哪些文件。Makefile仅仅是一个文件,里面有很多规则,来说明如何编译,编译顺序,Makefile中制定的规则,会由make这个工具来执行。
- 当想要自己指定makefile文件名的时候,可以使用以下命令
- make -f my_makefile
- makefile中的规则组成
- 目标:依赖列表
[tab]命令列表 - 其中第一条规则中的目标,将会成为最终目标。我们的最终目的,就是为了生成这个目标的
- 其他规则之间,没有必然的顺序关系
- 当系统时间信息不对时,是无法使用make命令的
- Makefile是根据文件的时间信息,来判断是否需要重新编译的
- 目标:依赖列表
最简单的Makefile
Makefile:
all:
gcc main.c test.c
因为没有依赖,所以无法判断依赖的时间是不是比目标新,所以make之后总是会执行命令
解决以上问题:
a.out: main.c test.c
gcc main.c test.c
增加依赖之后:
- 如果a.out不存在,则会执行命令
- 如果依赖的比目标新,则会执行命令
结果
变量
“:=” 立即赋值
“=” 延时赋值
“?=” 条件赋值 如果没有赋过值 就赋值 否则不赋值
“+=” 追加赋值
B := $A #立即赋值
C = $A #延时赋值
A = 10
D = 20
D ?= $A #条件赋值
E = 30
E += $A #追加
test:
@echo "B = $B"
@echo "C = $C"
@echo "D = $D"
@echo "E = $E"
输出结果:
B =
C = 10
D = 20
E = 30 10