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
标志自动处理此问题。
我有以下 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
标志自动处理此问题。