$(OBJDIR)/NetStats.o: ../../../source/network/NetStats.cpp $(GCH) | prebuild
$(CXX) $(CXXFLAGS) -MF $(OBJDIR)/NetStats.d -MT "$@" -o "$@" -c "$<"
NetStats.o
取决于3
个对象,但只有第一个($<
)参与编译,理由是什么?
-MF -MT是什么意思?
答案 0 :(得分:2)
首先,
-MF $(OBJDIR)/NetStats.d
生成依赖文件,如果标题中发生了某些变化,则允许自动重建源。
因此,NetStats.cpp已更改,只要您使用依赖于NetStats.o的目标运行make,就会重建它。
其次,来自GCC docs:
-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开关。
答案 1 :(得分:1)
通常情况下,目标文件可能依赖于比编译更多的东西。经典例子:
myprog.o: myprog.c header1.h header2.h
gcc -c -o myprog.o myprog.c
在这种情况下,您不会将标题提供给编译行,它们在处理源时由编译器本身购买。
但是仍然想要依赖项,因为如果myprog.c
包含的任何标题发生更改,您需要重新编译。