一、什么是make
make 是软件构造工具,make有多个版本,本文将基于GNU make,make会自动搜索当前目录下的makefile, Makefile或者GNUmakefile。
二、make核心规则
target ... : prerequisites ...
command
- target是目标文件,实际是Object File,或执行文件,以及标签(Label)
- prerequisites是target依赖的文件或是目标。
- 一个依赖关系可以附属有多个操作。
如果prerequisites的修改时间比target更新,或者target文件不存在,command被执行;首次执行make创建了target文件是因为target文件不存在,之后执行make会根据修改时间的属性进行判断,如更新了源码内容,那么command还会再次执行,这就是makefile的规则和核心。
三、实例介绍
测试c文件main.c:
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return 0;
}
对应makefile如下:
# 宏
CC ?= gcc
# main is a binary file
main: main.o
$(CC) -o main main.o
main.o: main.c
$(CC) -c -o main.o main.c
执行make后将会生产main可执行文件。
宏
宏分为自定义宏和内部宏,比如我们上面使用的CC就是自定义宏,make会在运行时,使用宏的值(gcc)来替代 (CC);
shell的环境变量可以直接作为宏调用,如果同一个自定义的宏同时也有同名环境环境变量,make将优先使用自定义宏。
内部宏
- $? :比目标还要新的依赖文件列表
- $@ :当前依赖关系的目标文件名
- $< :表示当前目标的第一个依赖文件
- $* :当前依赖关系中的目标文件名,不包括后缀
- $^ :当前目标的所有依赖文件
- $$ :字符"$"
后缀依赖
可以在在makefile中使用
.SUFFIXES: .c .o
.c.o:
$(CC) -c -o $@ $^
来说明.c和.o是后缀,并编写后缀依赖关系**.c.o**。
其他
- makefile的续行符为\
- @command表示不显示命令本身
- -command表示忽略命令报错
- makefile中经常会定义下面依赖关系:
all:
如果make后没有跟随文件名,那么将执行该依赖关系。
clean:
常用于清理历史文件。
test:
用于编写make test测试用例。
扫描二维码关注公众号,回复:
10536199 查看本文章
dep:
用于自动生成依赖关系。
完整版makefile例子
# 宏
CC ?= gcc
PACKNAME = main
.SUFFIXES: .c .o
.c.o:
$(CC) -c -o $@ $^
all: main
@echo "all"
# main is a binary file
main: main.o
$(CC) -o $@ $<
main.o: main.c
clean:
-rm $(PACKNAME) *.o
dep:
$(CC) -MM *.c
test:
@echo "write test case"
如果到这里你都看懂,那么说明你已经掌握了makefile常用的语法了。