Here is my Makefile:
.PHONY: all homework1
CFLAGS= -g -O0 -Wall -Werror -Wno-unused-function
LDFLAGS= -lm
all : homework1
homework1 : program.tab.o program.lex.o
%.o : %.c
gcc -o$@ -c $(CFLAGS) $<
%.lex.c : %.lex %.tab.h
flex -o$@ $<
%.tab.c %.tab.h : %.y
bison --verbose -o$@ -d $<
Whenever I try to compile, I get the warning make: Circular program.lex <- program.lex.o dependency dropped.
I don't see how program.lex
is dependent on program开发者_运维问答.lex.o
at all in the makefile. I see how the dependency tree is about 4 layers deep, but it doesn't look circular.
How can I improve my makefile?
The trouble is that there is an implicit rule in Make (well, in GNUMake anyway) for linking a single object file to build en executable. Your makefile says nothing about how to build program.lex
, so Make falls back on the implicit rule to build it from program.lex.o
.
Since your your layout seems to depend on having program.lex
to begin with, you can suppress the implicit rule by adding your own rule for program.lex
(which does nothing):
program.lex:;
run make with -d:
Considering target file `all'.
File `all' does not exist.
Considering target file `homework1'.
File `homework1' does not exist.
Considering target file `program.lex.o'.
File `program.lex.o' does not exist.
Looking for an implicit rule for `program.lex.o'.
Trying pattern rule with stem `program.lex'.
Trying implicit prerequisite `program.lex.c'.
Found an implicit rule for `program.lex.o'.
Considering target file `program.lex.c'.
Looking for an implicit rule for `program.lex.c'.
Trying pattern rule with stem `program'.
Trying implicit prerequisite `program.lex'.
Found an implicit rule for `program.lex.c'.
Considering target file `program.lex'.
Looking for an implicit rule for `program.lex'.
Trying pattern rule with stem `program.lex'.
Trying implicit prerequisite `program.lex.o'.
Found an implicit rule for `program.lex'.
make: Circular program.lex <- program.lex.o dependency dropped.
there is implicit link rule which gets invoked, not lex I originally put down
get rid off ".lex.*" extensions
@aaa carp is correct that is an implicit rule, but it's not one of the LEX
rules, because they build N.c
or N.r
from N.l
, and this is a rule that's building N
from N.o
. That looks to me like the "Linking a single object file" rule, described in info (make) Catalogue of Rules
. Renaming your .lex
files to .l
files will fix this problem.
Also: running flex
, I don't think you really need the .tab.h
file to build the lexer source. Try this instead:
%.l.c: %.l
flex -o$@ $<
program.l.o: program.tab.h
This will add the extra dependency to program.l.o
.
My immediate reaction was that you need an action after the rule that says homework1: program.tab.o program.lex.o
:
homework1: program.tab.o program.lex.o
${CC} -o $@ program.tab.o program.lex.o ${LDFLAGS}
However, since you've also marked homework1
as .PHONY
, maybe you are not ready to link the program yet. But your problem reproduces...
Conventionally, the source for Lex (or Flex) is kept in a .l
file, not in a .lex
file, so I changed the makefile to:
.PHONY: all homework1
CFLAGS= -g -O0 -Wall -Werror -Wno-unused-function
LDFLAGS= -lm
all : homework1
homework1 : program.tab.o program.lex.o
%.o : %.c
gcc -o $@ -c $(CFLAGS) $<
%.lex.c : %.l %.tab.h
flex -o $@ $<
%.tab.c %.tab.h : %.y
bison --verbose -o $@ -d $<
The warning message goes away. (I created your environment by using 'touch program.lex program.y
' initially; I then moved program.lex
to program.l
).
However, I'm still not quite sure what is going on in the broken version - but it probably does revolve around implicit rules as suggested by @Beta.
精彩评论