get a default value when variable is unset in make
Asked Answered
P

4

21

(edit: question more accurate based on @Michael feedback)

In bash, I often use parameter expansion: the following commands print "default value" when $VARNAME is unset, otherwise it prints the VARNAME content.

echo ${VARNAME:-default value}  #if VARNAME empty => print "default value" 
echo ${VARNAME-default value}   #if VARNAME empty => print "" (VARNAME string)

I did not find a similar feature on GNU make. I finally wrote in my Makefile:

VARNAME ?= "default value"
all:
        echo ${VARNAME}

But I am not happy with this solution: it always creates the variable VARNAME and this may change the behavior on some makefiles.

Is there a simpler way to get a default value on unset variable?

Pear answered 16/4, 2013 at 10:54 Comment(0)
B
32

If you want to use the expansion of a GNU make variable if it is non-empty and a default value if it is empty, but not set the variable, you can do something like this:

all:
        echo $(or $(VARNAME),default value)
Braiding answered 16/4, 2013 at 12:31 Comment(1)
Just to be anally complete, the make version of bash's ${VARNAME-default} (no :) is $(if $(filter undefined,$(origin VARNAME),default,${VARNAME}). (Appologgies if I've typed that wrongly.)Unaccustomed
B
1

If you want to test if a variable has a non-empty value, you can use:

ifeq ($(VARNAME),)
        VARNAME="default value"
else
        do_something_else
endif

For checking if a variable has been defined or not, use ifdef.

Refer to Syntax of Conditionals in the manual for more.

Bundy answered 16/4, 2013 at 11:25 Comment(3)
Thanks, this is a possible solution, but not as simple as VARNAME ?= "default value" (note: I do not want to create/change variable VARNAME). CheersPear
The snippet mentioned above doesn't create/change VARNAME. It simply checks whether it has a non-empty value & would evaluate to false (1) whether VARNAME exists or not, or (2) if VARNAME is empty. In either case, it wouldn't create VARNAME. You can use ifdef ($(VARNAME)) later to verify!Bundy
oops, you are right, my apologies. I was looking for something more convenient to use (like @MadScientist's answer). I wanted to tell you that I prefer to use VARNAME ?= "default value" (even if it creates a variable) than the above 5-lines-snippet (my point of view). I give you +1 because your solution is correct. I you think @MadScientist's answer is good, please give him +1 also ;-) Thank you for your help. Cheers.Pear
C
0

I have a similar case where the result of filtering a shell command could be a single word or empty string. When empty, it should fallback to the default word. In the example below APPLE_LINUX will be 'apple' on macOS or 'linux' on other platforms. MSG will be set to the message for the appropriate platform. The example intentionality avoids using ifeq.

MACHINE         := $(shell $(COMPILE.cpp) -dumpmachine)
MACHINE_APPLE   := $(findstring apple,$(MACHINE))
APPLE_LINUX     := $(firstword $(MACHINE_APPLE) linux)
apple.MSG       := You are building on macOS
linux.MSG       := You are building on Linux or another OS
MSG             := $($(APPLE_LINUX).MSG)
Compensatory answered 25/5, 2020 at 19:19 Comment(0)
D
-1

Just remove the colon. If you use :- in your substitution the default value will be used if the variable is null, an empty string or it does not exist, but just using - on its own will only substitute the default value if the variable has not been defined.

# var1=default
# var2=

# echo var2 is ${var2:-$var1}
var2 is something
# echo var3 is ${var3:-$var1}
var3 is something

# echo var2 is ${var2-$var1}
var2 is
# echo var3 is ${var3-$var1}
var3 is something
Davit answered 16/4, 2013 at 11:28 Comment(1)
Thank you for the distinction between :- and -. I edit my question to be more accurate. But your answer is for shell, it does not work for makefile...Pear

© 2022 - 2024 — McMap. All rights reserved.