Makefile实战篇
- 隐含规则1:编译C程序的隐含规则
“
在通过隐含规则执行默认指令时,默认执行 $(CC) -c $(CPPFLAGS) $(CFLAGS),所以CFLAGS这个变量的值要提前设置好(CFLAGS变量默认是无值的)
示例:
1 | OBJS=f1.of2.0 |
- 隐含规则2:链接object文件的隐含规则
1.n2 目标依赖于<n).o ,通过运行C的编译器来运行链接程序生成(一般是1d ),其生成命令是: $TCC $(LDFLAGS)
2.$ (LOADLIBES) $(LDLIBS) 。这个规则对于只有一个源文件的工程有效,同时也对多个Object文件(由不同的源文件生成)的也有效。
例如如下规则:
1 | x:x.o y.o z.o # 必须有目标文件x,和其中一个.o依赖的文件相同,这里x和x.o是相同的 |
如果没有一个源文件(如上例中的x.c)和你的目标名字(如上例中的x)相关联,那么,你最好写出自己的生成规则,不然,隐含规则会报错,例如:test:f1.o f2.o main.o 是不可以的(只会生成f1.o f2.o f3.o这几个文件但不会把它们链接成test目标),main:f1.o f2.o main.o是可以的。
示例:
1 | OBJS=f1.of2.0 |
- makefile的VPATH虚路径
1 | VPATH =src:../headers |
VPATH使用示例:
1 | # 假如我们要用到/src/module1下的.c源文件,如果没有VPATH = ./src/module这句话,我们需要在这样使用module1.c文件: |
有VPATH变量

没有VPATH变量

如果没有VPATH特殊变量来保存路径,我们每使用一个不在 makefile目录下的源文件.c或.o 都要输入一个相对makefile的相对路径,增加出错几率和重复书写。
补充知识:
1 | # 从当前目录开始,查找当前目录和所有子目录包含的.o文件,找到的.o文件交给rm执行删除 |
注意/的前后千万不能有空格,不然就把当前目录和根目录删了
外层父makefile
1 | SUBDIRS = module_1\ # 所有包含源文件的文件夹,make执行是会一次进入各个文件夹执行make -C |
各个模块子makefile(编译)
1 | ../$(OBJS_DIR)/module_1.o: module_1.c # 将module_1.c编译到上一级文件夹的/obj/module.o,展开:../obj/module_1.o:module.c |
obj目录下子makefile(链接)
1 | ../$(BIN_DIR)/$(BIN): $(OBJS) # 将OBJS编译放上一级文件夹/bin/myapp,展开:../bin/myapp:module_1.o module_2.o module_3.o main.o |
特殊符号解释:$(CC) : gcc , $^:所有依赖文件,$@目标文件,@echo:前面的@表示执行命令时不打印命令本身,只打印命令执行结果
运行过程:

config.mk配置文件:上面的外层父makefile的变量可以单独写一个config.mk配置文件中,在父makefile开头 include config.mk 效果一样,config.mk主要用于对不同的硬件需要编译不同的模块源文件的场景,只要修改config.mk就可以对程序进行裁剪添加模块。
源码地址:http://gitea.880755.xyz/private/make_test.git
- 本文作者: 龙兄嵌入式
- 本文链接: https://hexo.880755.xyz/1970/01/01/zblog/download/57.Makefile实战篇/