Makefile 配方在第一个目标之前开始

Makefile 配方在第一个目标之前开始,makefile,Makefile,错误:Makefile:12:**recipe在第一个目标之前开始。停下来 我的生成文件: 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: $(addprefi

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

我的生成文件:

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

您的问题是使用
eval
功能
eval
用于解析make构造,但您正在向其传递一个shell命令。考虑这条线:

$(foreach file,$(files),$(eval $(call generateObject,$(file))))
每次通过列表调用带有文件名的
generateObject
。它将扩展为shell命令;例如,如果
文件
是矩阵,则
调用
将扩展为:

^I@nasm -f elf32 -o obj/matrix.o src/matrix.asm
然后,将该文本字符串传递给
eval
,后者尝试将其作为生成文件读取。请注意,传递给
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 $@ $<
object:$(文件:%=$(objDir)/%.o)
$(objDir)/%.o:$(srcDir)/%.asm
@nasm-f elf32-o$@$<

您不需要
generateObject
变量,也不需要
call
,也不需要
eval
,甚至不需要
foreach

我可以看到这个makefile没有什么问题,当我使用它运行make时,不会出现类似的错误。您使用的是什么操作系统?您使用的make版本是什么(运行
make--version
)?我正在Ubuntu 16.04上使用GNU make 4.1。感谢您提供的解决方案和建议。