Makefile 如何检查是否设置了在外部文件中定义的目标中使用的变量

Makefile 如何检查是否设置了在外部文件中定义的目标中使用的变量,makefile,sh,gnu-make,Makefile,Sh,Gnu Make,这是我的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

这是我的
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}
。。。在这里,我已经将它包含到我的实际
生成文件中

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
目标,则
构建应用程序
目标会成功,因为变量
app\u NAME
app\u SRCDIR
app\u OUTDIR
似乎设置正确

我有点迷路了。。。我遗漏了什么吗?

一些东西

首先,测试的-v选项不是POSIX标准选项;这是一个bash扩展。Make将始终调用
/bin/sh
作为shell,它可能是bash,也可能不是bash,这取决于您的系统。如果您只关心变量是否具有非空值,则可以使用
[-n“$VAR”]

其次,不能将make函数(如
$(error…
)与shell操作(如
test
)穿插在一起。如果你想一想,这是没有办法的: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)
        ...

非常感谢您的支持,非常有效!为了让您知道,我不得不使用
[-n“${APP_NAME}”]
而不是
[-n“$$APP_NAME”]
。您的更改意味着您正在检查make变量是否设置正确。我以为您想检查shell环境变量是否设置正确。如果您只想检查make变量,为什么还要创建一个必须作为先决条件列出的规则并运行shell来执行检查呢?为什么不把它签入make本身呢?我只是在创建一组预构建的make目标。。。在本例中,我希望确保在导入
msbuild
时,
Makefile
定义所需的变量。长话短说,构建一个
mono
项目只需要导入
msbuild.mk
并定义3个
APP
变量。就这样:-)