使忽略生成的依赖项 [英] Make ignores generated dependencies

查看:66
本文介绍了使忽略生成的依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的项目编写一个Makefile,该文件会自动生成源文件之间的依赖关系. Makefile如下:

I'm trying to write a Makefile for my project that automatically generates the dependencies between my source files. The Makefile is as follows:

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会重建foo.o.但是,如果quux.h更改,Make会认为foo.o是最新的.我该如何解决?

Generating the dependencies works fine. However, Make ignores them. Suppose I have a file foo.cpp that includes the header file quux.h . If foo.cpp changes Make rebuilds foo.o. However if quux.h changes Make thinks that foo.o is up to date. How can I fix this?

继承人更多信息:make -d whistle_recognition | grep signalscanner.d的输出:

Heres more info: output of 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/前缀...是否可以通过模式替换来解决此问题?

And theres the problem: g++ doesn't include the obj/-prefix to the targets... Is there a way to fix this via pattern substitution?

推荐答案

人们通常有这样的规则来生成依赖项,但实际上是不必要的.

People often have such rules for dependency generation, but they are really unnecessary.

第一次构建项目时,不需要依赖项,因为它仍然会构建所有源代码.只有后续的构建才需要前一个构建的依赖项来检测需要重建的内容.

The first time a project is built no dependencies are necessary since it builds all sources anyway. It is only the subsequent builds that require the dependencies from the previous build to detect what needs to be rebuilt.

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

The dependencies are just a by-product of compilation.

生成的依赖项包含指向相应的.o文件的路径.由于在生成依赖项时未指定.o输出路径,因此这些路径不正确.

The generated dependencies contain paths to corresponding .o files. Since .o output paths were not specified when generating dependencies, those paths are incorrect.

以下解决方案将.d文件与相应的.o文件放置在一起,并且这些.d文件包含指向.o的正确路径.一口气也可以完成编译和依赖项.

The following solution puts .d files along with corresponding .o files and those .d files contain the correct paths to .o. It also does compilation and dependencies in one pass.

修复:

删除这些行:

$(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   

这篇关于使忽略生成的依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆