并非所有变量都在Makefile中递归扩展

时间:2018-06-26 23:59:31

标签: makefile

我只是在玩Makefile,而我试图理解为什么有些变量会被扩展两次,而另一些变量只会被扩展一次。假设以下Makefile:

FILE := $(shell mktemp)
TEMP = $(shell mktemp)
CONTENTS = $(shell cat $(FILE))
test:
    echo $(TEMP)
    echo $(CONTENTS)
    echo test > $(FILE)
    echo $(CONTENTS)
    echo $(TEMP)

运行make test输出以下内容:

echo /tmp/tmp.ZWFtOiCG9v
/tmp/tmp.ZWFtOiCG9v
echo

echo test > /tmp/tmp.FEubzF4Gwa
echo

echo /tmp/tmp.OIKSGVvY1l
/tmp/tmp.OIKSGVvY1l

TEMP每次被调用后如何扩展,而CONTENTS却只扩展一次?

我正在运行GNU Make 3.82

1 个答案:

答案 0 :(得分:0)

当食谱开始执行时,食谱的变量都会全部展开:

Chars:= ["5","6"] , cnt:= 0

Lbutton::
    Send % Chars[cnt:= ++cnt>chars.MaxIndex() ? 1 : cnt]
    KeyWait, Lbutton    
Return

即使没有#forcing `bash` to prevent `make` from using its builtin shell $ strace -t -e execve -f make -d SHELL=/bin/bash test >output 2>&1 $ cat output # with irrelevant bits elided 17:20:48 execve("/usr/bin/make", ["make", "-d", "SHELL=/bin/bash", "test"], [/* 52 vars */]) = 0 GNU Make 4.1 Built for x86_64-pc-linux-gnu Copyright (C) 1988-2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Reading makefiles... Reading makefile 'Makefile'... Updating makefiles.... Considering target file 'Makefile'. <lots of lines omitted> No need to remake target 'Makefile'. Updating goal targets.... # prepare the recipe Considering target file 'test'. File 'test' does not exist. Finished prerequisites of target file 'test'. Must remake target 'test'. # expand $(DATE) the first time strace: Process 32729 attached [pid 32729] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "date"], [/* 52 vars */]) = 0 [pid 32729] 17:20:48 execve("/bin/date", ["date"], [/* 52 vars */]) = 0 [pid 32729] 17:20:48 +++ exited with 0 +++ 17:20:48 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32729, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- # expand $(FILE) the first time strace: Process 32730 attached [pid 32730] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "mktemp"], [/* 52 vars */]) = 0 [pid 32730] 17:20:48 execve("/bin/mktemp", ["mktemp"], [/* 52 vars */]) = 0 [pid 32730] 17:20:48 +++ exited with 0 +++ 17:20:48 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32730, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- # expand $(DATE) the second time strace: Process 32731 attached [pid 32731] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "date"], [/* 52 vars */]) = 0 [pid 32731] 17:20:48 execve("/bin/date", ["date"], [/* 52 vars */]) = 0 [pid 32731] 17:20:48 +++ exited with 0 +++ 17:20:48 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32731, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- # expand $(FILE) the second time strace: Process 32732 attached [pid 32732] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "mktemp"], [/* 52 vars */]) = 0 [pid 32732] 17:20:48 execve("/bin/mktemp", ["mktemp"], [/* 52 vars */]) = 0 [pid 32732] 17:20:48 +++ exited with 0 +++ 17:20:48 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32732, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- # begin executing the recipe strace: Process 32733 attached Putting child 0x5629c95cb0c0 (test) PID 32733 on the chain. Live child 0x5629c95cb0c0 (test) PID 32733 [pid 32733] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "echo Tue Jun 26 17:20:48 PDT 201"...], [/* 56 vars */]) = 0 Tue Jun 26 17:20:48 PDT 2018 [pid 32733] 17:20:48 +++ exited with 0 +++ 17:20:48 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32733, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- Reaping winning child 0x5629c95cb0c0 PID 32733 strace: Process 32734 attached Live child 0x5629c95cb0c0 (test) PID 32734 [pid 32734] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "echo /tmp/tmp.nWxcC4KeVf"], [/* 56 vars */]) = 0 /tmp/tmp.nWxcC4KeVf [pid 32734] 17:20:48 +++ exited with 0 +++ 17:20:48 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32734, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- Reaping winning child 0x5629c95cb0c0 PID 32734 # significant time doesn't pass until here sleep 3 strace: Process 32735 attached Live child 0x5629c95cb0c0 (test) PID 32735 [pid 32735] 17:20:48 execve("/bin/bash", ["/bin/bash", "-c", "sleep 3"], [/* 56 vars */]) = 0 [pid 32735] 17:20:48 execve("/bin/sleep", ["sleep", "3"], [/* 56 vars */]) = 0 [pid 32735] 17:20:51 +++ exited with 0 +++ 17:20:51 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32735, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- Reaping winning child 0x5629c95cb0c0 PID 32735 strace: Process 32736 attached Live child 0x5629c95cb0c0 (test) PID 32736 [pid 32736] 17:20:51 execve("/bin/bash", ["/bin/bash", "-c", "echo Tue Jun 26 17:20:48 PDT 201"...], [/* 56 vars */]) = 0 Tue Jun 26 17:20:48 PDT 2018 [pid 32736] 17:20:51 +++ exited with 0 +++ 17:20:51 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32736, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- Reaping winning child 0x5629c95cb0c0 PID 32736 strace: Process 32737 attached Live child 0x5629c95cb0c0 (test) PID 32737 [pid 32737] 17:20:51 execve("/bin/bash", ["/bin/bash", "-c", "echo /tmp/tmp.QgNem5ezr0"], [/* 56 vars */]) = 0 /tmp/tmp.QgNem5ezr0 [pid 32737] 17:20:51 +++ exited with 0 +++ 17:20:51 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=32737, si_uid=1000, si_status=0, si_utime=0, si_stime=0} --- Reaping winning child 0x5629c95cb0c0 PID 32737 Removing child 0x5629c95cb0c0 PID 32737 from chain. Successfully remade target file 'test'. 17:20:51 +++ exited with 0 +++ ,这也是有道理的,因为变量可以扩展为多行,需要分别执行。