Makefile初步使用

Makefile初步使用

参考资料:Makefile常用语法



作为我第一次编写Makefile的Project,里面包含了`add.c`、`fun1.c`、`loop.c`、`main.c`这四个源文件,目标是编译生成可执行文件test。直接用gcc在命令行编译很麻烦而且不利于维护(当然这个Project很简单),下面直接贴出Makefile代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#obj = main.o fun1.o loop.o add.o                                  
src = $(wildcard ./*.c)
#obj = $(src:%.c = %.o)
obj = $(patsubst %.c,%.o,$(src))
targets = test
CC = gcc
$(targets): $(obj)
$(CC) -o $(targets) $(obj)
%.o: %.c
$(CC) -c $< -o $@
.PHONY: clean run
clean:
-rm $(targets) *.o
run:
./$(targets)
COUNT := $(shell find . -name "*.c" -or -name "*.h" | xargs grep -Ev "^$$" | wc -l)
count:
@echo Totally $(COUNT) lines of code in this directory except empty lines

关于变量obj的生成,我上面采用了三种方法,第一行是最浅显易懂的,直接把相应.c文件对应的可重定位文件枚举一下即可,但一旦添加了.c文件,又得修改Makefile,很是麻烦,于是有了后面两种。

src是目录下的所有.c文件,通过wildcard函数实现。obj都是根据src下面的文件生成对应的.o文件,第三种patsubst是字符串替换函数。通过实际运行我发现,一、三两种写法会在目录下面生成中间过程产生的可重定位文件,而使用obj = $(src:%.c = %.o)语句并不会在目录下面生成.o文件,刚开始我并没有注意到这一点,clean方法写的是-rm $(targets) $(obj),结果导致目录下的.c文件都被删除了。所以,假如采用第二种写法,clean方法只要写成-rm $(targets),否则要额外删除.o文件,吸取教训后我采用了如上代码中的语句。

最后我还实现了PA中实现过的统计不包括空行的代码行数的方法make count

Makefile里面还有很多东西值得探索,开头的链接值得一读。

0%