文章目录
本节源码在github仓库Makefile
1、程序的编译过程
介绍
- 1、预处理:检查语法,包含头文件,条件编译,展开宏,去掉注释;
- 2、编译:将 xxx.c ->xxx.s (汇编文件);
- 3、汇编:将 xxx.s -> xxx.o (机器码);
- 4、链接:xxx.o + 库文件 = 可执行程序;
用 gcc –o a a.c
可把1、2、3、4四个步骤一起完成。
VC下程序的编译
VC 下程序的编译过程总结:
2、在 linux 下面实现像 VC 下程序的编译的过程
代码为07.通用的Makefile_源码_文档_图片\09.Makefile\source\test
中的Makefile
。
使用命令a. gcc -o test a.c b.c编译
- 对于
a.c
:预处理、编译、汇编 - 对于
b.c
:预处理、编译、汇编 - 最后链接
优点:命令简单
缺点:如果文件多即使只修改了一个文件,但所有的文件都要重新"预处理、编译、汇编",效率低
使用Makefile编译
核心:规则
目标:依赖1 依赖2
命令
命令执行的条件:
i. "依赖"文件 比 "目标"文件 新
ii.没有"目标"这个文件
第一个 Makefile :
第二个 Makefile :
这种写法,只修改了头文件 a.h
不会重新编译。
第三个 Makefile:使用通配符
$@
:表示目标;
$<
:表示第一个依赖;
$^
:表示所有的依赖;
这种写法,只修改了头文件 a.h
会重新编译;
第四个 Makefile : 使用通配符 + 自动生成依赖文件
objs := a.o b.o
test:$(objs)
gcc -o test $^
# .a.o.d .b.o.d
# foreach函数:对于变量objs里的每一个成员改为.$(f).d(加一个前缀“.”和一个后缀“.d”)
# wildcard函数:查看dep_files中是否有“.d”文件,有的话就取出来
dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))
# 如果dep_files变量不为空的话,就把dep_files包含进来
ifneq ($(dep_files),)
include $(dep_files)
endif
# -Wp,-MD,.$@.d:表示生成依赖文件a.o.d、b.o.d
%.o : %.c
gcc -Wp,-MD,.$@.d -c -o $@ $<
clean:
rm *.o test
-
1、执行
make
命令时,使用命令gcc -o test $^
生成第一个目标test
,test
依赖于objs
,objs
为两个.o
文件; -
2、
.o
文件依赖于.c
文件,使用命令gcc -Wp,-MD,.$@.d -c -o $@ $<
生成。 -
其中
-Wp,-MD,.$@.d
:表示生成依赖文件a.o.d
、b.o.d
。 -
3、对于
.d
文件来说: -
使用
dep_files := $(foreach f,$(objs),.$(f).d)
函数和dep_files := $(wildcard $(dep_files))