一个简单的makefile实例
1,取自 brian Kernighan的 C programming language中 逆波兰式一章的代码为例子。
2,文件有 calc.h getch.c getop.c main.c makefile stack.c
makefile 文件
version 1:
1 calc: main.o getch.o getop.o stack.o 2 cc -o calc main.o getch.o getop.o stack.o 3 main.o: main.c calc.h 4 getch.o: getch.c 5 getop.o: getop.c calc.h 6 stack.o: stack.c calc.h
问题 1,main.o 等各模块 重复出现太多,需要 加入 clean 命令,便于 清理
version 2:
1 OBJS = main.o getch.o getop.o stack.o 2 calc: $(OBJS) 3 cc -o calc $(OBJS) 4 main.o: main.c calc.h 5 getch.o: getch.c 6 getop.o: getop.c calc.h 7 stack.o: stack.c calc.h 8 clean: 9 rm -rf $(OBJS) calc
问题2, 重复 写 *.c -> *.o 的过程麻烦,可以简化
version 3:
1 CC = gcc 2 OBJS = main.o getop.o stack.o getch.o 3 calc:$(OBJS) 4 $(CC) -o $@ $^ 5 $(OBJS): calc.h 6 %.o:%.c 7 $(CC) $< -c -o $@ 8 clean: 9 rm -rf calc $(OBJS)
使用了一些 @变量
$@
代表规则中的目标文件名。如果目标是一个文档(Linux中,一般称.a文件为文档),那么它代表这个文档的文件名。在多目标的模式规则中,它代表的是哪个触发规则被执行的目标文件名。
$^
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件名,它所代表的只能是所有库成员(.o文件)名。一个文件可重复的出现在目标的依赖中,变量“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件
$<
规则的第一个依赖文件名。如果是隐含规则,则它代表通过目标指定的第一个依赖文件。
注意:关于 phony的用法:
问题,目前还是对当前的环境有依赖,我们可以加入通配符的使用,另外还可以将所有的执行文件输出到一个制定文件中去
version4
1 CC = gcc 2 SRCS = $(wildcard *.c) 3 OBJS =$(patsubst %.c,%.o,$(SRCS)) 4 TARGET = calc 5 .PHONY: clean all post-install pre-install 6 OUTPUT = output 7 all: pre-install $(TARGET) post-install 8 9 $(TARGET):$(OBJS) 10 $(CC) -o $@ $^ 11 12 %.o:%.c 13 $(CC) $< -c -o $@ 14 15 pre-install: 16 @if [ ! -d ${OUTPUT} ]; \ 17 then mkdir ${OUTPUT}; \ 18 fi; 19 post-install: 20 mv $(TARGET) $(OBJS) $(OUTPUT) 21 clean: 22 rm -rf $(OUTPUT)