我正在阅读使用GNU Make管理项目,并在第2.7章 - 自动依赖关系生成中找到了这个例子.作者从GNU手册中说出了他们:
%.d: %c
$(CC) -M $(CPPFLAGS $< > $@.$$$$; \
sed s',\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
Run Code Online (Sandbox Code Playgroud)
但是,我能够用这个做同样的事情(注意sed):
-include $(subst .c,.d,$(SOURCES))
%.d: %.c
@$(CC) -M $(CPPFLAGS) $< | sed 's|:| $*.d : |' > $@;
Run Code Online (Sandbox Code Playgroud)
所有这些行都是生成依赖项,然后添加*.d名称.他们不得不改变第一行:
foo.o: bar.h foo.h fubar.h
Run Code Online (Sandbox Code Playgroud)
to foo.o foo.d:bar.h foo.h fubar.h
我更简单,似乎工作得很好,但我认为GNU伙伴有他们sed命令的理由.也:
sed?为什么不简单地将它作为commond line参数我知道GNU的人也可以想到这些,但出于某种原因,选择了更复杂的设置.我只是想了解他们的推理,所以我可以动态地做这些.
Eld*_*mov 12
实际上连规则本身都没有必要.在Paul D. Smith撰写的高级自动依赖生成文章中,可以很好地概述生成Make风格依赖关系的不同方法.
毕竟,以下规则应该足够(在使用GCC的情况下):
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -o $@ -c $<
-include $(SOURCES:.c=.d)
Run Code Online (Sandbox Code Playgroud)
我之前也回答过类似的问题.它包含选项的解释(GCC手册的引用)-MMD -MP.
解决问题:Why do a redirect of the file into sed? 如果您这样做:
@$(CC) -M $(CPPFLAGS) $< | sed 's|:| $*.d : |' > $@;
Run Code Online (Sandbox Code Playgroud)
并且编译失败(出错并且不生成任何输出),您将创建一个空的目标文件。当make再次运行时,它将看到新创建的空文件并且不会重新生成它,从而导致构建错误。使用中间文件是一种常见的防御策略,以避免意外创建空目标。