tags:

views:

221

answers:

4

When I run make all on the following Makefile I get this error:

Makefile:5: *** missing separator. Stop.

What's wrong with it and how do I fix it?

LEX = lex
YACC = yacc 
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c 
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
+1  A: 

Generally, this sort of error means that you have erroneously used spaces instead of a tab when indenting lines in your Makefile.

Your example appears to have been pasted without indenting, but I can't tell whether your file really looks like that or whether there was a paste error. In the following:

calcu: y.tab.o lex.yy.o
        $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl

the whitespace before $(CC) must be a tab, not spaces:

calcu: y.tab.o lex.yy.o
        $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
|tab-->|
Greg Hewgill
+1  A: 

Whitespace formatting can make answering this difficult. In Make whitespace is critical. Actions must have a tab character in front to be recognised as such by Make. e.g.


calcu: y.tab.o lex.yy.o
\t$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl y.tab.c y.tab.h: parser.y

Note that \t means <tab>. Not 4 spaces, not any spaces, but tab!

Also ensure there is a blank line between dependencies, i.e. if you're going to say file: dependencies then ensure there is a blank line immediately above.

PP
+6  A: 

G'day,

You need tabs to indent the lines underneath each target.

LEX = lex
YACC = yacc 
CC = gcc
calcu: y.tab.o lex.yy.o
    $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
    $(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
    $(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c 
    $(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
    $(LEX) calclexer.l
clean:
    rm *.o
    rm *.c
    rm calcu

BTW General convention is that you should use braces rather than brackets for your macros. Using brackets are a legacy thing left over from substituting an object back in to an archive. So the above is better expressed as:

LEX = lex
YACC = yacc 
CC = gcc
calcu: y.tab.o lex.yy.o
    ${CC} -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
    ${YACC} -d parser.y
y.tab.o: y.tab.c parser.h
    ${CC} -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c 
    ${CC} -c lex.yy.c
lex.yy.c: calclexer.l parser.h
    ${LEX} calclexer.l
clean:
    rm *.o
    rm *.c
    rm calcu

HTH

Rob Wells
+5  A: 

You need to indent like so. (Note: they changed my tabs into a 4space. Make sure to indent with the tab character.)

LEX = lex
YACC = yacc 
CC = gcc

calcu: y.tab.o lex.yy.o
    $(CC) -o calcu y.tab.o lex.yy.o -ly -lfl

y.tab.c y.tab.h: parser.y
    $(YACC) -d parser.y

y.tab.o: y.tab.c parser.h
    $(CC) -c y.tab.c

lex.yy.o: y.tab.h lex.yy.c 
    $(CC) -c lex.yy.c

lex.yy.c: calclexer.l parser.h
    $(LEX) calclexer.l

clean:
    rm *.o
    rm *.c
    rm calcu

The extra blank lines aren't required but the indenting is. You'll also need to make an all rule if you want to make all.

yjerem
Should specify that action lines must be indented with a leading tab and not with a leading space...
dmckee