As lazy programmers, we have a way around this problem, too.
Here is our new and slightly improved Makefile:
CXXFLAGS = -O -Wall -g SRC = main.c array.c main: $(SRC:.c=.o) gcc $(CXXFLAGS) -o main $^ array.o: array.c array.h gcc $(CXXFLAGS) -c array.c main.o: main.c array.h gcc $(CXXFLAGS) -c main.c %.d: %.c set -e; gcc $(CXXFLAGS) $^ -MM \ | sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \ [ -s $@ ] || rm -f $@
Here, we use a a special kind of rule that is more like a template.
The target ``%.d
'' is saying ``whatever ends with a .d
extension''. However, once the %
symbol is bound to a particular
name, that same name is used in the dependency, ``%.c
''. This means
that every .c
file can generate a .d
file.
The command to do this is rather complicated. At the core, it uses the
-MM
option of gcc
to generate a dependency file.
A dependency file looks just like the dependency part of a rule in a Makefile.
Each backslash \
at the end of the line of the command means
``I'm not done yet, continue on the next line''. The special variable
$^
refers to the all the names in the prerequisite of a rule.
$@
refers to the name of the target.
If you run the command ``make main.d
'', the make
program
should generate the main.d
file. Based on our assumptions,
the content of this file should be as follows;
main.o main.d : main.c array.h
Yep, it says that it also depends on main.c
and main.h
!
Copyright © 2006-10-08 by Tak Auyeung