Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get "at most once" semantics in variable assignments?

Shell commands sometimes take a long time to run, so you may not want to do VAR = $(shell slow-cmd) (with =, the slow-cmd will be run every time the variable is referenced). Using VAR := $(shell slow-cmd) can be useful, but if you are building a target that does not ever need the variable expanded, you will get one more invocation of the slow-cmd than is needed. In the following makefile (with gnu-make), you can get the desired behavior: the shell command to define a value for V2 is never invoked more than once, and for the target foo it is not invoked at all. But this is a heinous kludge. Is there a more reasonable way to ensure that a variable is only defined when needed, but never evaluated more than once?

V1 = $(shell echo evaluating V1 > /dev/tty; echo V1 VALUE)

all: foo bar V2
        @echo $(V1) $@
        @echo $(V2) $@

foo:
        @echo $(V1) $@

bar: V2
        @echo $(V1) $@
        @echo $(V2) $@

V2:
        $(eval V2 := $(shell echo evaluating V2 > /dev/tty; echo V2 VALUE))

.PHONY: all foo bar
like image 520
William Pursell Avatar asked Nov 26 '25 13:11

William Pursell


1 Answers

There's no way to do it without tricks, but there's a cleaner way (maybe) than you're using. You can use:

V1 = $(eval V1 := $$(shell some-comand))$(V1)

For more details and explanation of exactly how this works see this page.

like image 124
MadScientist Avatar answered Nov 28 '25 16:11

MadScientist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!