Makefile变量扩展/求值

6

目前我在处理一个Makefile问题,这是由于对一个make变量进行评估而引起的。我已经简化了复杂度,只留下产生问题的基本元素。

  • $(LIST) 被评估为一个文件列表,当Makefile被读取时。
  • step1过程中,其中一个文件被删除了。
  • step2中使用变量时,它不会再次被评估,因此不再有效,这导致复制命令时出现错误。
  • 如果变量在使用时被评估,即在step2期间进行评估,那将是很好的。

有什么想法来解决或解决这个问题吗?


Makefile:

LIST=$(wildcard src/*.txt)

all: step1 step2

step1:
    @echo "---------- step1 ----------"
    @echo $(LIST)
    rm src/q1.txt
    ls src

step2:
    @echo "---------- step2 ----------"
    @echo $(LIST)
    cp $(LIST) ./dst

执行日志:


$ make
---------- step1 ----------
src/q1.txt src/q2.txt
rm src/q1.txt
ls src
q2.txt
---------- step2 ----------
src/q1.txt src/q2.txt
cp src/q1.txt src/q2.txt ./dst
cp: cannot stat `src/q1.txt': No such file or directory
make: *** [step2] Error 1
1个回答

8

不要使用通配符函数。

LIST = src/*.txt

all: step1 step2

step1:
    @echo "---------- step1 ----------"
    @echo $(LIST)
    rm src/q1.txt
    ls src

step2:
    @echo "---------- step2 ----------"
    @echo $(LIST)
    cp $(LIST) ./dst

2
这个方法有效的原因是字符串“src / * .txt”被逐字地放置在echocp命令中,其中shell为每个命令再次扩展它(而不是make,它执行了$(wildcard)的扩展)。 - Jack Kelly
4
由于该变量在调用配方时展开(它使用“=”进行延迟展开,而不是“:=”进行立即或简单展开),因此您会期望原始makefile可以正常工作。但问题在于,为了提高效率,GNU make在进程中缓存目录的内容。所以,如果您以一种make无法识别的方式更改目录结构,就可能出现这种情况,即make对文件存在的想法与实际情况不符。 - MadScientist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接