Search code examples
makefileifndef

ifndef with multiple AND conditions in makefile gnu


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}

Solution

  • 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}