mrk
mrk

Reputation: 730

Makefile: check if multiple variables are set

In my Makefile I want to check if multiple environments variables are set. But I don't want to write multiple ifndef for each one. I just want an array of variables to make it reusable.

check-variables:
  for var in var1 var2 var3 ; do \
    if [ -z "$$var" ] ; then \
      echo "$$var is not set"; exit 1; \
    fi \
  done

But it's not working...

Upvotes: 1

Views: 1220

Answers (2)

mwag
mwag

Reputation: 4035

If you don't need to strip leading/trailing whitespace and you can assume that your values cannot contain single-quotes, you can do the following which is fairly concise:

MISSING=$(shell for x in '${VAR1}' '${VAR2}' '${VAR3}' ; do [ \"$$x\" = \"\" ] && echo 1 ; done)
ifneq ($(MISSING),)
  $(error Missing one or more required var(s): VAR1 VAR2 VAR3)
endif

How it works:

  • instead of listing var names, and then having to figure out how to dereference the var names, this approach lists var values and then inspects each
  • inside the for loop, we just check if the value is empty and if so, emit 1
  • this sets the MISSING makefile variable to either blank (no vars were empty), or a series of 1 chars (one for each empty var)
  • we can then check if MISSING is blank to determine whether any vars were blank

Upvotes: 0

MadScientist
MadScientist

Reputation: 100836

This isn't a make issue, it's a shell issue. If you ran that script at your shell prompt (changing $$ back to $ as make will do, of course) it wouldn't work either. Until you can get the command to work at your shell prompt, you can't get it to work in a makefile.

The shell command would be:

for var in var1 var2 var3 ; do \
  if [ -z "$var" ] ; then \
    echo "$var is not set"; exit 1; \
  fi \
done

You can see why this doesn't do what you want: you're checking the shell variable var every time. What you're trying to do is check the value of the variable which is named by the value of $var. To do this you need eval (the shell's eval, not make's eval function):

for var in var1 var2 var3 ; do \
  eval test -n \"\$$var\" \
      || { echo "$var is not set"; exit 1; }; \
done

You should discover that the above will work in the shell, then you need to put it back into the makefile (and double all the $).

Upvotes: 3

Related Questions