将整个目标锁定在 Makefile 中

问题描述 投票:0回答:2

我有一个 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
的定义肯定有问题,但我不明白是什么。

bash shell makefile locking sh
2个回答
3
投票

Make 在新 shell 中运行每个命令行。我猜你的fd在

eval
之后就消失了。您可以使用单个命令行并使用“;”分隔命令。如果为了清楚起见要分割命令行,则需要以“\”结束除最后一行之外的所有行。请参阅制作手册,拆分配方行。或者使用 shell 脚本。


0
投票

替代解决方案是使用

.ONESHELL
特殊目标,使整个目标在单个 shell 中运行,因此:

.ONESHELL: long_thing

long_thing:
  ...long recipe...

实际上,posix 的方式是使用

.ONESHELL
中的所有内容,所以:

.ONESHELL: %
© www.soinside.com 2019 - 2024. All rights reserved.