Make似乎认为先决条件是一个中间文件,删除它

时间:2009-03-20 05:35:00

标签: mysql ssl makefile

对于初学者来说,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

# Corrected, thanks Chris!
.PHONY: clean

default: ca

clean:
        rm -I *.pem

%: %-key.pem %-cert.pem
        @# Placeholder (to make this implicit create a rule and not cancel one)

Makefile:
        @# Prevent the catch-all from matching 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 $ $@

输出:

$ make host1
/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  

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

4 个答案:

答案 0 :(得分:3)

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

  

您可以阻止自动删除   标记为的中间文件   辅助文件。为此,请列出它   作为特殊的先决条件   目标.SECONDARY。当文件是   二级,make不会创建   文件只是因为它没有   已经存在,但制造没有   自动删除文件。印记   作为辅助文件也将其标记为   中间。

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

  

.PRECIOUS所依赖的目标如下   特殊待遇:如果制造被杀死   或在执行期间中断   他们的命令,目标不是   删除。请参阅中断或杀戮   使。此外,如果目标是   中间文件,它不会   在不再需要之后删除   通常这样做。见链条   隐含规则。在后一方面   它与.SECONDARY重叠   特殊目标。

     

您还可以列出隐式规则的目标模式(例如   `%。o')作为的先决条件文件   特殊目标。保护   规则创建的中间文件   其目标模式与之匹配   文件名。

答案 1 :(得分:2)

我注意到的第一件事就是你的行:

.PHONY = clean

应该是:

.PHONY : clean

请参阅:http://www.gnu.org/software/automake/manual/make/Phony-Targets.html

答案 2 :(得分:1)

请注意,%: %-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 $ $@

答案 3 :(得分:0)

尝试:

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