【问题标题】:Make seems to think a prerequisite is an intermediate file, removes itMake似乎认为先决条件是一个中间文件,将其删除
【发布时间】:2010-10-14 11:39:06
【问题描述】:

对于初学者来说,GNU make 中的这个练习无疑只是:练习而不是实用性,因为一个简单的 bash 脚本就足够了。 然而,它带来了我不太理解的有趣行为。

我编写了一个看似简单的 Makefile 来处理 SSL 密钥/证书对 as necessary for MySQL 的生成。我的目标是让make <name> 生成<name>-key.pem<name>-cert.pem 和任何其他必要的文件(特别是CA 对,如果其中任何一个丢失或需要更新,这会导致另一个有趣的后续处理练习反向部门重新颁发已由丢失/更新的 CA 证书签名的任何证书)。

按预期执行所有规则后,make 似乎过于激进地识别要删除的中间文件;它删除了一个我认为是“安全”的文件,因为它应该是作为我正在调用的主要规则的先决条件生成的。 (谦虚地翻译,我可能误解了 make 的 documented behavior 以符合我的期望,但不明白如何。;-)

已编辑(感谢Chris!)%-cert.pem 添加到.PRECIOUS 当然可以防止删除。 (我一直使用错误的语法。)

生成文件:

OPENSSL = /usr/bin/openssl

# 已更正,谢谢 Chris!
.PHONY:干净

默认值:ca

干净的:
        rm -I *.pem

%: %-key.pem %-cert.pem
        @# 占位符(使这个隐式创建一个规则而不是取消一个)

生成文件:
        @# 防止 catch-all 匹配 Makefile

ca-cert.pem:ca-key.pem
        $(OPENSSL) req -new -x509 -nodes -days 1000 -key ca-key.pem > $@

%-key.pem:
        $(OPENSSL) genrsa 2048 > $@

%-cert.pem: %-csr.pem ca-cert.pem ca-key.pem
        $(OPENSSL) x509 -req -in $$@

输出:

$ 制作主机1
/usr/bin/openssl genrsa 2048 > ca-key.pem
/usr/bin/openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem
/usr/bin/openssl genrsa 2048 > host1-key.pem
/usr/bin/openssl req -new -days 1000 -nodes -key host1-key.pem > host1-csr.pem
/usr/bin/openssl x509 -req -in host1-csr.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > host1-cert.pem
rm host1-csr.pem host1-cert.pem

这让我发疯了,我很乐意尝试任何建议并发布结果。如果我只是对这个完全不感兴趣,请随意嘲笑。你不可能伤害我的感情。 :)

【问题讨论】:

  • +1 因为这是 GNU make 中一个有趣的利基市场,但没有得到很好的探索......

标签: mysql ssl makefile


【解决方案1】:

http://www.gnu.org/software/automake/manual/make/Chained-Rules.html#Chained-Rules

您可以防止自动删除 通过将其标记为中间文件 次要文件。为此,请列出 作为特殊的先决条件 目标.SECONDARY。当一个文件是 次要的,make 不会创建 文件只是因为它没有 已经存在,但 make 不存在 自动删除文件。打标 作为次要的文件也将其标记为 中级。

http://www.gnu.org/software/automake/manual/make/Special-Targets.html

.PRECIOUS 所依赖的目标如下 特殊处理:如果 make 被杀死 或在执行过程中中断 他们的命令,目标不是 删除。见打断或杀死 制作。此外,如果目标是 中间文件,不会 不再需要后删除, 像往常一样。见链 隐式规则。在这后一方面 它与 .SECONDARY 重叠 特殊目标。

您还可以列出隐式规则的目标模式(例如 `%.o') 作为 特殊目标 .PRECIOUS 保存 由规则创建的中间文件 其目标模式匹配 文件名。

【讨论】:

    【解决方案2】:

    我注意到的第一件事是你的台词:

    .PHONY = clean
    

    应该是:

    .PHONY : clean
    

    见:http://www.gnu.org/software/automake/manual/make/Phony-Targets.html

    【讨论】:

    • 当然,这也是我使用 .PRECIOUS 失败的原因。感谢您接听!
    【解决方案3】:

    请注意,%: %-key.pem %-cert.pem 之类的模式规则是隐式规则,它应用中间清理规则。

    对于真正要构建的目标文件,使其明确,即不要使用模式规则。

    在您的情况下,Makefile 应该是:

    OPENSSL = /usr/bin/openssl
    # Replace this to match your host files
    HOSTS=$(wildcard host*) 
    
    # Corrected, thanks Chris!
    .PHONY: clean
    
    default: ca-cert.pem
    
    clean:
            rm -I *.pem
    
    ca-cert.pem: ca-key.pem
            $(OPENSSL) req -new -x509 -nodes -days 1000 -key ca-key.pem > $@
    
    $(addsuffix -key.pem,$(HOSTS)): %-key.pem : $(HOSTS)
            $(OPENSSL) genrsa 2048 > $@
    
    $(addsuffix -cert.pem,$(HOSTS)): %-cert.pem: %-csr.pem ca-cert.pem ca-key.pem
            $(OPENSSL) x509 -req -in $ $@
    

    【讨论】:

      【解决方案4】:

      试试:

      .SECONDARY: $(wildcard *-csr.pem) $(wildcard *-cert.pem)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-03
        • 2018-05-06
        • 1970-01-01
        • 2021-04-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多