Reputation: 9724
Here's my 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}
... and here I've included it into my actual Makefile
:
include ./msbuild.mk
SRCDIR = src
APP_NAME = MyApp
APP_SRCDIR = ${SRCDIR}/code/${APP_NAME}
APP_OUTDIR = ${OUTDIR}/${APP_NAME}
.DEFAULT_GOAL = build-app
When I try this...
make build-app
... the check-env
target in msbuild.mk
aborts the script saying the variables are not set (even they are set in the actual Makefile
). Furthermore, if I remove the check-env
target, the build-app
target succeeds as variables APP_NAME
, APP_SRCDIR
, and APP_OUTDIR
seem to be set correctly.
I'm a bit lost... Am I missing something?
Upvotes: 0
Views: 119
Reputation: 100836
A few things.
First, the -v option to test is not a POSIX standard option; it's a bash extension. Make will always invoke /bin/sh
as the shell which may or may not actually be bash, depending on your system. If all you care about is whether the variable has a non-empty value or not you can use [ -n "$VAR" ]
instead.
Second, you can't intersperse make functions like $(error ...)
with shell operations like test
. If you think about it there's no way that can work: make doesn't have a shell interpreter embedded in it, it expands the command, runs a real shell process, and waits for the exit code to know if it worked. How can a condition that is handled by the shell control whether or not a make function like $(error ...)
is run or not?
If you want to test shell variables you have to use shell commands to handle the error, something like this:
check-env: ## Check build environment
[ -n "$$APP_NAME" ] || { echo APP_NAME not set; exit 1; }
If you just want to check for make variables being set, you can do it more straightforwardly using make syntax. Something like:
check-env = $(foreach V,APP_NAME,APP_SOURCEDIR,APP_OUTDIR, \
$(if $($V),,$(error Variable $V is not set)))
build-app:
$(check-env)
...
Upvotes: 1