我正在使用gmake并gcc -MM跟踪手册中的标题依赖项.该机制依赖于makefile include指令来导入计算的依赖项.
由于.d文件包含在makefile中,因此它们必须存在于任何目标中,包括clean.因此,在clean做正确的事情之前,必须生成依赖关系,如果一个人无法构建,那么就会clean变得更加混乱.
此外clean,它希望在构建任何目标之前创建所有依赖项.
此外,如果任何文件被更改为包含不存在的文件,则依赖关系解析会中断,并且根本不会构建任何文件.
如果删除了标头,那么现有的依赖项文件仍然将其命名为目标,并且在删除有问题的依赖项文件之前不会构建任何内容...这是无法完成的clean.
include用通配符替换替换模式以包含所有预先存在的依赖项文件可以解决一些问题,但它仍然无法清除损坏的依赖项,并且永远不会删除过时的依赖项文件.有更好的解决方案吗?该手册的示例是否真正用于实际用途?
我正在阅读使用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的人也可以想到这些,但出于某种原因,选择了更复杂的设置.我只是想了解他们的推理,所以我可以动态地做这些.
我的c ++项目有以下设置:
在src文件夹中,有*.cpp和相应的*.h文件,在obj文件夹中我想要我的.o文件.
到目前为止,编译和链接不是问题.但是现在我有太多.cpp和.h文件手动将它们放入Makefile中.所以我决定在makefile中编写这个小指令:
collect_sources:
@echo "collecting source files";
@echo "SRCS = \\" > sources;
@for file in ./src/*.cpp; \
do \
echo "$$file \\" >> sources; \
done
Run Code Online (Sandbox Code Playgroud)
我也这样做
-include sources
Run Code Online (Sandbox Code Playgroud)
在makefile的开头
生成的文件sources看起来很好,尽管在最后一行中有一个我不喜欢的反斜杠.但是afaik也应该是有害的.
我现在还需要自动构建依赖项.在我上一个版本中,我SRCS直接在Makefile中定义了*.cpp文件,以下代码很好:
$(SRCDIR)/%.cpp:
@$(CXX) $(DEPFLAGS) -MT \
"$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
$(addprefix ,$$file) >> $(DEP);
clear_dependencies:
echo "" > $(DEP);
depend: clear_dependencies $(SRCS)
Run Code Online (Sandbox Code Playgroud)
但是包含sources-file,它永远不会到达上面的代码块.
以下是Makefile顶部定义的常量:
CXX = g++
CXXFLAGS = -Wall \
-Wextra \
-Wuninitialized \
-Wmissing-declarations \
-pedantic \
-O3 …Run Code Online (Sandbox Code Playgroud)