Makefile 未检测到头文件中的更改?

Makefile not detecting changes in header file?

我有以下 MakeFile:

TARGET = target
CC = gcc-9
CFLAGS = -g -std=c99 -Wall -Wvla -Wextra -Wundef -Wshadow -Wpointer-arith -O2 -D_FORTIFY_SOURCE=2 
OBJ = dep1.o $(TARGET).o dep2.o

all: $(TARGET)

run: $(TARGET)
    ./$<

$(TARGET): $(OBJ)
    $(CC) $(CFLAGS) $^ -o $@

$(TARGET).o: $(TARGET).c
    $(CC) -c $(CFLAGS) $^

dep1.o: dep1.c
    $(CC) -c $(CFLAGS) $^

dep2.o: dep2.c
    $(CC) -c $(CFLAGS) $^

dep1.c: dep1.h
$(TARGET).c: dep1.h

clean:
    rm -rfv $(TARGET) *.o *.a *.dylib *.dSYM

dep1.h 更改时,我希望能够重新编译所涉及的新更改。 dep1.c 包括 dep1.h$(TARGET) 还包括 dep1.h

我在网上尝试了其他几种解决方案,但 none 似乎确实有效。我能够让它工作的唯一方法是更改​​ all: clean $(TARGET)。通过这样做,项目将首先得到清理,然后它会重新编译 dep1.h 中的新更改,但我觉得这是一个非常 hacky 的解决方案,还有更好的方法,但我不确定。

这是不正确的:

dep1.c: dep1.h
$(TARGET).c: dep1.h

C 文件不依赖于 H 文件。说 C 文件依赖于 H 文件意味着您使用 H 文件来创建 C 文件。实际上,是目标文件同时依赖于H和C文件。

dep1.o: dep1.c dep1.h

这是手动写法。您不需要编写规则,隐式规则就可以,但是为此编写显式规则的正确方法需要使用 $< 而不是 $^,因为 $^ 包括所有依赖项(包括头文件)。 $<变量只包含第一个输入,所以你必须先在依赖项中写C文件。

dep1.o: dep1.c dep1.h
    $(CC) -c $(CFLAGS) $<

如果您的编译器支持 -M 标志(GCC 支持,并且许多其他编译器以兼容的方式支持它们),可以使用 -M 标志自动处理此问题。