Как получить семантику «максимум один раз» в присваиваниях переменных? - PullRequest
0 голосов
/ 09 июня 2018

Команды оболочки иногда выполняются очень долго, поэтому вы можете не захотеть делать VAR = $(shell slow-cmd)=, slow-cmd будет запускаться каждый раз, когда ссылается на переменную).Использование VAR := $(shell slow-cmd) может быть полезным, но если вы создаете цель, которой переменная не требуется, вы получите еще один вызов slow-cmd, чем необходимо.В следующем make-файле (с gnu-make) вы можете получить желаемое поведение: команда оболочки для определения значения для V2 никогда не вызывается более одного раза, а для цели foo она вообще не вызывается.Но это отвратительный клудж.Есть ли более разумный способ гарантировать, что переменная определяется только при необходимости, но никогда не оценивается более одного раза?

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

Ответы [ 2 ]

0 голосов
/ 09 июня 2018

Нет способа сделать это без хитростей, но есть более чистый способ (возможно), чем вы используете.Вы можете использовать:

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

Для получения более подробной информации и объяснения, как именно это работает, см. эту страницу .

0 голосов
/ 09 июня 2018

Целевые специфические отложенные переменные являются опцией:

host> cat Makefile
foo: VFOO = $(shell echo "VFOO" >> log.txt; echo "VFOO")

foo:
    @echo '$(VFOO)' > $@

bar: VBAR = $(shell echo "VBAR" >> log.txt; echo "VBAR")

bar:
    @echo '$(VBAR)' > $@

host> make foo
host> cat log.txt
VFOO
host> make foo
make: 'foo' is up to date.
host> cat log.txt
VFOO
host> make bar
host> cat log.txt
VFOO
VBAR
host> make bar
make: 'bar' is up to date.
host> cat log.txt
VFOO
VBAR
...