食谱在第一个目标之前开始

时间:2017-05-06 23:33:29

标签: makefile

错误:Makefile:12:***食谱在第一个目标之前开始。停止。

我的makefile:

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"$

1 个答案:

答案 0 :(得分: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