如何检查是否设置了在外部文件中定义的目标中使用的变量
How to Check Whether a Variable Used in a Target Defined in an External File Is Set
这是我的 msbuild.mk
...
# default build configuration
CONFIGURATION = Release
.PHONY: check-env build-app
check-env: ## Check build environment
[ -v APP_NAME ] && $(error APP_NAME not set)
[ -v APP_SRCDIR ] && $(error APP_SRCDIR not set)
[ -v APP_OUTRDIR ] && $(error APP_OUTDIR not set)
build-app: check-env ## Build .NET application
@msbuild ${APP_SRCDIR}/${APP_NAME}.sln -t:Build \
-p:BaseIntermediateOutputPath=${APP_OUTDIR}/obj/ \
-p:OutDir=${APP_OUTDIR}/bin/ \
-p:Configuration=${CONFIGURATION}
... 在这里,我将其包含在我的实际 Makefile
:
中
include ./msbuild.mk
SRCDIR = src
APP_NAME = MyApp
APP_SRCDIR = ${SRCDIR}/code/${APP_NAME}
APP_OUTDIR = ${OUTDIR}/${APP_NAME}
.DEFAULT_GOAL = build-app
当我尝试这个时...
make build-app
... msbuild.mk
中的 check-env
目标中止脚本,表示变量未设置(即使它们在实际 Makefile
中设置)。此外,如果我删除 check-env
目标,build-app
目标会成功,因为变量 APP_NAME
、APP_SRCDIR
和 APP_OUTDIR
似乎设置正确。
我有点迷茫...我是不是漏掉了什么?
一些事情。
首先,要测试的-v选项不是POSIX标准选项;这是一个 bash 扩展。 Make 将始终调用 /bin/sh
作为 shell,它实际上可能是也可能不是 bash,具体取决于您的系统。如果您只关心变量是否具有非空值,则可以改用 [ -n "$VAR" ]
。
其次,您不能将 $(error ...)
之类的 make 函数与 test
之类的 shell 操作穿插在一起。如果你考虑一下,没有办法可以工作:make 没有嵌入 shell 解释器,它扩展了命令,运行 是一个真正的 shell 进程,并等待退出代码以了解它是否有效。 shell 处理的条件如何控制像 $(error ...)
这样的 make 函数是否是 运行 还是没有?
如果你想测试 shell 变量你必须使用 shell 命令来处理错误,像这样:
check-env: ## Check build environment
[ -n "$$APP_NAME" ] || { echo APP_NAME not set; exit 1; }
如果您只想检查 make 变量被设置,您可以使用 make 语法更直接地完成它。类似于:
check-env = $(foreach V,APP_NAME,APP_SOURCEDIR,APP_OUTDIR, \
$(if $($V),,$(error Variable $V is not set)))
build-app:
$(check-env)
...
这是我的 msbuild.mk
...
# default build configuration
CONFIGURATION = Release
.PHONY: check-env build-app
check-env: ## Check build environment
[ -v APP_NAME ] && $(error APP_NAME not set)
[ -v APP_SRCDIR ] && $(error APP_SRCDIR not set)
[ -v APP_OUTRDIR ] && $(error APP_OUTDIR not set)
build-app: check-env ## Build .NET application
@msbuild ${APP_SRCDIR}/${APP_NAME}.sln -t:Build \
-p:BaseIntermediateOutputPath=${APP_OUTDIR}/obj/ \
-p:OutDir=${APP_OUTDIR}/bin/ \
-p:Configuration=${CONFIGURATION}
... 在这里,我将其包含在我的实际 Makefile
:
include ./msbuild.mk
SRCDIR = src
APP_NAME = MyApp
APP_SRCDIR = ${SRCDIR}/code/${APP_NAME}
APP_OUTDIR = ${OUTDIR}/${APP_NAME}
.DEFAULT_GOAL = build-app
当我尝试这个时...
make build-app
... msbuild.mk
中的 check-env
目标中止脚本,表示变量未设置(即使它们在实际 Makefile
中设置)。此外,如果我删除 check-env
目标,build-app
目标会成功,因为变量 APP_NAME
、APP_SRCDIR
和 APP_OUTDIR
似乎设置正确。
我有点迷茫...我是不是漏掉了什么?
一些事情。
首先,要测试的-v选项不是POSIX标准选项;这是一个 bash 扩展。 Make 将始终调用 /bin/sh
作为 shell,它实际上可能是也可能不是 bash,具体取决于您的系统。如果您只关心变量是否具有非空值,则可以改用 [ -n "$VAR" ]
。
其次,您不能将 $(error ...)
之类的 make 函数与 test
之类的 shell 操作穿插在一起。如果你考虑一下,没有办法可以工作:make 没有嵌入 shell 解释器,它扩展了命令,运行 是一个真正的 shell 进程,并等待退出代码以了解它是否有效。 shell 处理的条件如何控制像 $(error ...)
这样的 make 函数是否是 运行 还是没有?
如果你想测试 shell 变量你必须使用 shell 命令来处理错误,像这样:
check-env: ## Check build environment
[ -n "$$APP_NAME" ] || { echo APP_NAME not set; exit 1; }
如果您只想检查 make 变量被设置,您可以使用 make 语法更直接地完成它。类似于:
check-env = $(foreach V,APP_NAME,APP_SOURCEDIR,APP_OUTDIR, \
$(if $($V),,$(error Variable $V is not set)))
build-app:
$(check-env)
...