This will most probably be obvious and / or a banality. But since I am trying different approaches for hours without success...
I am on Linux Mint 19. I am entirely new to Makefiles. Excuse me, if the problem is trivial.
Let it be clear, that I care for the distrib
and SHA512SUMS
targets only in this question.
As I heavily change the code of those scripts, I would like the SHA512SUMS
file to be re-generated each time I run the distrib
target, but not in case I run the check
target, of course, that would make the check
target irrelevant, as you can see.
This Makefile is becoming to be a little complicated for a shell scripter. Any help will be appreciated.
PREFIX?=/usr/local/bin
install_path=$(DESTDIR)$(PREFIX)
encrypt_script=encrypt-file-aes256
decrypt_script=decrypt-file-aes256
distrib_name=openssl-file-encryption-decryption-shell-scripts
.PHONY: check install uninstall distrib
check: $(encrypt_script) $(decrypt_script) SHA512SUMS
echo && sha512sum --check --status SHA512SUMS && ( echo "Ok. You may use 'sudo make install' or '(sudo) make install PREFIX=SomeDir' command now." ) || ( echo "ERROR: Files hash sum mismatch!" && echo && exit 1 )
install: check
echo && [ -d $(install_path) ] || mkdir --parents $(install_path)
install --verbose --mode=0755 --target-directory=$(install_path) $(encrypt_script) $(decrypt_script)
uninstall:
rm $(install_path)/$(encrypt_script) $(install_path)/$(decrypt_script)
rmdir --ignore-fail-on-non-empty $(install_path)
distrib: check $(encrypt_script) $(decrypt_script) Makefile SHA512SUMS
if [ $$(id --user) -eq 0 ]; then ( echo && echo "Target 'distrib' has to be run as normal user!" && echo && exit 1 ) fi
rm --force $(distrib_name).tar.xz
rm --force $(distrib_name).tar.xz.asc
rm --force --recursive $(distrib_name)
mkdir $(distrib_name)
# sha512sum $(encrypt_script) $(decrypt_script) > $(distrib_name)/SHA512SUMS
cp $(encrypt_script) $(decrypt_script) Makefile SHA512SUMS $(distrib_name)
wget --quiet --output-document=$(distrib_name)/LICENSE https://git.io/fxByv # https://raw.githubusercontent.com/burianvlastimil/openssl-file-encryption-decryption-shell-scripts/master/LICENSE
wget --quiet --output-document=$(distrib_name)/README.md https://git.io/fxByJ # https://raw.githubusercontent.com/burianvlastimil/openssl-file-encryption-decryption-shell-scripts/master/README.md
chmod 755 $(distrib_name)/$(encrypt_script) $(distrib_name)/$(decrypt_script)
chmod 644 $(distrib_name)/Makefile $(distrib_name)/SHA512SUMS $(distrib_name)/LICENSE $(distrib_name)/README.md
tar --create --file=$(distrib_name).tar $(distrib_name)
xz --format=xz -9 --extreme --check=sha256 $(distrib_name).tar
rm --force --recursive $(distrib_name)
gpg --local-user 7D2E022E39A88ACF3EF6D4498F37AF4CE46008C3 --sign --armor --output $(distrib_name).tar.xz.asc --detach-sig $(distrib_name).tar.xz
SHA512SUMS:
sha512sum --check --status SHA512SUMS || sha512sum $(encrypt_script) $(decrypt_script) > SHA512SUMS
Reading on Force Targets, I came up, hopefully, with a solution below:
If a rule has no prerequisites or recipe, and the target of the rule is a nonexistent file, then make imagines this target to have been updated whenever its rule is run. This implies that all targets depending on this one will always have their recipe run.
Hence, I created an empty target force-rebuild-hash-file:
.
Thus, the SHA512SUM
file will always be re-created when calling this target or distrib
target which depends on it.
I think it is finally solved overall, feel free to comment, if not.
In case you or I, myself, find any errors, I will update this answer to reflect them.
To de-duplicate some code I came across this answer and applied it.
I renamed SHA512SUMS
to SHA512SUM
, it does not matter much, but I find it more used.
I found $@
to print target names a good way of keeping track of what targets are being run. For instance, if SHA512SUM
does not exist and we install it like this:
make install PREFIX=./test
we get a very nice overview (output):
echo && echo Target: check && echo
Target: check
if [ -f SHA512SUM ]; then ( echo && sha512sum --check SHA512SUM && ( echo && echo "Ok. You may use 'sudo make install' or '(sudo) make install PREFIX=SomeDir' command now." ) || ( echo && echo "ERROR: Files hash sum mismatch!" && echo && exit 1 ) ) else make --file=Makefile SHA512SUM; fi
make[1]: Entering directory '/home/vlastimil/Development/sh/openssl-encryption'
echo && echo Target: SHA512SUM && echo
Target: SHA512SUM
sha512sum encrypt-file-aes256 decrypt-file-aes256 > SHA512SUM
make[1]: Leaving directory '/home/vlastimil/Development/sh/openssl-encryption'
echo && echo Target: install && echo
Target: install
echo && [ -d ./test ] || mkdir --parents ./test
install --verbose --mode=0755 --target-directory=./test encrypt-file-aes256 decrypt-file-aes256
'encrypt-file-aes256' -> './test/encrypt-file-aes256'
'decrypt-file-aes256' -> './test/decrypt-file-aes256'
Current Makefile
DESTDIR ?=
PREFIX ?= /usr/local/bin
install_path := $(DESTDIR)$(PREFIX)
encrypt_script := encrypt-file-aes256
decrypt_script := decrypt-file-aes256
distrib_name := openssl-encryption
this_file := $(lastword $(MAKEFILE_LIST))
.PHONY: check install uninstall distrib
# https://stackoverflow.com/a/27132934/1997354
check: $(encrypt_script) $(decrypt_script)
echo && echo Target: $@ && echo
if [ -f SHA512SUM ]; then ( echo && sha512sum --check SHA512SUM && ( echo && echo "Ok. You may use 'sudo make install' or '(sudo) make install PREFIX=SomeDir' command now." ) || ( echo && echo "ERROR: Files hash sum mismatch!" && echo && exit 1 ) ) else $(MAKE) --file=$(this_file) SHA512SUM; fi
install: check
echo && echo Target: $@ && echo
echo && [ -d $(install_path) ] || mkdir --parents $(install_path)
install --verbose --mode=0755 --target-directory=$(install_path) $(encrypt_script) $(decrypt_script)
uninstall:
echo && echo Target: $@ && echo
rm $(install_path)/$(encrypt_script) $(install_path)/$(decrypt_script)
rmdir --ignore-fail-on-non-empty $(install_path)
distrib: SHA512SUM check $(encrypt_script) $(decrypt_script) Makefile
echo && echo Target: $@ && echo
# https://english.stackexchange.com/a/468131/319970
# https://stackoverflow.com/a/52782747/1997354
if [ $$(id --user) -eq 0 ]; then ( echo && echo "Target 'distrib' has to be run as normal user!" && echo && exit 1 ) fi
rm --force $(distrib_name).tar.xz
rm --force $(distrib_name).tar.xz.asc
rm --force --recursive $(distrib_name)
mkdir $(distrib_name)
cp $(encrypt_script) $(decrypt_script) Makefile SHA512SUM $(distrib_name)
wget --quiet --output-document=$(distrib_name)/LICENSE https://git.io/fxByv
wget --quiet --output-document=$(distrib_name)/README https://git.io/fxByJ
chmod 755 $(distrib_name)/$(encrypt_script) $(distrib_name)/$(decrypt_script)
chmod 644 $(distrib_name)/Makefile $(distrib_name)/SHA512SUM $(distrib_name)/LICENSE $(distrib_name)/README
tar --create --file=$(distrib_name).tar $(distrib_name)
xz --format=xz -9 --extreme --check=sha256 $(distrib_name).tar
rm --force --recursive $(distrib_name)
gpg --local-user 7D2E022E39A88ACF3EF6D4498F37AF4CE46008C3 --sign --armor --output $(distrib_name).tar.xz.asc --detach-sig $(distrib_name).tar.xz
# https://www.gnu.org/software/make/manual/html_node/Force-Targets.html
force-rebuild-hash-file:
# real target file
SHA512SUM: force-rebuild-hash-file
echo && echo Target: $@ && echo
sha512sum $(encrypt_script) $(decrypt_script) > SHA512SUM
You could also declare SHA512SUM
as order-only prerequisite of check, not a prerequisite of distrib
but add $(MAKE) --always-make SHA512SUM
to your distrib
recipe:
check: $(encrypt_script) $(decrypt_script) | SHA512SUM
...
distrib: check $(encrypt_script) $(decrypt_script) Makefile
$(MAKE) --always-make SHA512SUM
...
I think the best would be to remove the explicit dependency on SHA512SUMS from the check
-target, and have a (shell) test inside that target and explicitly create the file if it's not there yet:
check: ...
...
if [ ! -e SHA512SUM ] ; then <create SHA512SUM HERE>; fi
.. do something with SHA512SUM ...