开发者

Makefile circular dependency

开发者 https://www.devze.com 2023-01-15 04:14 出处:网络
Here is my Makefile: .PHONY: all homework1 CFLAGS= -g -O0 -Wall -Werror -Wno-unused-function LDFLAGS= -lm

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消