Make seems to think a prerequisite is an intermediate file, removes it
- by James
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. :)