【问题标题】:Makefile pattern rules not workingMakefile 模式规则不起作用
【发布时间】:2017-07-05 10:45:21
【问题描述】:

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

【问题讨论】:

  • Makefiles 是一种陈旧且太低级(意思是:太容易犯人为错误)的软件构建方式。对于 Erlang,如果你真的想坚持 Makefiles,那么我建议非常好的erlang.mk。如果你想考虑其他选项,那么rebar3.org。在 Erlang 之外,考虑 cmake.org,它将生成 Makefile 或(更好!)忍者配置。

标签: makefile erlang


【解决方案1】:

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

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

make ebin/foo.beam

如果您没有在命令行中指定目标,make 将选择 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多