Makefile中使用export定义变量取值为空的解决方法
问题根因
变量为空、执行报错是踩了Makefile两个核心执行规则的坑:
- Makefile中每条独立命令行(Tab开头、未做反斜杠续行的行),都会单独启动独立Shell子进程执行。上一行export的环境变量会随子进程退出销毁,下一行命令完全无法读取。
- Makefile解析阶段会优先替换所有
$(xxx)格式的内容为Make自身的变量值。如果要让变量在Shell执行阶段才解析、读取Shell内定义的值,必须把$转义为$$,否则Make找不到对应自定义变量就会替换为空字符串。
正确修复代码
修改后的run_harness目标段写法如下:
.PHONY: run_harness run_harness: link_dirs @mkdir -p $(LOG_DIR) @export WRK="3d-unet"; \ export startTime=`date +%s`; \ echo $$WRK, $$startTime; @set -o pipefail && $(PYTHON3_CMD) code/main.py $(RUN_ARGS) --action="run_harness" 2>&1 | tee $(LOG_DIR)/stdout.txt @set -o pipefail && $(PYTHON3_CMD) scripts/print_harness_result.py $(RUN_ARGS) 2>&1 | tee -a $(LOG_DIR)/stdout.txt
如果后续需要在同一段逻辑里用到这两个变量,只要把后续命令和上面的export、echo用反斜杠续行连在同一个Shell进程块里就行,不用重复定义。
写法说明
- 用反斜杠
\把需要共享变量的所有Shell命令连为一个整体,保证所有命令在同一个Shell子进程内执行,变量可正常传递。 - Shell侧定义的变量,引用时必须写
$$变量名,转义后Make不会提前展开,会交给Shell在执行时解析。 - 时间获取可以用反引号
`date +%s`,也可以写$$(date +%s)——如果用$()的Shell命令替换格式,同样要转义$为$$,避免被Make提前解析报错。 - 命令块最后一行末尾不要留多余的分号和反斜杠,避免触发Shell语法错误。
内容的提问来源于stack exchange,提问作者mahmood
相关产品推荐
相关产品推荐

