我有一个 Makefile,其目标执行多个系统范围的操作(例如安装软件包),因此我想以其他 make 进程等待该目标的方式锁定目标,从而防止并行执行。
我尝试按照这个答案中的解释使用flock,但我认为makefiles的特殊性正在阻碍。
这就是我现在拥有的:
LOCKFILE=/var/lock/makefile.lock
LOCKFD=200
mytarget:
# make sure to release the lock in any case
eval "exec $(LOCKFD)>$(LOCKFILE)"; trap "flock -xn $(LOCKFD) && rm -f $(LOCKFILE)" EXIT
# get exclusive waiting lock
flock -x $(LOCKFD)
[regular target operations...]
# release lock and delete the lock file
flock -u $(LOCKFD); flock -xn $(LOCKFD) && rm -f $(LOCKFILE)
由于此错误而失败,因为文件描述符 200 未正确设置:
$ make mytarget
# make sure to release the lock in any case
eval "exec 200>/var/lock/makefile.lock"; trap "flock -xn 200 && rm -f /var/lock/makefile.lock" EXIT
# get exclusive waiting lock
flock -x 200
flock: 200: Bad file descriptor
Makefile:57: recipe for target 'mytarget' failed
eval
的定义肯定有问题,但我不明白是什么。
Make 在新 shell 中运行每个命令行。我猜你的fd在
eval
之后就消失了。您可以使用单个命令行并使用“;”分隔命令。如果为了清楚起见要分割命令行,则需要以“\”结束除最后一行之外的所有行。请参阅制作手册,拆分配方行。或者使用 shell 脚本。
替代解决方案是使用
.ONESHELL
特殊目标,使整个目标在单个 shell 中运行,因此:
.ONESHELL: long_thing
long_thing:
...long recipe...
实际上,posix 的方式是使用
.ONESHELL
中的所有内容,所以:
.ONESHELL: %