2013-07-22 110 views
1

我在make(3.81)中遇到与隐式规则有关的错误。的示例代码是:使隐式规则第一次失败,但第二次成功

dongli:test02 dongli$ ls -R 
Makefile a.F90 b.F90 dir 

./dir: 
a.t.F90 

代码间的依赖关系:

a.t.F90: a.F90 
a.t.o: a.t.F90 
b.o: b.F90 
b: a.t.o b.o 

a.F90是中间代码,并且当a.F90被更新a.t.F90将被更新。我的make过程是:

试验1(所有在位置代码):

------------------------------------------------------------- 
Project: >>> test <<< 
------------------------------------------------------------- 
Creating dependency a.t.o 
------------------------------------------------------------- 
-----> ./dir/a.t.F90 
Creating dependency b.o 
------------------------------------------------------------- 
-----> b.F90 
Creating target 'b' 
---> b is created. 
------------------------------------------------------------- 
Finished 
------------------------------------------------------------- 

试验2(触摸a.F90):

dongli:test02 dongli$ touch a.F90 
dongli:test02 dongli$ make 
------------------------------------------------------------- 
Project: >>> test <<< 
------------------------------------------------------------- 
Processing templates in a.F90 
------------------------------------------------------------- 
Creating dependency a.t.o 
------------------------------------------------------------- 
-----> a.t.F90 
gfortran: error: a.t.F90: No such file or directory 
gfortran: fatal error: no input files 
compilation terminated. 
make: *** [a.t.o] Error 1 

试验3:(运行make):

dongli:test02 dongli$ make 
------------------------------------------------------------- 
Project: >>> test <<< 
------------------------------------------------------------- 
Creating dependency a.t.o 
------------------------------------------------------------- 
-----> ./dir/a.t.F90 
Creating dependency b.o 
------------------------------------------------------------- 
-----> b.F90 
Creating target 'b' 
---> b is created. 
------------------------------------------------------------- 
Finished 
------------------------------------------------------------- 

我知道有在make目录缓存(见here)的错误,但对我来说,dir/a.t.F90始终存在。任何想法?谢谢!

UPDATE1:

我用make -d捕捉测试2以下信息:

 Finished prerequisites of target file `a.t.F90'. 
     Prerequisite `a.F90' is newer than target `a.t.F90'. 
     Must remake target `a.t.F90'. 
    Ignoring VPATH name `./dir/a.t.F90'. 

    ... 

     Successfully remade target file `a.t.F90'. 
Finished prerequisites of target file `a.t.o'. 
Prerequisite `a.t.F90' of target `a.t.o' does not exist. 
Must remake target `a.t.o'. 

为什么./dir/a.t.F90是当它的前提条件是a.F90比它更新的忽略?

UPDATE2:

我已经把例子代码上gist

UPDATE3:

我发现了以下相关信息:

如果目标需要重建,GNU使丢弃的文件名VPATH搜索这一目标过程中发现 ,和使用makefile中给出的文件名在本地建立文件 。如果目标不需要重建 ,则GNU make将使用在VPATH 搜索期间找到的文件名。

+0

我已将此错误隔离为最小集合。如果有人需要他们弄清楚什么是错误的,我可以把它们放在某个地方。 –

+0

谢谢,这正是我正在寻找的。 – schwart

回答

0

我做了一个解决方法,我在隐式规则中插入了一些脚本,添加了缺少的目录部分代码,因为VPATH对此有一些限制。

%.o: %.$(1) 
    @echo " Creating dependency [email protected]" 
    @echo $$(seperator) 
    @TEMPLATE_PATTERN='.*\.t\.$(1)'; \           < 
    if [[ $$$$(dirname $$<) == '.' && '$$<' =~ $$$$TEMPLATE_PATTERN ]]; then \ < 
     SRC=$(PROJECT_ROOT)/.codemate/processed_codes/$$<; \     < 
    else \                  < 
     SRC=$$<; \                < 
    fi; \                  < 
    $(FC) -c $$$$SRC $(OPTIONS) $(FFLAGS) $(INCLUDES) 

标记为<

1

您确实需要显示创建这些目标的规则。您已经提供了有关构建的许多方面的大量信息,但调试中最关键的方面之一就是看到规则。

像这样的失败(第一次构建失败,第二次失败)几乎总是由于规则不符合你所描述的规则。如果你告诉作出这样的规则建立一个文件“富”,通过创建类似foo : bar,但随后你写不实际创建“富”,而是“酒吧/富”,类似的配方:

foo : bar ; cp bar bar/foo 

那就错了。此类问题的另一个常见原因是您定义了一个构建“foo.x”的规则,但它也构建了“foo.y”,并且您不会告诉它,但稍后使用“foo.y”作为先决条件,那是行不通的。你必须定义一个规则告诉make这两个文件是从配方的一次调用产生的,如:

%.x %.y : %.z ; cp $< $*.x && cp $< $*.y 

最后,你提到VPATH上面,它看起来像你正在尝试使用VPATH找到生成的文件。这是行不通的。 VPATH只能用于用于查找源文件(文件不知道如何构建并期望始终存在)。没有更多关于你的makefile以及规则是如何构建的,这就是我们所能说的。

编辑补充:

我不知道它是真的有必要用这么多的评估和来电来访;通常人们似乎会直接选择这些非常强大的工具,而简单的工具就足够了。无论如何,你遇到的问题与我在上面第一条评论中所怀疑的完全相同。你有这样的规则:

%.t.F90: %.$(1) 
     @echo " Processing templates in $$^" 
     @echo $$(seperator) 
     @cp $$< dir/[email protected] 

注意最后一行,在那里,而不是创建您要创建dir/[email protected][email protected];这正是我上面描述的情况。无论什么时候你有一个规则建立的东西不完全是[email protected],几乎100%肯定规则是错误的。您需要将其编写为:

dir/%.t.F90: %.$(1) 
     @echo " Processing templates in $$^" 
     @echo $$(seperator) 
     @cp $$< [email protected] 

并且可能会有更多更改以匹配该目标。

+0

感谢您的帮助!我已将代码放在要点https://gist.github.com/dongli/6059091上。 –

相关问题