我正在编写一个简单的Makefile来处理我从一系列Markdown文本源创建的文档(PDF,HTML,LaTeX,EPUB,DOCX)。
现在我想将一些中间文件作为副本备份到一个单独的目录中,在过程中通过向其名称添加时间戳来重命名它们。
但是,我没有让它发挥作用。我定义了一个时间戳变量,如下所示:
.PHONY: timestamp
timestamp: ts := `/bin/date "+%Y-%m-%d---%H-%M-%S"`
timestamp:
@echo Timestamp is $(ts)
%.tex: %.mmd timestamp
# My commands to create the LaTeX go here. (Simplified for Stackoverflow)
pandoc -t latex -f markdown -o $(LATEXDIR)/$@ $<
$(CP) $(LATEXDIR)/$@ $(BACKUPS)/$(ts)---$@
(是的,我在Makefile中使用了标签 - 不要被上面的复制所迷惑,如果你从它上面复制'''''',那么
当我运行make timestamp
时,我会看到预期的输出,例如Timestamp is 2014-11-01---22-11-10
。
但是正在运行make bookdraft.tex
,...
$(LATEXDIR)
,---bookdraft.tex
,而不是2014-11-01---22-11-10---bookdraft.tex
所以我的ts
变量丢失了......
我是Makefiles的初学者,几个小时的谷歌搜索和实验并没有把我带到任何地方。
注意,我可以在当前目标内动态设置时间戳。但是,这将更改在同一make
调用期间备份的每个其他目标的时间戳。但这不是我想要的 - 我希望每次调用make
时将时间戳固定为相同的值。所以我想以某种方式在Makefile的开头设置timestamp变量,然后在make
的当前运行中重复使用它。 (make的下一次运行应该重新设置值。)
我想出了一个临时的解决方法,将时间戳写入名为.ts
的文件中,然后再从那里读取它:
timestamp:
@echo `/bin/date "+%Y-%m-%d---%H-%M-%S"` > .ts
然后再说:
%.tex: %.mmd timestamp
# My commands to create the LaTeX go here. (Simplified for Stackoverflow)
pandoc -t latex -f markdown -o $(LATEXDIR)/$@ $<
$(CP) $(LATEXDIR)/$@ $(BACKUPS)/`/bin/cat .ts`---$@
但是,我不太喜欢这种管道磁带方法 - 我正在寻找一种更优雅的Makefile-ish解决方案。
更新
乔纳森莱弗勒提出了一个解决方案,但这不符合我的要求......或者他不明白我想要什么,因为我没有解释得很好,或者我没有正确地实施他的建议。无论如何,我现在可以更好地说明我不想要的东西。考虑这个 Makefile.leffler (在代码中正确完成<tabs>
):
ts := `/bin/date "+%Y-%m-%d---%H-%M-%S"`
timestamp:
@echo Timestamp is $(ts)
@sleep 10
@echo Timestamp is $(ts)
dummy:
@sleep 10
@echo Timestamp is $(ts)
@sleep 10
@echo Timestamp is $(ts)
当我运行make -f Makefile.leffler timestamp dummy
时,输出为:
Timestamp is 2014-01-13---01-58-43
Timestamp is 2014-01-13---01-58-53
Timestamp is 2014-01-13---01-59-03
Timestamp is 2014-01-13---01-59-13
那就是不我想要的东西!我想要这个:
Timestamp is 2014-01-13---01-58-43
Timestamp is 2014-01-13---01-58-43
Timestamp is 2014-01-13---01-58-43
Timestamp is 2014-01-13---01-58-43
我希望我的目标现在得到更好的澄清。
在修改了Jonathan的原始答案后,现在这是Makefile示例的解决方案:
ts := $(shell /bin/date "+%Y-%m-%d---%H-%M-%S")
timestamp:
@echo Timestamp is $(ts)
@sleep 10
@echo Timestamp is $(ts)
dummy:
@sleep 10
@echo Timestamp is $(ts)
@sleep 10
@echo Timestamp is $(ts)
make -f Makefile.leffler timestamp dummy
的输出现在完全符合我的要求:
Timestamp is 2014-01-13---02-44-11
Timestamp is 2014-01-13---02-44-11
Timestamp is 2014-01-13---02-44-11
Timestamp is 2014-01-13---02-44-11
答案 0 :(得分:11)
不要让ts
以timestamp
:
ts := $(shell /bin/date "+%Y-%m-%d---%H-%M-%S")
timestamp:
@echo Timestamp is $(ts)
%.tex: %.mmd
# My commands to create the LaTeX go here. (Simplified for Stackoverflow)
pandoc -t latex -f markdown -o $(LATEXDIR)/$@ $<
$(CP) $(LATEXDIR)/$@ $(BACKUPS)/$(ts)---$@
这与先前提出的解决方案不同,它使用GNU make
$(shell ...)
函数。定义宏时会对此进行评估。通过此更改,修订问题中测试makefile的输出(例如):
$ make -f ts.mk
Timestamp is 2014-01-12---17-16-35
Timestamp is 2014-01-12---17-16-35
$ make -f ts.mk timestamp dummy
Timestamp is 2014-01-12---17-16-53
Timestamp is 2014-01-12---17-16-53
Timestamp is 2014-01-12---17-16-53
Timestamp is 2014-01-12---17-16-53
$
或者,在时间戳之前和之后使其更清晰(10秒是一个非常长的延迟,有时!),你可能会得到:
$ date; make -f ts.mk timestamp dummy; date
Sun Jan 12 17:19:02 PST 2014
Timestamp is 2014-01-12---17-19-02
Timestamp is 2014-01-12---17-19-02
Timestamp is 2014-01-12---17-19-02
Timestamp is 2014-01-12---17-19-02
Sun Jan 12 17:19:32 PST 2014
$