代码之家  ›  专栏  ›  技术社区  ›  William Pursell

如何在变量赋值中获得“最多一次”语义?

  •  0
  • William Pursell  · 技术社区  · 6 年前

    shell命令有时需要很长时间才能运行,因此您可能不想这样做。 VAR = $(shell slow-cmd) (与 = ,每次引用变量时都会运行slow命令)。使用 VAR := $(shell slow-cmd) 可能很有用,但是如果您正在构建一个不需要扩展变量的目标,那么您将再次调用 slow-cmd 比需要的多。在下面的makefile(使用gnu make)中,您可以获得所需的行为:定义v2值的shell命令永远不会被多次调用,并且对于目标 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 回复  |  直到 6 年前
        1
  •  5
  •   MadScientist    6 年前

    没有技巧是不可能做到的,但有一种比你用的更干净的方法。您可以使用:

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

    有关此工作方式的详细信息和解释,请参见 this page .

        2
  •  0
  •   Renaud Pacalet    6 年前

    目标特定延迟变量是一个选项:

    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