我有一个脚本,在运行时会生成一个文件。我想创建一个Makefile来运行脚本来生成文件,如果生成的文件不存在或者脚本发生了变化。
这是一个简化版本。我们假设我有一个像这样的可执行脚本gen_test.sh
:
#!/bin/sh
echo "This is a generated file" > genfile.foo
这样的Makefile:
#
# Test Makefile
#
GEN_SCRIPT = $(CURDIR)/gen_test.sh
GEN_FILE = $(CURDIR)/genfile.foo
$(GEN_FILE): $(GEN_SCRIPT)
$(shell $(GEN_SCRIPT))
.PHONY: clean
clean:
$(RM) $(GEN_FILE)
当我运行make
时,我看到以下输出:
make: '/workspace/sw/bhshelto/temp/makefile_test/genfile.foo' is up to date.
但genfile.foo
实际上已生成。
这里发生了什么?为什么我看到"是最新的"消息,我该如何摆脱它?
谢谢!
答案 0 :(得分:1)
当我运行
make
时,我看到以下输出:make: '/workspace/sw/bhshelto/temp/makefile_test/genfile.foo' is up to date.
但
genfile.foo
实际上已生成。
正如user657267建议:从配方正文中删除$(shell)
。
假设gen_test.sh
没有产生任何输出(或仅在stderr上输出),对行为的解释相当简单:
make
检测到需要重建$(GEN_FILE)
并调用规则。
在命令调用之前,make
执行命令内部变量的扩展。由于(不必要的)$(shell)
,在此扩展期间已经调用了$(GEN_SCRIPT)
。
$(GEN_SCRIPT)
可以正常工作,但不会产生任何输出,因此$(shell $(GEN_SCRIPT))
会扩展为空字符串。
看到命令为空,因此没有命令可以运行。
make
然后再次检查文件(如果变量扩展有副作用)并且看到目标是最新的。但是,由于展开的命令为空,make
会打印其通用的is up to date
消息。