makefile - 如何在整个 Makefile 运行中重用包含时间戳的变量

标签 makefile

我正在编写一个简单的 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 ,...
  • ...我的 LaTeX 文件最终在 $(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/

    相关文章:

    c++ - 如何在构建之间保留 lldb session

    linux - 如何制作 'makefile"?编译错误

    shell - 在 makefile 中转义

    c - 是否可以通过 makefile 设置环境变量?

    makefile - 是否有一个足够智能的并行 make 系统可以智能地响应低内存/交换条件?

    c++ - C++ dyld:未加载库-设置 '-L'后

    makefile - make 中的高级自动依赖项

    c - 库不是使用 makefile 创建的

    makefile - 在 GNU Make 中加入列表的元素

    linux - 错误编译 freetype make : Nothing to be done for 'unix'