Makefile循环依赖

时间:2010-09-09 05:30:26

标签: c makefile dependencies circular-dependency

这是我的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 $<

每当我尝试编译时,都会收到警告make: Circular program.lex <- program.lex.o dependency dropped.我在makefile中看不到program.lex如何依赖program.lex.o。我看到依赖树是如何约4层深,但它看起来不是圆形的。

如何改进makefile?

4 个答案:

答案 0 :(得分:6)

麻烦的是Make中有一个隐含的规则(好吧,无论如何,在GNUMake中),用于链接单个目标文件以构建可执行文件。您的makefile没有说明如何构建program.lex,因此Make会依赖于隐式规则来构建program.lex.o

由于您的布局似乎取决于开始使用program.lex,因此您可以通过为program.lex添加自己的规则来禁止隐式规则(<什么都不做):

program.lex:;

答案 1 :(得分:2)

使用-d:

运行make
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.

有隐式链接规则被调用,而不是我原来的lex 放下

摆脱“.lex。*”扩展

答案 2 :(得分:2)

@aaa carp是正确的,这是一个隐式规则,但它不是LEX规则之一,因为它们从N.c构建N.rN.l,是从N构建N.o的规则。这在我看来就像info (make) Catalogue of Rules中描述的“链接单个目标文件”规则。将.lex文件重命名为.l个文件可以解决此问题。

另外:运行flex,我认为你真的不需要.tab.h文件来构建词法分析器源。试试这个:

%.l.c: %.l
    flex -o$@ $<
program.l.o: program.tab.h

这会将额外的依赖项添加到program.l.o

答案 3 :(得分:0)

我的直接反应是,您需要在显示homework1: program.tab.o program.lex.o

的规则后执行操作
 homework1:  program.tab.o program.lex.o
         ${CC} -o $@ program.tab.o program.lex.o ${LDFLAGS}

但是,由于您还将homework1标记为.PHONY,因此您可能尚未准备好链接该计划。但你的问题再现......

传统上,Lex(或Flex)的源代码保存在.l文件中,而不是.lex文件中,因此我将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 : %.l %.tab.h
    flex -o $@ $<
%.tab.c %.tab.h : %.y
    bison --verbose -o $@ -d $<

警告消息消失。 (我最初使用“touch program.lex program.y”创建了您的环境;然后我将program.lex移至program.l)。

但是,我仍然不太确定破碎版本中发生了什么 - 但它可能确实围绕着@Beta建议的隐式规则。