new_perl
new_perl

Reputation: 7735

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

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

NetStats.o depends on 3 objects, but only the first one($<) is involved in the compilation,what's the rationale?

And what does the -MF -MT thing mean?

Upvotes: 2

Views: 146

Answers (2)

Viktor Latypov
Viktor Latypov

Reputation: 14467

First,

 -MF $(OBJDIR)/NetStats.d

generates the dependency file which then allows automatic rebuilds of the sources if something changed in the header.

So, it the NetStats.cpp is changed, it will be rebuilt as soon as you run make with a target which depends on NetStats.o

Second, from GCC docs:

 -MT target

Change the target of the rule emitted by dependency generation. By default CPP takes the name of the main input file, including any path, deletes any file suffix such as `.c', and appends the platform's usual object suffix. The result is the target.

An -MT option will set the target to be exactly the string you specify. If you want multiple targets, you can specify them as a single argument to -MT, or use multiple -MT options.

For example, -MT '$(objpfx)foo.o' might give $(objpfx)foo.o: foo.c


.d files look just like a part of makefile. Here's an extract from Canvas.d for one of my projects:

 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 \
    .....

Basically, the preprocessors searches all the dependencies in the .cpp file and generates an additional target to specify these dependencies.

To see what .d files really are one might try to write the test.c

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

and run the gcc -MD -c test.c command

For my MingW environment it is

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

To exclude the system include files from dependency lists one might also use the -MM switch.

Upvotes: 2

paxdiablo
paxdiablo

Reputation: 881113

It's often the case that an object file may depend on more things than you have to compile. Classic example:

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

In that case, you don't give the headers to the compile line, they're bought in by the compiler itself when processing the source.

But you still want the dependency, since you want to recompile if any headers included by myprog.c are changed.

Upvotes: 1

Related Questions