对于初学者来说,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
这让我发疯,我很乐意尝试任何建议并发布结果。如果我只是在这个上面完全不知所措,请随意嘲笑。你不可能伤害我的感情。 :)
答案 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)