Reputation: 27
I am writting a makefile for my tiny project,here is my makefile:
CC=gcc
CFLAGS=-I.
DEPS = parse.h y.tab.h
OBJ = y.tab.o lex.yy.o parse.o
FLAGS = -g -Wall
LDFLAGS = -lpthread
default:all
all: lisod
lex.yy.c: lexer.l
flex $^
y.tab.c: parser.y
yacc -d $^
%.o: %.c $(DEPS)
$(CC) $(FLAGS) -c -o $@ $< $(CFLAGS)
example: $(OBJ) example.o
$(CC) -o $@ $^ $(CFLAGS)
lisod: lisod.o csapp.o $(OBJ) $(LDFLAGS)
$(CC) -o $@ $^ $(CFLAGS) $(FLAGS)
# hello:
# echo hello
clean:
rm -f *~ *.o example lex.yy.c y.tab.c y.tab.h lisod
but when i execute make,it appears that no -g option,thus i can't debug with gdb here is part of the output of make:
gcc -I. -c -o lisod.o lisod.c
gcc -I. -c -o csapp.o csapp.c
Upvotes: 0
Views: 46
Reputation: 181574
but when i execute make,it appears that no -g option,thus i can't debug with gdb
If you look carefully at your output, you will realize that the issue is not so much the -g
flag specifically, but that the pattern rule you've provided is not being used at all. The fact that the -I.
option appears first instead of last establishes this.
What you are getting is the default rule for building .o files from corresponding .c files. Rules you provide override built-in ones when both apply, but in make
's analysis, your pattern rule does not (always) apply because it designates prerequisites (at least y.tab.h
) that may not initially exist and for which there is no build rule. (See How Patterns Match in the GNU Make manual.)
You're in fact running into a classic problem with make
's model of the world: it doesn't deal very cleanly with recipes that generate multiple outputs that serve as prerequisites for other rules. You might be interested in the Automake manual's discussion of this topic, which is mostly addressed generically at conforming make
implementations, and which provides a series of increasingly complex (and increasingly flexible) rules. This simple pattern is recommended as "enough for most cases":
y.tab.c: parser.y
yacc -d $^
# Add this, so make knows where y.tab.h comes from:
y.tab.h: y.tab.c
# I assume that parse.h is an ordinary source, not a generated one
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) $(FLAGS) -c -o $@ $<
Note that I moved the CFLAGS
to the beginning of the compile command instead of the end. Though it probably does not make a difference in your case, it is not entirely stylistic, as the order of options on the build command line is significant. That effects link commands greatly, but it can effect compile commands too, depending on the options involved.
Update:
As long as you're relying on feature specific to GNU make
(pattern rules) anyway, however, you might as well make full use of them. As @MadScientist observed in comments, GNU make
treats pattern rules with multiple targets differently than it (and other make
s) treat ordinary rules with multiple targets: it understands and expects one execution of the rule's recipe to create all the targets matched to one set of prerequisites via the pattern.
Thus, if you're going to use pattern rules at all, then as MS observes, this is even better than the above "enough for most cases" alternative:
%.tab.c %.tab.h : parser.%
yacc -d $^
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) $(FLAGS) -c -o $@ $<
Upvotes: 1