c++ - Makefile中如何根据各自的header Dependency构建多个Source文件?

标签 c++ unix sed makefile gnu-make

我发现使用 make 实用程序生成 header 依赖项很晦涩 makefile对于源文件并使用它构建库或相应地创建可执行文件。

1)

按照手册中的建议:

http://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html#Automatic-Prerequisites

我尝试了那里提到的方法(在我的例子中,依赖文件存在于 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/

相关文章:

c++ - 在 64 位系统上更大的指针有什么好处?

c++ - 我如何使用方法来处理大量指针?

linux - 异步和同步 I/O 操作系统是否独立?

bash - 为什么从文件中获取标准输入与通过管道接收标准输入不同?

bash - 查找并替换为 sed

sed:用下划线替换引号内的空格

c++ - 变量嵌套 for 循环

c++ - cygwin:lib 在 vi​​sual studio 2005 中不受支持

python - 获取函数的局部变量

bash - 通过 sed 的管道问题