gpt4 book ai didi

c++ - 使用 -MM 生成包含指令和依赖项

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:58:09 25 4
gpt4 key购买 nike

如果包含的目标已过期或不存在,我希望由包含指令触发构建规则。

目前的 makefile 看起来像这样:

program_NAME := wget++
program_H_SRCS := $(wildcard *.h)
program_CXX_SRCS := $(wildcard *.cpp)
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o}
program_OBJS := $(program_CXX_OBJS)

DEPS = make.deps

.PHONY: all clean distclean

all: $(program_NAME) $(DEPS)

$(program_NAME): $(program_OBJS)
$(LINK.cc) $(program_OBJS) -o $(program_NAME)

clean:
@- $(RM) $(program_NAME)
@- $(RM) $(program_OBJS)
@- $(RM) make.deps

distclean: clean

make.deps: $(program_CXX_SRCS) $(program_H_SRCS)
$(CXX) $(CPPFLAGS) -MM $(program_CXX_SRCS) > make.deps

include $(DEPS)

问题是 include 指令似乎在构建 make.deps 的规则之前执行,这实际上意味着如果 make.deps 不存在,make 要么没有依赖列表,要么总是从中获取 make.deps以前的版本而不是当前版本。

例如:

$ make clean 
$ make
makefile:32: make.deps: No such file or directory
g++ -MM addrCache.cpp connCache.cpp httpClient.cpp wget++.cpp > make.deps
g++ -c -o addrCache.o addrCache.cpp
g++ -c -o connCache.o connCache.cpp
g++ -c -o httpClient.o httpClient.cpp
g++ -c -o wget++.o wget++.cpp
g++ addrCache.o connCache.o httpClient.o wget++.o -o wget++

编辑

我读了docs for the include directive ,听起来如果包含目标不存在,它将继续处理父 makefile 并尝试构建目标,但我并不完全清楚这是如何工作的:

If an included makefile cannot be found in any of these directories, a warning message is generated, but it is not an immediately fatal error; processing of the makefile containing the include continues. Once it has finished reading makefiles, make will try to remake any that are out of date or don't exist. See section How Makefiles Are Remade. Only after it has tried to find a way to remake a makefile and failed, will make diagnose the missing makefile as a fatal error.

回答

这是对我接受的答案的修改。缺少的一件事是依赖文件也依赖于源,除非将它们添加到正在包含的 deps 文件中,否则不会重新生成:

%.d: $(program_CXX_SRCS)
@ $(CXX) $(CPPFLAGS) -MM $*.cpp | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $@

sed.d 文件的名称添加到每个依赖行的开头,如下所示:

foo.d foo.o: foo.cpp foo.h bar.h baz.h

我从这篇关于递归 make 的危险的惊人论文中得到了这个想法:

Recursive Make Considered Harmful

我还将以下内容添加到 makefile 中:

clean_list += ${program_SRCS:.c=.d}

# At the end of the makefile
# Include the list of dependancies generated for each object file
# unless make was called with target clean
ifneq "$(MAKECMDGOALS)" "clean"
-include ${program_SRCS:.c=.d}
endif

最佳答案

您依赖隐式规则来编译您的 .cpp 文件。您必须重新定义它以使用将创建依赖文件的 -MM 和 -MF 标志。

%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ -MM -MF $@.d

然后,您必须使用 -include 在 Makefile 中包含这些依赖文件,当依赖文件尚不存在时(第一次或清理后)不会出错。

program_DEPS := $(program_OBJS:.o=.o.d)
-include $(program_DEPS)

并且记得在 clean 规则中为依赖文件添加 rm 命令。

关于c++ - 使用 -MM 生成包含指令和依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2801532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com