Make mk makefile -include dash include dependence
今天有位同学拿着一个Android中的makefile文件问我,"-include"是什么意思?为什么要加个减号?
欢迎转载,但是请注明原出处:http://blog.youkuaiyun.com/howellzhu
我相信对经常配置开源工程进行autoconf的人一定非常熟悉,但是对于普通的Android开发工程师就不一定了解了。
在这里我简单说一下:
-include: 表示include的目标如果存在就包含进来,如果不存在就算了(不要报错)。
这位同学非常富有探索精神,拿到了答案并没有满意,非常不高兴的继续问:啥时候会有这种需求?
欢迎转载,但是请注明原出处:http://blog.youkuaiyun.com/howellzhu
一般来说,如果比较简单的依赖关系,可以手工进行维护。比如一个工程中有两个源文件:foo.c和bar.c。两个头文件foo.h和bar.h,编译成为一个程序prog。
我们的Make文件一般这么写:
OBJS := foo.o bar.o
prog: $(OBJS)
gcc $^ -o $@
%.o: %.c
gcc -c $^ -o $@
clean:
rm -f prog $(OBJS)
但是这里有一个问题,依赖关系靠手工维护,并且只维护到foo.o依赖于foo.c,bar.o依赖于bar.c。
为了简化手工维护的工作,我们可以考虑用gcc -MM命令来帮我们维护依赖关系,加入foo.c中include了foo.h。那么如下的命令
gcc -MM -c foo.c 将输出如下的内容:
foo.o: foo.c foo.h
这就是我们希望得到的依赖关系。我们在Makfile中进行-MM的处理并将该输出行保存到一个.d文件,然后在Makefile文件中将其include进来就ok了。
OBJS := foo.o bar.o
prog: $(OBJS)
gcc $^ -o $@
include foo.d
%.o: %.c
gcc -c $*.c -o $*.o
gcc -MM -c $*.c > $*.d
clean:
rm -f prog $(OBJS) *.d
但是这里有个问题,如果从来没有编译过,或者make clean以后,再build就会出错,因为找不到foo.d。
这样用-include就能实现,如果有就include,如果没有就不要include。
这样会不会有问题?仔细想想不会,因为如果没有.d的时候就没有.o,没有.o就会发起重新编译,因此不会因为dependency不对而导致问题。
OBJS := foo.o bar.o
prog: $(OBJS)
gcc $^ -o $@
-include $(OBJS:.o=.d)
%.o: %.c
gcc -c $*.c -o $*.o
gcc -MM -c $*.c > $*.d
clean:
rm -f prog $(OBJS) *.d
这里使用了一个技巧(OBJS:.o=.d),即对OBJS中的所有变量,将.o替换成为.d。这样避免手工编写.d文件目标列表。
-include和Android中
$(call inherit-product-if-exists, xxx)
这样的语法作用很像。
为了便于喜欢研究的同学深究,我特意上传makefile的宝典pdf文件供大家下载:
欢迎转载,但是请注明原出处:http://blog.youkuaiyun.com/howellzhu