为何GNU Makefile中部分自定义函数需用eval,部分无需?
Makefile自定义函数中eval的作用差异解析
核心差异:函数功能与Make解析逻辑的匹配度
makerec函数:作用是生成符合Make语法的规则/命令,展开后的内容直接属于Make能直接识别的顶层元素(比如目标依赖规则),不需要额外处理就能被解析执行。
举个例子,假设makerec的定义是生成汇编文件的编译规则:makerec = $(1)/%.o: $(1)/%.s as -o $$@ $$<调用
$(makerec a)时,展开结果是:a/a.o: a/a.s as -o $@ $<这是标准的Make规则,会被直接纳入解析流程,自然不需要eval。
inclmk函数:核心是执行变量赋值这类Make指令,这类指令如果只是作为函数展开后的字符串,不会被Make自动当作指令执行——因为函数展开的结果默认是普通文本,只有通过
eval,才能让Make把这段字符串重新当作Makefile代码解析,进而完成变量赋值。
现象原因解析:为什么去掉eval后变量赋值失效
假设inclmk的定义(去掉eval)是:
inclmk = srcdir := $(patsubst %/,%,$(dir $1)) $(info +++ $(srcdir))
当调用$(inclmk a/makefile.mk)时,函数会先展开为:
srcdir := $(patsubst %/,%,$(dir a/makefile.mk)) $(info +++ $(srcdir))
但这段内容只是被当作普通字符串输出,Make不会把第一行识别为变量赋值指令,因此srcdir始终是空变量,$(info)也就只能打印+++。
而加上eval后,eval会把展开后的字符串重新当作Makefile代码解析,此时srcdir := ...才会被执行,变量被正确赋值,$(info)就能打印出预期的路径。
内容的提问来源于stack exchange,提问作者LGabci
相关产品推荐
相关产品推荐

