2016-09-19 3 views
2

У меня есть Makefile с целью, которая выполняет несколько общесистемных операций (например, установка пакетов), поэтому я хочу заблокировать цель так, чтобы другие make-процессы подождали эту цель, предотвращая параллельное выполнение.Заблокировать целую цель в Makefile

Я попытался использовать стадо, как описано в this answer, но я думаю, что особенности make-файлов мешают.

Это то, что я прямо сейчас:

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 определение, но я не вижу, что.

+0

@shellter Все, что объяснено в ответе, я связался с вопросом. EXIT - это имя сигнала для ловушки и выглядит как 'eval', иначе' exec' интерпретирует fd как команду. – framos

+0

Для дальнейшего использования ссылки на внешние сайты не являются хорошей идеей. Вопросы должны быть автономными. Если для вашей информации есть внешний источник, вы можете включить это, но вы должны отредактировать Q, чтобы включить соответствующие факты. Ответ ниже выглядит хорошо. Удачи. – shellter

+0

Блокировка затрудняет задачу, и цель ничего не выполняет. Я думаю, вы пытаетесь принудить вас к тому, чтобы делать то, что было сделано, чтобы обеспечить альтернативу. Вам действительно нужно блокировать здесь? Когда процесс A должен «ждать» в процессе B, сделать B создать цель после ее завершения и сделать эту цель зависимой от A. – reinierpost

ответ

3

Сделать прогон каждой командной строки в новой оболочке. Я думаю, ваш fd исчез после eval. Вы можете использовать одну командную строку и отдельные команды с помощью «;». Если вы хотите разделить командную строку для ясности, вам нужно завершить все, кроме последней строки, с помощью «\». См. Руководство по эксплуатации, Splitting Recipe Lines. Или используйте сценарий оболочки.

+0

Спасибо за ваш ответ и ссылку на руководство по эксплуатации! Я думаю, что ваша идея извлечь все в сценарий оболочки будет работать лучше всего, я попробую и отправлю отчет. – framos

+0

Извлечение всего, чтобы скрипт работал, спасибо @rveerd! – framos

Смежные вопросы