【问题标题】:Makefile repeatedly making .PHONY targetMakefile 反复制作 .PHONY 目标
【发布时间】:2020-06-04 08:40:47
【问题描述】:

我有一个如下所示的 Makefile:

.PHONY: aws-deps

requirements.txt: Pipfile Pipfile.lock
    pipenv lock -r > $@

aws-deps: requirements.txt
    pip3 install --upgrade --target aws_src/ -r $<

如果我多次运行make requirements.txt,它会正确地表示它是最新的。但是,如果我运行make aws-deps,它的行为不会像我期望的.PHONY 目标那样运行,它每次都会运行,无论requirements.txt 是否已更改。比如先删除 requirements.txt:

$ make aws-deps
pipenv lock -r > requirements.txt
pip3 install --upgrade --target aws_src/ -r requirements.txt
<snip>

$ make aws-deps
pip3 install --upgrade --target aws_src/ -r requirements.txt
<snip>

我是否误解了 .PHONY deps 的作用?我希望 aws-deps 仅在其先决条件发生变化时才做某事,即我的 requirements.txt 发生了变化 - 有人知道我在让它工作时缺少什么吗?

谢谢!

【问题讨论】:

    标签: makefile dependencies


    【解决方案1】:

    .PHONY 目标告诉 make 将目标视为不是文件,即使可能存在与该目标具有相同名称的文件。由于这里没有名为 aws-deps 的文件,.PHONY 对您的情况没有实际影响。相反,make 没有任何东西可以比较 requirements.txt 的时间戳,并假定必须运行 aws-deps 的规则。您可以通过

    来改变这种行为
    AWS_DEP = .aws-deps-done # hidden file to compare a timestamp against
    
    .PHONY: aws-deps
    
    aws-deps: $(AWS_DEP)
    
    $(AWS_DEP): requirements.txt
        pip3 install --upgrade --target aws_src/ -r $<
        @touch $@
    

    【讨论】:

    • 完美答案,谢谢! :) 这有点烦人,但这确实是有道理的。只有一个问题,为什么@touch 而不是touch?我发现用 google/SO 搜索这个是不可能的!
    • 我很乐意提供帮助 :) 在构建规则中的任何命令前添加 @ 前缀可确保该命令除了被执行之外不会被打印出来。它只是减少了琐碎命令的视觉噪音。
    【解决方案2】:

    我经历过类似的案例。我不太喜欢创建另一个文件 .hidden 或可见。但这就是我经常看到的。我查看了 GNU make 手册 [谁会这样做?],希望作者已经考虑了如此明显的事情。我找到了目标.INTERMEDIATE,它并不期待文件更新。所以,你的例子是:

    requirements.txt: Pipfile Pipfile.lock
        pipenv lock -r > $@
    
    .INTERMEDIATE: aws-deps
    aws-deps: requirements.txt
        pip3 install --upgrade --target aws_src/ -r $<
    

    它工作得很好,不需要写一个额外的文件作为标志。我使用此.INTERMEDIATE 目标类型在大量编译 PDF 文件之前打印一条消息,并在类似的大量编译 PNG 文件之前打印另一条消息。如果您尝试使用.PHONY,编译将重复。如果您在规则块内打印消息,它将为正在处理的每个文件打印。打印一次性消息是.INTERMEDIATE 的另一种用法。

    【讨论】:

    • 这是一个非常好的解决方案,感谢分享! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多