Makefile:目标依赖关系-如何始终保持依赖关系? [英] Makefile: Target dependency - How to always-make it?
问题描述
这很可能是显而易见的和/或平庸的.但是由于我尝试了数小时的不同方法却没有成功...
我在Linux Mint 19上.我对Makefiles完全陌生.对不起,如果问题很简单.
I am on Linux Mint 19. I am entirely new to Makefiles. Excuse me, if the problem is trivial.
很明显,我只在这个问题上关心distrib
和SHA512SUMS
目标.
Let it be clear, that I care for the distrib
and SHA512SUMS
targets only in this question.
当我大量更改这些脚本的代码时,我希望每次运行distrib
目标时都重新生成SHA512SUMS
文件,但是当然不希望在运行check
目标时重新生成该文件,如您所见,这会使check
目标无关紧要.
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.
对于Shell脚本编写者来说,此Makefile变得有些复杂.任何帮助将不胜感激.
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.
因此,我创建了一个空目标force-rebuild-hash-file:
.
Hence, I created an empty target force-rebuild-hash-file:
.
因此,调用此目标或依赖它的distrib
目标时,将始终重新创建SHA512SUM
文件.
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.
我将SHA512SUMS
重命名为SHA512SUM
,这没什么大不了,但是我发现它更常用.
I renamed SHA512SUMS
to SHA512SUM
, it does not matter much, but I find it more used.
我发现$@
打印目标名称是跟踪正在运行的目标的好方法.例如,如果SHA512SUM
不存在,我们将像这样安装它:
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'
当前的Makefile
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
这篇关于Makefile:目标依赖关系-如何始终保持依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!