简体   繁体   中英

Makefile circular dependency

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 Nc or Nr from Nl , and this is a rule that's building N from No . 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.lo .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM