Makefile模式规则不起作用

时间:2017-02-16 10:59:28

标签: makefile erlang

我正在学习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以获得我想要的行为 - 因为我有六个目标(在其他项目甚至更多),这似乎是一个不必要的麻烦。有没有办法根据源文件名定义目标?

1 个答案:

答案 0 :(得分:2)

目标规则告诉make,只要需要在beam目录中生成ebin文件,并且erl目录中存在相应的src文件,它可以使用erlc

然而,这并不能说明这是它需要做的事情。你可以通过在命令行上给它一个目标来明确告诉make它需要做什么:

make ebin/foo.beam

如果您未在命令行上提供目标,make将选择makefile中的第一个非模式规则作为其目标。但是,您的makefile没有任何非模式规则,因此没有目标。

您可能想要的是,对于erl中的每个现有src文件,make应该将beam中相应的ebin文件视为目标。您可以致电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