Makefile 实例参考

通过将一个 Makefile 从最原始的状态一步步简化,来展现多种常见的 Makefile 语法和技巧。

最初始的形态:

 1main: main.o submodule.o utils.o
 2	gcc main.o submodule.o util.o -o main
 3
 4main.o: main.c submodule.h utils.h
 5	gcc -g -c main.c -o main.o
 6
 7submodule.o: submodule.c submodule.h utils.h
 8	gcc -g -c submodule.c -o submodule.o
 9
10utils.o: utils.c utils.h
11	gcc -g -c utils.c -o utils.o
12
13.PHONY: clean
14clean:
15	rm main main.o submodule.o utils.o

引入变量:

 1OBJS=main.o submodule.o utils.o
 2CC=gcc
 3CFLAGS=-g
 4
 5main: $(OBJS)
 6	$(CC) $(OBJS) -o main
 7
 8main.o: main.c submodule.h utils.h
 9	$(CC) $(CFLAGS) -c main.c -o main.o
10
11submodule.o: submodule.c submodule.h utils.h
12	$(CC) $(CFLAGS) -c submodule.c -o submodule.o
13
14utils.o: utils.c utils.h
15	$(CC) $(CFLAGS) -c utils.c -o utils.o
16
17.PHONY: clean
18clean:
19	rm main $(OBJS)

引入 Static Pattern RulesAutomatic Variables$<$@):

 1OBJS=main.o submodule.o
 2DEPS=submodule.h utils.h
 3CC=gcc
 4CFLAGS=-g
 5
 6main: $(OBJS) utils.o
 7	$(CC) $(OBJS) -o $@
 8
 9$(OBJS): %.o: %.c $(DEPS)
10	$(CC) -c $(CFLAGS) $< -o $@
11
12utils.o: utils.c utils.h
13	$(CC) $(CFLAGS) -c utils.c -o utils.o
14
15.PHONY: clean
16clean:
17	rm main $(OBJS)

或者引入 Implicit Rules ,同时使用了单一规则多目标单一目标多规则 的语法:

 1OBJS=main.o submodule.o utils.o
 2CC=gcc
 3CFLAGS=-g
 4
 5main: $(OBJS) 
 6	$(CC) $(OBJS) -o $@
 7
 8main.o submodule.o: submodule.h
 9
10$(OBJS): utils.h
11
12.PHONY: clean
13clean:
14	rm main $(OBJS)

另外,一个常有的情况是:我们想把编译出来的二进制文件放到一个特殊的目录下,或者把源文件和头文件分目录存放。这里使用了 Substitution References ,以及 infoshell 函数:

 1OBJS=main.o submodule.o utils.o
 2CC=gcc
 3CFLAGS=-g
 4BIN_DIR=./bin
 5_TARGETS = main
 6TARGETS = $(_TARGETS:%=$(BIN_DIR)/%)
 7
 8$(info $(shell mkdir -p $(BIN_DIR)))
 9
10$(TARGETS): $(OBJS) 
11	$(CC) $(OBJS) -o $@
12
13main.o submodule.o: submodule.h
14
15$(OBJS): utils.h
16
17.PHONY: clean
18clean:
19	rm main $(OBJS)

最后介绍一个好用的参数:make -n

“dry-run”, just print what it’s gonna do but not actually do it. Really helpful for debugging.

参考资料:


基于 Jenkins 搭建针对内核的 CI
利用云服务器建立个人博客网站