【问题标题】:recipe commences before first target配方在第一个目标之前开始
【发布时间】:2017-05-06 23:33:28
【问题描述】:

错误:Makefile:12: *** 配方在第一个目标之前开始。停下来。

我的生成文件:

objDir := obj
incDir := include
srcDir := src
binDir := bin
files := matrix palindrome encryption

define generateObject
    @nasm -f elf32 -o $(objDir)/$(1).o $(srcDir)/$(1).asm
endef

object: $(addprefix $(srcDir)/,$(addsuffix .asm,$(files)))
    @echo -n "Generating object files... "
    $(foreach file,$(files),$(eval $(call generateObject,$(file))))
    @echo "Done"

我在一篇文章中读到,这可能是由于不需要的空格/制表符,但我找不到任何内容。

我试过cat -e -t -v Makefile,结果是:

objDir := obj$
incDir := include$
srcDir := src$
binDir := bin$
files := matrix palindrome encryption$
$
define generateObject$
^I@nasm -f elf32 -o $(objDir)/$(1).o $(srcDir)/$(1).asm$
endef$
$
object: $(addprefix $(srcDir)/,$(addsuffix .asm,$(files)))$
^I@echo -n "Generating object files... "$
^I$(foreach file,$(files),$(eval $(call generateObject,$(file))))$
^I@echo "Done"$

【问题讨论】:

  • 我可以看到这个 makefile 没有任何问题,当我使用它运行 make 时,我没有收到这样的错误。您使用什么操作系统?你用的是什么版本的make(运行make --version)?
  • 我在 Ubuntu 16.04 上使用 GNU Make 4.1。

标签: makefile


【解决方案1】:

您的问题是使用eval 函数。 eval 用于解析 make 结构,但您传递给它的是一个 shell 命令。考虑这一行:

$(foreach file,$(files),$(eval $(call generateObject,$(file))))

每次通过列表时,您都会使用文件名调用generateObject。这将扩展为一个 shell 命令;例如,如果file矩阵,那么call 将扩展为:

^I@nasm -f elf32 -o obj/matrix.o src/matrix.asm

然后你把那个文本字符串传递给eval,它会尝试把它作为一个makefile来读取。请注意,传递给eval 的文本本身必须是完整且有效的makefile;就像您递归调用 make 并将此字符串作为 makefile 给它一样,只是解析的结果应用于当前的 makefile。您不能只给 eval 有效 makefile 的一部分(如配方中的一个命令行)并将其插入到当前的 makefile 中。由于该行本身无效,因此您会收到此错误。

您不想在结果上运行eval,而是将它们连接到一个shell命令中。试试这个:

define generateObject
  nasm -f elf32 -o $(objDir)/$(1).o $(srcDir)/$(1).asm
endef

object: $(addprefix $(srcDir)/,$(addsuffix .asm,$(files)))
        @echo -n "Generating object files... "
        @$(foreach file,$(files),$(call generateObject,$(file)) && ) true
        @echo "Done"

但是,这真的不是“让路”。您不想在单个规则中构建多个目标:这违背了 make 的主要观点,即它只重建过时的文件。

你应该像这样编写你的makefile:

object: $(files:%=$(objDir)/%.o)

$(objDir)/%.o : $(srcDir)/%.asm
        @nasm -f elf32 -o $@ $<

您不需要generateObject 变量、calleval,甚至foreach

【讨论】:

  • 感谢您的解决方案和建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多