2
$(OBJDIR)/NetStats.o: ../../../source/network/NetStats.cpp $(GCH) | prebuild
    $(CXX) $(CXXFLAGS) -MF $(OBJDIR)/NetStats.d -MT "$@" -o "$@" -c "$<"

NetStats.o依赖于3对象,但编译中只涉及第一个($<),这是什么原理?

-MF -MT 是什么意思?

4

2 回答 2

2

第一的,

 -MF $(OBJDIR)/NetStats.d

生成依赖文件,如果头文件发生变化,则允许自动重建源文件。

因此,如果 NetStats.cpp 发生更改,它将在您使用依赖于 NetStats.o 的目标运行 make 后立即重建

其次,来自 GCC 文档:

 -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:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/stdio.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw_mac.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/vadefs.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sdks/_mingw_directx.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sdks/_mingw_ddk.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw_print_push.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sec_api/stdio_s.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/_mingw_print_pop.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/stdlib.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/include-fixed/limits.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/include-fixed/syslimits.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/limits.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/sec_api/stdlib_s.h \
 c:\eqmingw\bin\../lib/gcc/x86_64-w64-mingw32/4.6.0/../../../../x86_64-w64-mingw32/include/malloc.h

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

于 2012-05-15T11:35:36.050 回答
1

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

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

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

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

于 2012-05-15T11:36:51.510 回答