错误: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"$
答案 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
变量,call
,eval
,甚至foreach
。