Makefile中Try2内联调用FileExists逻辑异常求助
Makefile内联调用FileExists判断异常的原因解析
问题核心
你尝试三种方式调用FileExists宏时,Try2在文件不存在时始终将CallInline设为1(预期为0),而Try3能正常工作,问题根源在于宏定义的空白字符干扰了$(if)函数的判断逻辑。
原因分析
1. FileExists宏的空白问题
你的FileExists宏定义包含前导缩进空白:
define FileExists $(and $(wildcard $(1)),1) endef
- 当文件存在时:
$(wildcard)返回文件名,$(and)返回1,宏展开结果为1(带前导空白的1); - 当文件不存在时:
$(wildcard)返回空,$(and)返回空,但宏会保留前导空白,最终返回纯空白字符串(空格/制表符)。
2. $(if)函数的判断规则
Make的$(if)函数判定逻辑是:只要参数非空(包括纯空白字符串),就视为“真”。
在Try2的代码中:
$(eval $(if $(call FileExists,$(1)),\ $(eval CallInline:=1),\ $(eval CallInline:=0)))
无论文件是否存在,$(call FileExists,...)的返回值都是非空(要么是带空白的1,要么是纯空白),因此$(if)始终走then分支,将CallInline设为1。
3. Try3正常工作的原因
Try3先将宏调用结果赋值给变量,再做判断:
$(eval ExistsVar=$(call FileExists,$(1))) $(eval $(if $(ExistsVar),\ $(eval FromVar:=1),\ $(eval FromVar:=0)))
Make在处理变量展开时,会自动将纯空白的变量值视为空字符串:
- 文件不存在时:
ExistsVar的纯空白值被判定为空,$(if)走else分支,FromVar设为0; - 文件存在时:
ExistsVar的值是带空白的1,非空,$(if)走then分支,FromVar设为1。
解决方案
修改FileExists宏,确保返回值仅为1或空字符串:
方案1:去掉宏内的前导空白
define FileExists $(and $(wildcard $(1)),1) endef
方案2:用$(strip)清理空白
define FileExists $(strip $(and $(wildcard $(1)),1)) endef
修改后,$(call FileExists,...)在文件不存在时返回空字符串,$(if)会正确判定为假,Try2的逻辑即可正常工作。
内容的提问来源于stack exchange,提问作者AndrewAUS
相关产品推荐
相关产品推荐

