我正在学习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 :(得分:2)
目标规则告诉make,只要需要在beam
目录中生成ebin
文件,并且erl
目录中存在相应的src
文件,它可以使用erlc
。
然而,这并不能说明这是它需要做的事情。你可以通过在命令行上给它一个目标来明确告诉make它需要做什么:
make ebin/foo.beam
如果您未在命令行上提供目标,make将选择makefile中的第一个非模式规则作为其目标。但是,您的makefile没有任何非模式规则,因此没有目标。
您可能想要的是,对于erl
中的每个现有src
文件,make应该将beam
中相应的ebin
文件视为目标。您可以致电wildcard
和patsubst
:
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
文件。