make: Automatic Prerequisites

1 
1 4.14 Generating Prerequisites Automatically
1 ===========================================
1 
1 In the makefile for a program, many of the rules you need to write often
1 say only that some object file depends on some header file.  For
1 example, if 'main.c' uses 'defs.h' via an '#include', you would write:
1 
1      main.o: defs.h
1 
1 You need this rule so that 'make' knows that it must remake 'main.o'
1 whenever 'defs.h' changes.  You can see that for a large program you
1 would have to write dozens of such rules in your makefile.  And, you
1 must always be very careful to update the makefile every time you add or
1 remove an '#include'.
1 
1    To avoid this hassle, most modern C compilers can write these rules
1 for you, by looking at the '#include' lines in the source files.
1 Usually this is done with the '-M' option to the compiler.  For example,
1 the command:
1 
1      cc -M main.c
1 
1 generates the output:
1 
1      main.o : main.c defs.h
1 
1 Thus you no longer have to write all those rules yourself.  The compiler
1 will do it for you.
1 
1    Note that such a rule constitutes mentioning 'main.o' in a makefile,
1 so it can never be considered an intermediate file by implicit rule
1 search.  This means that 'make' won't ever remove the file after using
1 it; ⇒Chains of Implicit Rules Chained Rules.
1 
1    With old 'make' programs, it was traditional practice to use this
1 compiler feature to generate prerequisites on demand with a command like
1 'make depend'.  That command would create a file 'depend' containing all
1 the automatically-generated prerequisites; then the makefile could use
1 'include' to read them in (⇒Include).
1 
1    In GNU 'make', the feature of remaking makefiles makes this practice
1 obsolete--you need never tell 'make' explicitly to regenerate the
1 prerequisites, because it always regenerates any makefile that is out of
1 date.  ⇒Remaking Makefiles.
1 
1    The practice we recommend for automatic prerequisite generation is to
1 have one makefile corresponding to each source file.  For each source
1 file 'NAME.c' there is a makefile 'NAME.d' which lists what files the
1 object file 'NAME.o' depends on.  That way only the source files that
1 have changed need to be rescanned to produce the new prerequisites.
1 
1    Here is the pattern rule to generate a file of prerequisites (i.e., a
1 makefile) called 'NAME.d' from a C source file called 'NAME.c':
1 
1      %.d: %.c
1              @set -e; rm -f $@; \
1               $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
1               sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
1               rm -f $@.$$$$
1 
1 ⇒Pattern Rules, for information on defining pattern rules.  The
1 '-e' flag to the shell causes it to exit immediately if the '$(CC)'
1 command (or any other command) fails (exits with a nonzero status).
1 
1    With the GNU C compiler, you may wish to use the '-MM' flag instead
11 of '-M'.  This omits prerequisites on system header files.  ⇒
 Options Controlling the Preprocessor (gcc)Preprocessor Options, for
1 details.
1 
1    The purpose of the 'sed' command is to translate (for example):
1 
1      main.o : main.c defs.h
1 
1 into:
1 
1      main.o main.d : main.c defs.h
1 
1 This makes each '.d' file depend on all the source and header files that
1 the corresponding '.o' file depends on.  'make' then knows it must
1 regenerate the prerequisites whenever any of the source or header files
1 changes.
1 
1    Once you've defined the rule to remake the '.d' files, you then use
1 the 'include' directive to read them all in.  ⇒Include.  For
1 example:
1 
1      sources = foo.c bar.c
1 
1      include $(sources:.c=.d)
1 
1 (This example uses a substitution variable reference to translate the
1 list of source files 'foo.c bar.c' into a list of prerequisite
1 makefiles, 'foo.d bar.d'.  ⇒Substitution Refs, for full
1 information on substitution references.)  Since the '.d' files are
1 makefiles like any others, 'make' will remake them as necessary with no
1 further work from you.  ⇒Remaking Makefiles.
1 
1    Note that the '.d' files contain target definitions; you should be
1 sure to place the 'include' directive _after_ the first, default goal in
1 your makefiles or run the risk of having a random object file become the
1 default goal.  ⇒How Make Works.
1