In a Makefile, a deploy
recipe needs a environment variable ENV
to be set to properly execute itself, whereas others don\'t care, e.g.:
Inline variant
In my makefiles, I normally use an expression like:
deploy:
test -n "$(ENV)" # $$ENV
rsync . $(ENV).example.com:/var/www/myapp/
The reasons:
Don't forget the comment which is important for debugging:
test -n ""
Makefile:3: recipe for target 'deploy' failed
make: *** [deploy] Error 1
... forces you to lookup the Makefile while ...
test -n "" # $ENV
Makefile:3: recipe for target 'deploy' failed
make: *** [deploy] Error 1
... explains directly what's wrong
Global variant (for completeness, but not asked)
On top of your Makefile, you could also write:
ifeq ($(ENV),)
$(error ENV is not set)
endif
Warnings:
clean
target will fail if ENV is not set. Otherwise see Hudon's answer which is more complexOne possible problem with the given answers so far is that dependency order in make is not defined. For example, running:
make -j target
when target
has a few dependencies does not guarantee that these will run in any given order.
The solution for this (to guarantee that ENV will be checked before recipes are chosen) is to check ENV during make's first pass, outside of any recipe:
## Are any of the user's goals dependent on ENV?
ifneq ($(filter deploy other-thing-that-needs-ENV,$(MAKECMDGOALS)),$())
ifndef ENV
$(error ENV not defined)
endif
endif
.PHONY: deploy
deploy: foo bar
...
other-thing-that-needs-ENV: bar baz bono
...
You can read about the different functions/variables used here and $()
is just a way to explicitly state that we're comparing against "nothing".