【问题标题】:Makefile circular dependencyMakefile 循环依赖
【发布时间】:2010-09-09 05:30:25
【问题描述】:

这是我的 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 &lt;- program.lex.o dependency dropped. 我在 makefile 中根本看不到 program.lex 是如何依赖于 program.lex.o 的。我看到依赖树大约有 4 层深,但它看起来不是圆形的。

如何改进我的 makefile?

【问题讨论】:

  • 不仅您的问题被标记为“作业”(没有任何人要求您这样做),而且您的可执行文件也被命名为“作业”。只是一个观察!没有评论:D
  • 这是作业。当然,作业是写flex和bison文件,而不是makefile。 makefile 应该是最简单的部分:P
  • 根据我的经验,Makefile 绝非易事。

标签: c makefile dependencies circular-dependency


【解决方案1】:

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

由于您的布局似乎依赖于以 program.lex 开头,您可以通过为 program.lex 添加自己的规则来抑制隐式规则(什么都不做):

program.lex:;

【讨论】:

  • 消除隐含规则的好技巧。我以前没见过。
【解决方案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.*”扩展名

【讨论】:

  • 不 - 这是试图链接由单个目标文件制成的程序的规则。
【解决方案3】:

@aaa carp 是正确的,这是一条隐含规则,但它不是 LEX 规则之一,因为它们从 N.l 构建 N.cN.r,而这是构建 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

【讨论】:

  • 谢谢!修复问题。希望我知道所有这些隐含的规则。你知道我能不能把它们关掉吗?
  • @Mike:gnu.org/software/make/manual/make.html#Catalogue-of-Rules 是所有规则的目录。 make -r 将在没有隐式规则的情况下运行,但我不记得它是否作为 MAKEFLAGS 变量中的设置起作用,或者是否必须在命令行中指定。
【解决方案4】:

我的第一反应是,您需要在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 建议的隐式规则。

【讨论】:

  • “破解版”中的“破损”来自“链接单个对象文件”规则(foo.o -> foo)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
  • 2010-09-12
相关资源
最近更新 更多