我发现使用 make 实用程序生成 header 依赖项很晦涩 makefile
对于源文件并使用它构建库或相应地创建可执行文件。
1)
按照手册中的建议:
我尝试了那里提到的方法(在我的例子中,依赖文件存在于 obj/下):
obj/%.d:%.cpp
@set -e; rm -f $@; \
g++ -MM $(CPPFLAGS) ${INC_FLAGS} $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
但这会抛出一个 shell 错误:
/bin/sh: cannot create obj/xyz.d.23030: Directory nonexistent
但是obj目录存在,我不明白sed命令的使用。手册解释说它将任何“.obj : .cpp”规则替换为“.obj .dep : .cpp”,但是如何替换?
2)
我也试过这里提到的方法:
http://mad-scientist.net/make/autodep.html
obj/%.o : %.c
g++ -MMD ${CPPFLAGS} ${INC_FLAGS} -c $$< -o $$@
@cp obj/$*.d obj/$*.P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P; \
rm -f $*.d
使用此依赖文件生成但断言以下错误消息:
"/bin/sh: cannot open obj/%.P: No such file"
sed: -e expression #2, char 4: unterminated `s' command
再次使用 sed
不清楚。
这变得更加模糊......在第二种方法中,如果我不添加单独的规则来创建依赖文件并在对象创建时生成它们,因为“g++ -MP -MMD -c”会创建两个 . o 和.d。 但是如何使用在同一命令中生成的依赖项 makefile 再次编译 .o 呢?
我感谢任何帮助解决发生的错误,并帮助我理解这一点。 或者请提出一些优雅的方法来做同样的事情。
编辑:(如评论中所建议) 在同时使用 -MMD 和 -MP 的第二种方法中,它按预期工作,但我不明白它是如何工作的。这里不需要 sed comamnd,如果相关 header 被修改,源代码将被重建:
对象/%.o : %.c g++ -MMD -MP ${CPPFLAGS} ${INC_FLAGS} -c $$< -o $$@
但是如gcc manual page中所述,如果我没理解错-MMD用来生成依赖(不包括系统头文件)文件和-MP用来为每个头文件生成空规则,但它只修改了对象规则: 即,
obj/%.o obj/%.d : %.cpp
(这就是 GNU make 手册中提到的 sed 正在做的事情)
或者类似的东西,
obj/%.o : %.cpp (list of dependent headers for particular .cpp file)
下面两个命令有什么用,它是如何工作的?
a) sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@;
二)
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < $*.d >> $*.P;
最佳答案
However obj directory is present,
显然不是。这是您需要解决的第一件事。
I didn't understand the use of sed command. The manual explains that it replaces any ".obj : .cpp" rule to ".obj .dep : .cpp", But How ?
特殊的 make 变量 $*
包含与目标模式匹配的词干,这将是目标中与模式匹配的部分 %
sed 命令将 obj/%.o:
替换为 obj.o obj.d:
,正如 Make 手册所述。要解释“如何”,您需要了解 sed,但这并不是一个非常复杂的 sed 命令。
Using this dependency file is generated but following error message is asserted:
那个make recipe有一个#
字符,意思是后面的都是注释,需要用\#
转义
但是,如果您使用的是 GCC,则只需将 -MMD
添加到生成目标文件的常规方法中会更容易,这将生成 .d
文件作为编译的副作用,因此您不需要为 .d
文件创建单独的目标。
关于c++ - Makefile中如何根据各自的header Dependency构建多个Source文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23928569/