About the GNU make dependency files *.d

放肆的年华 提交于 2019-12-05 09:49:36

Exit on all errors

@set -e;

Delete existing dep file ($@ = target = %.d)

rm -f $@;

Have the compiler generate the dep file and output to a temporary file postfixed with the shell pid ($< = first prerequisite = %.c, $$$$ -> $$ -> pid)

$(CC) -M $(CPPFLAGS) $< > $@.$$$$;

Capture the target matching $*.o ($* = match stem = %), replace it with the target followed by the dependency file itself, output to dep file

sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \

Delete temp dep

rm -f $@.$$$$

Let's plug in foo, CC = gcc, and CPPFLAGS = '' to see what happens after make has finished expanding stuff:

foo.d: foo.c
    @set -e; rm -f foo.d; \
     gcc -M foo.c > foo.d.$$; \
     sed 's,\(foo\)\.o[ :]*,\1.o foo.d : ,g' < foo.d.$$ > foo.d; \
     rm -f foo.d.$$

The shell itself will expand $$ to the pid, and the final rule in the dep file will look something like

foo.o foo.d : foo.c foo.h someheader.h

Note that this is a pretty outdated way of generating dependencies, if you're using GCC or clang you can generate them as part of compilation itself with CPPFLAGS += -MMD -MP.

Say you have a program called foo:

objs := foo.o bar.o
deps := $(objs:.o=.d)

vpath %.c $(dir $(MAKEFILE_LIST))

CPPFLAGS += -MMD -MP

foo: $(objs)

.PHONY: clean
clean: ; $(RM) foo $(objs) $(deps)

-include $(deps)

That's all you need, the built-in rules will do the rest. Obviously things will be a little more complicated if you want the object files in a different folder or if you want to build outside the source tree.

The vpath directive allows you to run make in a different directory and have the files created there, e.g. make -f path/to/source/Makefile.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!