I'm trying to use the same value to all tasks, but the variable are evaluating for every task. How to avoid it?
Version: GNU Make 4.1
Makefile content:
SHELL = /bin/bash -ex
BUILD_TIMESTAMP ?= $(shell date '+%Y%m%d%H%M%S')
VERSION ?= 1.2-${BUILD_TIMESTAMP}
t1:
echo ${VERSION}
sleep 1
t2:
echo ${VERSION}
sleep 1
Output:
$ make t1 t2
date +%Y%m%d%H%M%S
echo 1.2-20170803143838
+ echo 1.2-20170803143838
1.2-20170803143838
sleep 1
+ sleep 1
+ date +%Y%m%d%H%M%S
echo 1.2-20170803143839
+ echo 1.2-20170803143839
1.2-20170803143839
sleep 1
+ sleep 1
The ?= in GNU make is equivalent to a = that's only done when the variable was undefined before. As you may know, = sets a recursively expanded variable, that is, its value is only expanded when the variable itself is expanded.
What you want instead is a simply expanded variable, its content is only expanded once and directly assigned to it. For more info on the difference, see The Two Flavors of Variables. You get a simply expanded variable by assigning it with :=.
You have two options to solve your immediate problem:
Make BUILD_TIMESTAMP a simply expanded variable by reassigning it:
BUILD_TIMESTAMP ?= $(shell date '+%Y%m%d%H%M%S')
BUILD_TIMESTAMP := ${BUILD_TIMESTAMP}
VERSION ?= 1.2-${BUILD_TIMESTAMP}
Do the logic for only assigning when the variable was undefined yourself:
ifeq ($(origin BUILD_TIMESTAMP), undefined)
BUILD_TIMESTAMP := $(shell date '+%Y%m%d%H%M%S')
endif
VERSION ?= 1.2-${BUILD_TIMESTAMP}
Just add the following statements to your code after corresponding ?= assignments:
BUILD_TIMESTAMP := $(BUILD_TIMESTAMP)
VERSION := $(VERSION)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With