我正在编写一个简单的 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 中使用选项卡——不要被上面的复制所迷惑,如果你从中复制'n'粘贴......)
当我跑
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 的开头设置时间戳变量,然后在当前运行的 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 解决方案。
更新:
Jonathan Leffler 提出了一个解决方案,但这与我的要求不符……或者他不明白我想要什么,因为我解释得不够好,或者我没有正确实现他的建议。无论如何,我现在可以更好地说明我不想要的东西。
考虑这个 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
我希望我的目标现在更清楚了。
解决方案/更新 2:
在修改了 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
最佳答案
不做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
$
关于makefile - 如何在整个 Makefile 运行中重用包含时间戳的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21081596/