Makefile好比菜谱,菜谱告诉厨师如何做菜,Makefile则告诉make工具如何编译源代码。
Makefile的基本拼图是规则,规则可以简单的理解为,如何通过源生成目标,其格式如下:
目标 : 源
从源生成目标的方法
规则至少说明了两件事:什么时间,如何生成目标。
当源发生变化时,目标被重新生成。生成的方法在规则的第二行中被描述。
我们看一个最简单的Makefile。
hello.c:
#include <stdio.h>
int main()
{
printf("Hello world!\n");
}
Makefile:
hello : hello.c
gcc hello.c -o hello
编译运行:
# make
gcc hello.c -o hello
# ./hello
Hello world!
虽然绝大多数Makefile都可以写得如此清晰执白,但是在现实中的Makefile却令人崩溃。我们看一个略显复杂的例子。
Makefile:
PROGRAMS = server client
server_OBJS = server.o server_priv.o server_access.o
server_LIBS = priv protocol
client_OBJS = client.o client_api.o client_mem.o
client_LIBS = protocol
# Everything after this is generic
.PHONY: all
all: $(PROGRAMS)
define PROGRAM_template =
$(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%)
ALL_OBJS += $$($(1)_OBJS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
$(PROGRAMS):
$(LINK.o) $^ $(LDLIBS) -o $@
clean:
rm -f $(ALL_OBJS) $(PROGRAMS)
然而,再复杂的Makefile都是由各种简单的部分构成。以后,我们将有机会学习每个简单而具体的知识点。
GNU Make Manual(参考1)有200多页,不好读,但却是找到Makefile各种问题答案的首选文档。