我如何理解这个生成文件规则的细节

How do I make sense of the nitty gritty of this makefile rule?

本文关键字:文件 规则 细节 何理解      更新时间:2023-10-16
$(OBJDIR)/NetStats.o: ../../../source/network/NetStats.cpp $(GCH) | prebuild
    $(CXX) $(CXXFLAGS) -MF $(OBJDIR)/NetStats.d -MT "$@" -o "$@" -c "$<"

NetStats.o取决于3对象,但编译中只涉及第一个($<(,理由是什么?

-

MF -MT 是什么意思?

首先,

 -MF $(OBJDIR)/NetStats.d

生成依赖项文件,然后允许在标头中发生更改时自动重建源。

因此,NetStats.cpp 被更改了,一旦您使用依赖于 NetStats.o 的目标运行 make 时,它就会重建

其次,来自海湾合作委员会文档:

 -MT target

更改依赖项生成发出的规则的目标。默认情况下,CPP 采用主输入文件的名称(包括任何路径(,删除任何文件后缀(如".c"(,并附加平台的常用对象后缀。结果就是目标。

-MT 选项会将目标设置为您指定的字符串。如果需要多个目标,可以将它们指定为 -MT 的单个参数,或使用多个 -MT 选项。

例如,-MT '$(objpfx(foo.o' 可能会给出 $(objpfx(foo.o: foo.c


.d文件看起来就像makefile的一部分。以下是我的一个项目的 Canvas.d 摘录:

 Out/Mac/ppc64/Obj/Canvas.o: Src/Linderdaum/Renderer/Canvas.cpp 
     Src/Linderdaum/Renderer/Canvas.h Src/Linderdaum/Core/iObject.h 
    /usr/include/c++/4.0.0/deque /usr/include/c++/4.0.0/bits/functexcept.h 
    /usr/include/c++/4.0.0/exception_defines.h 
    .....

基本上,预处理器搜索.cpp文件中的所有依赖项,并生成一个附加目标来指定这些依赖项。

要了解 .d 文件到底是什么,可以尝试编写 test.c

 #include <stdio.h>
 #include <stdlib.h>
 int main() { return 0; }

并运行 gcc -MD -c test.c 命令

对于我的MingW环境,它是

test.o: test.c 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/stdio.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw_mac.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/vadefs.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sdks/_mingw_directx.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sdks/_mingw_ddk.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw_print_push.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sec_api/stdio_s.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw_print_pop.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/stdlib.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/include-fixed/limits.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/include-fixed/syslimits.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/limits.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sec_api/stdlib_s.h 
 c:eqmingwbin../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/malloc.h

要从依赖关系列表中排除系统包含文件,还可以使用 -MM 开关。

通常情况下,目标文件可能依赖于比您必须编译的内容更多的内容。经典示例:

myprog.o: myprog.c header1.h header2.h
    gcc -c -o myprog.o myprog.c

在这种情况下,您不会将标头提供给编译行,它们在处理源代码时由编译器本身购买。

但是您仍然需要依赖项,因为如果更改了myprog.c包含的任何标头,则要重新编译。