GNU make:如何防止“-include file.ext”执行目标为 'file.ext' 的规则?

GNU make: how prevent '-include file.ext' from executing a rule the target of which is 'file.ext'?

回顾一下术语,这是 makefile 的结构 'rule':

target:   dependencies ...
          commands
          ...

这是我写的 makefile:

CC = mpicc
SHAREDLIB = libfmd.so
CFLAGS = -fPIC -Wall -Wno-unused-result -O3 -fopenmp
LFLAGS = -lm -fopenmp -lgsl -lgslcblas

OBJS = $(patsubst %.c,%.o,$(wildcard *.c))

.PHONY: all shared clean
all: shared
shared: $(SHAREDLIB)
$(SHAREDLIB): depend.mk $(OBJS)
    $(CC) $(OBJS) -shared -o $@ $(LFLAGS)
depend.mk: *.c *.h
    $(CC) -MM *.c > depend.mk
-include depend.mk
clean:
    rm -f *.o libfmd.so depend.mk

文件夹干净后,我输入 make clean,显示以下行:

mpicc -MM *.c > depend.mk
rm -f *.o libfmd.so depend.mk

在我看来 -include depend.mk 除了包含 depend.mk 之外,还执行 depend.mk 是其目标的规则。我想停止这种行为。

你是对的。请参阅文档中的 How Makefiles are Remade

没有办法阻止这种行为:如果有一条规则创建一个包含的 makefile,如果它已过期,make 将始终重建它,然后 re-invoke 自己读取最新版本。

问题来了,你为什么要避开呢?也许如果您在更高层次上解释了您实际正在寻找的行为,我们可以提供帮助。正如您在此处拥有的那样,可以在不创建任何 depend.mk 文件的情况下创建 .o 文件,然后编译失败,您修改头文件以修复它,但由于 depend.mk 文件没有当您 re-run 使源文件未正确重建时存在。

如果您想准确处理 C/C++ 与 GCC 的依赖关系,您可以看看 Auto-Dependency Generation

depend.mk: *.c *.h
    $(CC) -MM *.c > depend.mk

仅供参考,这是错误的,因为 make 不支持规则字符串中的 shell 通配符。尽管在 shell 本身扩展时可以工作的配方行。

I'd like to stop this behavior

depend.mk是默认目标的先决条件,所以无论如何都是目标。

此外,对于大型项目,预处理到 depend.mk 的速度很慢,因此切换到手动编写的依赖项或使用推荐的方式生成它们是完全有意义的,正如@MadScientist 所建议的。