gnu make 中的`make depends`魔法?

`make depends` magic in gnu make?

我有一个生成依赖文件的简单脚本 (depends.sh),并对依赖文件进行了一些更改。

#!/bin/sh
#echo "## Got: $*"
CC=""
DIR=""
shift 2
case "$DIR" in
    "" | ".")
    $CC -MM -MG "$@" | sed -e 's@^\(.*\)\.o:@.d .o:@'
    ;;
    *)
    $CC -MM -MG "$@" | sed -e "s@^\(.*\)\.o:@$DIR/.d $DIR/.o:@"
    ;;
esac

脚本是从 Makefile 中调用的,这是其中的摘录。

DEP := $(OBJ:.o=.d)

# implicit rules

%.d: %.c
    ./depends.sh $(CC) `dirname $*.c` $(CFLAGS) $*.c > $@

-include $(DEP)

# Actual targets

depend: $(DEP)

有趣的是 make depends 执行以下操作:

./depends.sh gcc `dirname src/hellomake.c` -Wall -Wno-unused-function -g -O  -Isrc  src/hellomake.c > src/hellomake.d
./depends.sh gcc `dirname src/hellofunc.c` -Wall -Wno-unused-function -g -O  -Isrc  src/hellofunc.c > src/hellofunc.d
cat depends.sh >depends 
chmod a+x depends

没有depends目标(只有depend目标),但它执行依赖目标甚至创建依赖脚本,并使其可执行。

这背后的魔力是什么?

最后两行来自内置规则,如果你使用make的“-p”选项,你可以看到。看起来像

%.sh:

%: %.sh
#  commands to execute (built-in):
    cat $< >$@
    chmod a+x $@

它触发是因为您的脚本名为 "depends.sh"。另外两行是 运行 因为 make 需要 $(DEPS) 数据。