Win11+Cygwin环境下Makefile canned recipe中if-else语句报错问题
解决GNU Make Canned Recipe添加Bash条件判断的报错问题
问题场景
在Win11系统的Cygwin v3.5.3环境中使用GNU Make v4.4.1编写Makefile,原本有一个可被多目标调用的通用canned recipe,传递不同变量时运行正常:
MYDate = date -u +'$1: %d-%m-%Y %H:%M:%S' define cand-recipe = $(call MYDate, $(var1)) @echo -e "\nIn the canned recipe" @rsync -aqh $(sdir) $(ddir) 2> $(elog) endef
调用方式:
mytarget: var1 := some value mytarget: sdir := $(SRCDir) mytarget: ddir := $(DSTDir) mytarget: elog := $(ERRlogfile) mytarget: $(cand-recipe)
但尝试添加Bash if-else语句处理错误日志时,Make报错*** prerequisites cannot be defined in recipes. Stop.,修改后的错误代码:
MYDate = date -u +'$1: %d-%m-%Y %H:%M:%S' define cand-recipe = $(call MYDate, $(var1)) @echo -e "\nIn the canned recipe" @rsync -aqh $(sdir) $(ddir) 2> $(elog) @if [ -s $(elog) ]; then\ $(call MYDate, ERROR:);\ $(eval elogvar := $(file < $(elog)));\ echo -e "\n$(elogvar)\n";\ $(file >> $(elog),$(call MYDate, ERROR:));\ fi endef
需求:当错误日志文件elog非空时,在终端打印时间戳、输出日志内容,并向日志追加时间戳。
错误原因
报错核心是在Recipe中混用了Make解析期函数与Shell执行期命令:
$(eval)、$(file)是Make内置函数,会在Make解析Makefile阶段执行,而非Shell运行Recipe命令时触发。- Make解析这些函数时,会将输出内容误判为规则的依赖项(prerequisites),从而抛出错误。
- 同时,
$(file < $(elog))会在Make解析阶段就读取日志文件,而非满足Shell的if [ -s $(elog) ]条件后才执行,逻辑完全混乱。
正确实现方案
将所有逻辑交由Shell处理,避免在Recipe中使用Make解析期函数,调整后的代码如下:
# 定义生成时间戳的Shell命令模板(转义$为$$,避免Make解析) MYDate = date -u +'$$1: %d-%m-%Y %H:%M:%S' define cand-recipe = # 打印初始时间戳 $(call MYDate, $(var1)) @echo -e "\nIn the canned recipe" @rsync -aqh $(sdir) $(ddir) 2> $(elog) # Shell条件判断:日志非空时执行处理逻辑 @if [ -s $(elog) ]; then \ # 打印错误时间戳 $(call MYDate, ERROR:); \ # 输出日志内容到终端 echo -e "\n"; cat $(elog); echo -e "\n"; \ # 向日志追加错误时间戳 $(call MYDate, ERROR:) >> $(elog); \ fi endef
调用方式保持不变:
mytarget: var1 := some value mytarget: sdir := $(SRCDir) mytarget: ddir := $(DSTDir) mytarget: elog := $(ERRlogfile) mytarget: $(cand-recipe)
关键调整说明
- 转义Shell变量:将
MYDate中的$1改为$$1,避免Make将其解析为Make的位置参数,确保传递给Shell后正常工作。 - 移除Make解析期函数:去掉
$(eval)和$(file),改用Shell的cat读取日志内容,>>重定向追加时间戳。 - 保持Recipe语法正确:Shell多行命令的换行符前必须加
\,确保Make将其作为完整的Shell命令传递。
内容的提问来源于stack exchange,提问作者Shah-G
相关产品推荐
相关产品推荐

