views:

29

answers:

1

Dear gurus,

Please consider the following Makefile:

CC = g++
CFLAGS = -c -O -Wall
EFLAGS = -O -Wall -lm -o

UTILITIES = error.o stream_manip.o mat_ops.o GaussElim.o 
UTILITIES += abstractmatrix.o dvector.o dmatrix.o ConjGrad.o

# All objects
%.o:    %.cpp %.hpp
    $(CC) $(CFLAGS) $<

# Executables (doesn't have extension)
% : %.cpp $(UTILITIES)
    $(CC) $(EFLAGS) % $< $(UTILITIES)

# Specific executable
#TS_CG : TS_CG.cpp $(UTILITIES)
    #$(CC) $(EFLAGS) $@ [email protected] $(UTILITIES)

The match-anything rule (for executables) is supposed to enable me to type the following in a terminal:

make TS_CG

and have make compile the executable called TS_CG. However, make doesn't use my match-all target. Instead it uses its default compilation rule.

On the other hand, if all the objects listed in UTILITIES exist, it does use my match-all target. Hence it seems the matching depends on the existance of the prerequisites.

Apparently:

When a rule is terminal, it does not apply unless its prerequisites actually exist.

(according to make manual ). But my rule is not terminal; it is not marked by a double colon!

So why does this still seem to apply?

I might also ask if anyone has a better solution for differentiating between object targets and executable targets, as I have tried to do in my file.

+1  A: 

I'm surprised that Make is able to build TS_CG when the UTILITIES don't already exist, since I wouldn't expect it to know that TS_CG needs them.

Anyway, when Make is trying to find a rule for TS_CG, all it finds are implicit rules (nothing specific to TS_CG). In particular, it has %: %.cpp $(UTILITIES), which you provided, and %: %.cpp, which is built in. If $(UTILITIES) all exist, then it will use the first rule, otherwise it will move down the list, looking for a rule whose prerequisites do exist, and find the second. Only if it fails to find any rule whose prerequisites exist will it resort to looking for rules to build the prerequisites.

Beta
Thanks for your reply Beta, which I assume is the right answer. It does seem contrary to what was cited from the make manual in my post, but I guess that's because the built-in rule is not overwritten by my rule (which I thought it would be).
Patrick