Make 忽略生成的依赖项
Make ignores generated dependencies
我正在尝试为我的项目编写一个 Makefile,它会自动生成我的源文件之间的依赖关系。
Makefile如下:
CC = g++
CFLAGS = -std=c++11 -Wfatal-errors -fdiagnostics-color=always
LDFLAGS = -lm -lfftw3
SRCDIR = src
OBJDIR = obj
DEPDIR = dep
SRCS = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SRCS))
DEPS = $(patsubst $(SRCDIR)/%.cpp,$(DEPDIR)/%.d,$(SRCS))
PROG = whistle_recognition
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o$(PROG) $(OBJS) $(LDFLAGS)
.PHONY: clean run
$(DEPS): $(DEPDIR)/%.d : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -MM $< -MF $@
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -r $(OBJS) $(DEPS) $(PROG)
run: $(PROG)
./$(PROG)
-include $(DEPS)
生成依赖项工作正常。但是,Make 会忽略它们。
假设我有一个包含头文件 quux.h 的文件 foo.cpp 。
如果 foo.cpp 发生变化,则进行重建 foo.o。但是,如果 quux.h 发生变化,Make 认为 foo.o 是最新的。我该如何解决这个问题?
编辑:
下面是更多信息:make -d whistle_recognition | grep signalscanner.d
:
的输出
Reading makefile 'dep/signalscanner.d' (search path) (don't care) (no ~ expansion)...
Considering target file 'dep/signalscanner.d'.
File 'dep/signalscanner.d' does not exist.
Finished prerequisites of target file 'dep/signalscanner.d'.
Must remake target 'dep/signalscanner.d'.
g++ -std=c++11 -Wfatal-errors -fdiagnostics-color=always -MM src/signalscanner.cpp -MF dep/signalscanner.d
Putting child 0xcda970 (dep/signalscanner.d) PID 2404 on the chain.
Live child 0xcda970 (dep/signalscanner.d) PID 2404
Successfully remade target file 'dep/signalscanner.d'.
Reading makefile 'dep/signalscanner.d' (search path) (don't care) (no ~ expansion)...
Considering target file 'dep/signalscanner.d'.
Finished prerequisites of target file 'dep/signalscanner.d'.
Prerequisite 'src/signalscanner.cpp' is older than target 'dep/signalscanner.d'.
No need to remake target 'dep/signalscanner.d'.
make -p whistle_recognition | signalscanner.o
的输出(缩短):
[...]
obj/signalscanner.o: src/signalscanner.cpp
[...]
signalscanner.o: src/signalscanner.cpp src/signalscanner.h src/frequencyanalyzer.h src/freqanalyzer_test.h src/wav_file.h src/signalscanner_test.h
还有问题:g++
不包含目标的 obj/
前缀...有没有办法通过模式替换来解决这个问题?
人们经常有这样的依赖生成规则,但实际上没有必要。
第一次构建项目时不需要任何依赖项,因为它无论如何都会构建所有源代码。只有后续构建需要前一个构建的依赖项才能检测需要重建的内容。
依赖项只是编译的副产品。
生成的依赖项包含相应 .o
文件的路径。由于在生成依赖项时未指定 .o
输出路径,因此这些路径不正确。
以下解决方案将 .d
文件与相应的 .o
文件放在一起,这些 .d
文件包含到 .o
的正确路径。它还一次完成编译和依赖。
修复:
删除这些行:
$(DEPS): $(DEPDIR)/%.d : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -MM $< -MF $@
-include $(DEPS)
更新这些行:
DEPS = $(OBJS:%.o=%.d)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CFLAGS) -MD -MP -o $@ $<
在底部添加这些行:
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
我正在尝试为我的项目编写一个 Makefile,它会自动生成我的源文件之间的依赖关系。 Makefile如下:
CC = g++
CFLAGS = -std=c++11 -Wfatal-errors -fdiagnostics-color=always
LDFLAGS = -lm -lfftw3
SRCDIR = src
OBJDIR = obj
DEPDIR = dep
SRCS = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SRCS))
DEPS = $(patsubst $(SRCDIR)/%.cpp,$(DEPDIR)/%.d,$(SRCS))
PROG = whistle_recognition
$(PROG): $(OBJS)
$(CC) $(CFLAGS) -o$(PROG) $(OBJS) $(LDFLAGS)
.PHONY: clean run
$(DEPS): $(DEPDIR)/%.d : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -MM $< -MF $@
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -r $(OBJS) $(DEPS) $(PROG)
run: $(PROG)
./$(PROG)
-include $(DEPS)
生成依赖项工作正常。但是,Make 会忽略它们。 假设我有一个包含头文件 quux.h 的文件 foo.cpp 。 如果 foo.cpp 发生变化,则进行重建 foo.o。但是,如果 quux.h 发生变化,Make 认为 foo.o 是最新的。我该如何解决这个问题?
编辑:
下面是更多信息:make -d whistle_recognition | grep signalscanner.d
:
Reading makefile 'dep/signalscanner.d' (search path) (don't care) (no ~ expansion)...
Considering target file 'dep/signalscanner.d'.
File 'dep/signalscanner.d' does not exist.
Finished prerequisites of target file 'dep/signalscanner.d'.
Must remake target 'dep/signalscanner.d'.
g++ -std=c++11 -Wfatal-errors -fdiagnostics-color=always -MM src/signalscanner.cpp -MF dep/signalscanner.d
Putting child 0xcda970 (dep/signalscanner.d) PID 2404 on the chain.
Live child 0xcda970 (dep/signalscanner.d) PID 2404
Successfully remade target file 'dep/signalscanner.d'.
Reading makefile 'dep/signalscanner.d' (search path) (don't care) (no ~ expansion)...
Considering target file 'dep/signalscanner.d'.
Finished prerequisites of target file 'dep/signalscanner.d'.
Prerequisite 'src/signalscanner.cpp' is older than target 'dep/signalscanner.d'.
No need to remake target 'dep/signalscanner.d'.
make -p whistle_recognition | signalscanner.o
的输出(缩短):
[...]
obj/signalscanner.o: src/signalscanner.cpp
[...]
signalscanner.o: src/signalscanner.cpp src/signalscanner.h src/frequencyanalyzer.h src/freqanalyzer_test.h src/wav_file.h src/signalscanner_test.h
还有问题:g++
不包含目标的 obj/
前缀...有没有办法通过模式替换来解决这个问题?
人们经常有这样的依赖生成规则,但实际上没有必要。
第一次构建项目时不需要任何依赖项,因为它无论如何都会构建所有源代码。只有后续构建需要前一个构建的依赖项才能检测需要重建的内容。
依赖项只是编译的副产品。
生成的依赖项包含相应 .o
文件的路径。由于在生成依赖项时未指定 .o
输出路径,因此这些路径不正确。
以下解决方案将 .d
文件与相应的 .o
文件放在一起,这些 .d
文件包含到 .o
的正确路径。它还一次完成编译和依赖。
修复:
删除这些行:
$(DEPS): $(DEPDIR)/%.d : $(SRCDIR)/%.cpp
$(CC) $(CFLAGS) -MM $< -MF $@
-include $(DEPS)
更新这些行:
DEPS = $(OBJS:%.o=%.d)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
$(CC) -c $(CFLAGS) -MD -MP -o $@ $<
在底部添加这些行:
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif