目录
所谓隐含规则指的是,我们在Makefile文件中不使用 gcc/g++ 命令来生成目标文件,但是执行make命令以后,Makefile 会自动帮我们执行。这就是Makefile 的隐含规则,也可以称为自动推导的过程。
既然是自动推导,那就需要自己去寻找 .c 文件、.h 文件,下面就从两个角度来考虑
如果我们只提供了 .o 文件,此时执行 make 命令的时候,Makefile 自动推导 .o 需要的依赖项为 .c 文件,此时编译器会默认在当前目录和环境变量中查找,然后自动帮我们生成 .o 文件 以及 目标文件。
- OBJS=test.o main.o
- TARGET=main
-
- $(TARGET): $(OBJS) # 自动推导
这个过程中生成 .o 文件用到的生成命令:
- # CC 默认是 gcc
- # CPPFLAGS 是 gcc预编译选项,无默认值
- # CFLAGS 是 gcc 的编译选项,无默认值
- $(CC) –c $(CPPFLAGS) $(CFLAGS)
假设有个 test.h 文件的所在位置是 ./include/ ,Makefile在预处理阶段会将头文件展开,如果这个时候找不到头文件,就无法生成 .i 文件,更不用说后面的 .s、.o 文件了。
因为是让编译器自己去推导的,所以我们应该告诉编译器在哪个目录下去找头文件,此时就要手动设置预定义变量 CFLAGS了,而额外添加头文件的搜索路径用的是 -I 选项
- OBJS=test.o main.o
- TARGET=main
- CFLAGS=-I./include # 添加额外的头文件搜索路径
-
- $(TARGET): $(OBJS) # 自动推导
伪目标和普通的目标文件不一样,只有目标,没有依赖项,也就不会生成目标文件,一般用于清理、备份工作。伪目标有点类似于C中的函数,一般包含以下两步:
- OBJS=test.o main.o
- TARGET=main
- CFLAGS=-I./include
- $(TARGET): $(OBJS)
-
- .PHONY:clean cleanAll # 声明伪目标
- clean: # 伪目标实现
- $(RM) $(TARGET)
- cleanAll:
- $(RM) $(OBJS) $(TARGET) # RM 是预处理变量,$(RM)等价于 rm -f