2017-02-16 82 views
2

我正在学习makefiles,并且不能将我的头围绕在我遇到的这个问题上,并想了解如何/为什么会失败。Makefile模式规则不起作用

我在src目录中有半打erlang文件。我想将它们编译成一个ebin目录,而不必为它们中的每一个定义规则。根据Gnu make文档,pattern rules should be right up my alley

但是,使用下面的makefile,我从make中得到的全部是make: *** No targets. Stop。这是为什么?

ebin/%.beam: src/%.erl 
    mkdir -p ebin 
    erlc -o ebin $< 

编辑:基于this answer,我现在明白了,我将不得不使用make ebin/cmplx.beam显式声明的目标,例如。然而,我仍然不明白我应该如何编写我的makefile来获得我想要的行为 - 因为我有六个目标(甚至更多其他项目),这似乎是不必要的麻烦。有没有办法根据源文件名来定义目标?

+0

可能的[Makefile模式规则失败?]的重复(http://stackoverflow.com/questions/5155510/makefile-pattern-rule-fails) –

回答

2

目标规则告诉make,每当它需要产生一个beam文件中ebin目录,且存在相应的erl文件中src目录下,它可以使用erlc

但是,这并不能说明这是它需要做的。你可以明确地告诉做什么,它需要给它的命令行上的目标要做到:

make ebin/foo.beam 

如果你不给在命令行上的目标,使会选择第一个非模式规则makefile作为它的目标。然而,你的makefile没有任何非模式规则,所以没有目标。

您可能想要的是,对于src中的每个现有的erl文件,make应该考虑将ebin中对应的beam文件作为目标。您可以实现通过调用wildcardpatsubst

erl_files=$(wildcard src/*.erl) 
beam_files=$(patsubst src/%.erl,ebin/%.beam,$(erl_files)) 

ebin/%.beam: src/%.erl 
     mkdir -p ebin 
     erlc -o ebin $< 

all: $(beam_files) 

(缩进线必须是实际的物理制表符,而不是空格。)

这样一来,运行make将重建所有beam文件,这些文件出日期。 all被选为默认目标,并且依次取决于现有或潜在的所有beam,其中每个依次取决于相应的erl文件。

这个技巧是described in the GNU make manual