Make 似乎认为先决条件是中间文件,将其删除

发布于 2024-07-15 12:59:37 字数 2005 浏览 1 评论 0 原文

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

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

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

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

Makefile:

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  

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

For starters, this exercise in GNU make was admittedly just that: an exercise rather than a practicality, since a simple bash script would have sufficed. However, it brought up interesting behavior I don't quite understand.

I've written a seemingly simple Makefile to handle generation of SSL key/cert pairs as necessary for MySQL. My goal was for make <name> to result in <name>-key.pem, <name>-cert.pem, and any other necessary files (specifically, the CA pair if any of it is missing or needs updating, which leads into another interesting follow-up exercise of handling reverse deps to reissue any certs that had been signed by a missing/updated CA cert).

After executing all rules as expected, make seems to be too aggressive at identifying intermediate files for removal; it removes a file I thought would be "safe" since it should have been generated as a prereq to the main rule I'm invoking. (Humbly translated, I likely have misinterpreted make's documented behavior to suit my expectation, but don't understand how. ;-)

Edited (thanks, Chris!) Adding %-cert.pem to .PRECIOUS does, of course, prevent the deletion. (I had been using the wrong syntax.)

Makefile:

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 $ $@

Output:

$ 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  

This is driving me crazy, and I'll happily try any suggestions and post results. If I'm just totally noobing out on this one, feel free to jibe away. You can't possibly hurt my feelings. :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

软糖 2024-07-22 12:59:37

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

您可以防止自动删除
中间文件,将其标记为
辅助文件。 要执行此操作,请将其列出
作为特殊的先决条件
目标.SECONDARY。 当一个文件是
其次,make不会创建
文件仅仅因为它不
已经存在,但 make 不存在
自动删除该文件。 标记
作为次要文件也将其标记为
中间。

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

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

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

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

You can prevent automatic deletion of
an intermediate file by marking it as
a secondary file. To do this, list it
as a prerequisite of the special
target .SECONDARY. When a file is
secondary, make will not create the
file merely because it does not
already exist, but make does not
automatically delete the file. Marking
a file as secondary also marks it as
intermediate.

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

The targets which .PRECIOUS depends on are given the following
special treatment: if make is killed
or interrupted during the execution of
their commands, the target is not
deleted. See Interrupting or Killing
make. Also, if the target is an
intermediate file, it will not be
deleted after it is no longer needed,
as is normally done. See Chains of
Implicit Rules. In this latter respect
it overlaps with the .SECONDARY
special target.

You can also list the target pattern of an implicit rule (such as
`%.o') as a prerequisite file of the
special target .PRECIOUS to preserve
intermediate files created by rules
whose target patterns match that
file's name.

寂寞清仓 2024-07-22 12:59:37

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

.PHONY = clean

应该是:

.PHONY : clean

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

The first thing i noticed is that your line:

.PHONY = clean

should be:

.PHONY : clean

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

慕巷 2024-07-22 12:59:37

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

Note that pattern rules like %: %-key.pem %-cert.pem are implicit rules, which apply the intermediate clean up rule.

For the files that are truly targets to be built, make them explicit, i.e. don't use pattern rules.

In your case, the Makefile should be:

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 $ $@
提笔落墨 2024-07-22 12:59:37

尝试:

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

Try:

.SECONDARY: $(wildcard *-csr.pem) $(wildcard *-cert.pem)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文