ifndef with multiple AND conditions in makefile gnu

268 Views Asked by At

How do I ensure that make command has the parameter ENV passed in it?

Eg: make destroy ENV=test if ENV is not passed I should throw error.

Code:

ENV ?=prod
ifndef ENV
   $(error ENV is not defined, Please provide ENV paramter in your make command)
ifndef FORCE
   @/bin/echo -n "Are you sure to DESTROY configuration for ${ENV}? [y/N] " && read ans && [ $${ans:-N} = y ]
endif
endif
   terraform destroy ${ARGS}
2

There are 2 best solutions below

2
HardcoreHenry On BEST ANSWER

The question is whether you want to test whether they are empty, or whether they are defined. If you want to test that at least one is set to a non-empty value, you can use the following trick:

ifeq ($(CONDITION1)$(CONDITION2),)
# Both CONDITION1 and CONDITION2 are empty or not defined
endif

If you want to test if either is defined (but potentially emtpy), you could would use the origin function:

ifeq ($(origin CONDITION1)$(origin CONDITION2),undefinedundefined)
# Both CONDITION1 and CONDITION2 are not defined
endif

For more complex expressions, you can also use the $(if ...), $(and ...) and $(or ...) functions (see here). eg:

ifeq ($(or $(CONDITION1),$(CONDITION2)),)
# Both CONDITION1 and CONDITION2 are empty or not defined
endif

EDIT:

As to the updated question, it is a bit different than what you were originally asking. The cleanest way to do this is to add the checks in a recipe rather than conditional parts of the make:

checkenv:
   @[ "$(origin ENV)" -eq "command line" ] \
       || echo "ERROR ENV not defined on command line" >&2 \
       && false
   @[ $(FORCE) ] \
       || echo -n "Are you sure to DESTROY configuration for ${ENV}? [y/N]" \
       && read ans \
       && [ $${ans:-N} = y ] 

maintarget: checkenv
    terraform destroy ${ARGS}
1
Emanuel P On

Make doesn't support that. You can nest them. That has the same effect

ifndef CONDITION1
ifndef CONDITION2
<do something>
endif
endif
<do nothing>