Makefile的foreach内使用if条件函数报参数不足错误如何解决
错误原因排查
- 语法错误:
if函数括号不匹配
你嵌套的第二层if函数写为$(if [! -d "${HOME}/.wasm/emsdk"]),,这里多了一个右括号,直接把第二层if函数提前关闭,导致if函数只拿到1个参数,触发insufficient number of arguments报错。 - 语法混用:Makefile
if函数条件中直接写shell判断逻辑
Makefile的if函数只会判断条件展开后的结果是否非空,不能直接识别shell的[判断语法,你需要把目录存在性判断通过shell函数执行,拿到返回结果再给if函数处理。 - 逻辑问题:命令执行时机错误
你现在把@echo、@source写在变量赋值的foreach展开逻辑里,这些命令不会直接执行,只会作为字符串赋值给变量K,不会触发你期望的逻辑。 - 环境变量生效问题
Makefile中每一行shell命令默认在独立的子进程执行,直接执行source只会修改子进程的环境,不会对当前Makefile的全局环境生效,也不会影响后续执行的其他命令。
修正后的写法
如果只需要判断是否有任意一个emsdk命令存在即可,可使用更简洁的写法:
EXECUTABLES = emcc em++ emcmake emconfigure emmake # 先判断首个emsdk命令是否在路径中 EMSDK_IN_PATH := $(shell which $(firstword $(EXECUTABLES)) 2>/dev/null) ifeq ($(EMSDK_IN_PATH),) # 命令不存在,判断emsdk安装目录是否存在 EMSDK_DIR_EXISTS := $(shell test -d "${HOME}/.wasm/emsdk" && echo 1) ifeq ($(EMSDK_DIR_EXISTS),) $(error Emsdk is not installed consider running bash install_requirements first) else # 导入emsdk环境,让环境变量对当前Makefile全局生效 $(shell source "${HOME}/.wasm/emsdk/emsdk_env.sh >/dev/null 2>&1 && env") $(eval export $(shell source "${HOME}/.wasm/emsdk/emsdk_env.sh >/dev/null 2>&1 && env | cut -d= -f1)) endif else $(info Emsdk binaries are already added to path) endif
如果需要严格遍历检查所有emsdk命令都存在,可调整为如下写法:
EXECUTABLES = emcc em++ emcmake emconfigure emmake # 遍历所有命令,标记是否存在缺失 HAS_MISSING := $(foreach exec,$(EXECUTABLES),$(if $(shell which $(exec) 2>/dev/null),,missing)) ifneq ($(filter missing,$(HAS_MISSING)),) EMSDK_DIR_EXISTS := $(shell test -d "${HOME}/.wasm/emsdk" && echo 1) ifeq ($(EMSDK_DIR_EXISTS),) $(error Emsdk is not installed consider running bash install_requirements first) else $(shell source "${HOME}/.wasm/emsdk/emsdk_env.sh >/dev/null 2>&1 && env") $(eval export $(shell source "${HOME}/.wasm/emsdk/emsdk_env.sh >/dev/null 2>&1 && env | cut -d= -f1)) endif else $(info Emsdk binaries are already added to path) endif
内容的提问来源于stack exchange,提问作者Hrant Nurijanyan
相关产品推荐
相关产品推荐

