Make seems to think a prerequisite is an intermediate file, removes it

Posted by James on Stack Overflow See other posts from Stack Overflow or by James
Published on 2009-03-20T05:35:00Z Indexed on 2010/03/17 0:01 UTC
Read the original article Hit count: 403

Filed under:
|
|

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. :)

© Stack Overflow or respective owner

Related posts about makefile

Related posts about ssl