忽略生成的依赖项

时间:2015-09-03 15:28:19

标签: build makefile gnu-make

我试图为我的项目编写一个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改变了make rebuilds foo.o.但是如果quux.h发生了变化,那么认为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/ - 前缀......有没有办法通过模式替换解决这个问题?

1 个答案:

答案 0 :(得分:2)

人们经常会有依赖关系生成的规则,但实际上并没有必要。

第一次构建项目时,不需要依赖项,因为它无论如何都会构建所有源代码。只有后续构建才需要先前构建的依赖项来检测需要重建的内容。

依赖关系只是编译的副产品。

生成的依赖项包含指向相应.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