Предотвращение выполнения двумя экземплярами make одной и той же цели (параллельное создание) - PullRequest
4 голосов
/ 15 марта 2011

Я пытаюсь заставить параллельную работу работать на нашем сервере сборки. Здесь я сталкиваюсь с очень частой проблемой, когда два случая, когда make пытается создать две разные цели, скажем, A и B, почти одновременно пытаются создать цель, которая требуется обоим, скажем C.

Поскольку оба экземпляра пытаются собрать C вместе в разных экземплярах, C make завершается неудачей для любого из них, поскольку для создания одного из C необходимо несколько файлов переместить сюда и туда, и любой из этих экземпляров в конечном итоге перемещает или удаляет уже созданный файл.

Существует ли общая конструкция, которую я могу использовать для предотвращения повторного входа в make-файл, если цель уже выполняется?

Обновление:

Хорошо, позвольте мне сказать это так: Мое заявление требует присутствия A.lo и B.lo. Эти A.lo и B.lo являются библиотеками, которые также связываются с C.lo. Так что правила выглядят как

app.d: A.lo B.lo (другие lo)

(сделать ссылку)

В другом каталоге произнесите A (в котором будет A.lo):

A.lo: C.lo (другие .o s и .lo s)

(сделать ссылку)

В каком-то другом каталоге произнесите B (в котором будет B.lo):

B.lo: C.lo (другие .o s и .lo s)

(сделать ссылку)

Таким образом, при создании app.d вилы делаются с двумя параллельными марками для целей A.lo и B.lo. При входе в каталоги A и B производят раздвоение еще двух потоков для целевого C.lo независимо, и иногда оба они одновременно связывают C.lo, что приводит к сбою одного из них с некоторыми странными ошибками, такими как файл не распознается ( поскольку он может быть записан другим экземпляром компоновщика)

Как мне решить эту проблему? Невозможно создать A.lo и B.lo без C.lo, связанного с ними.

Ответы [ 2 ]

2 голосов
/ 11 апреля 2012

Это может звучать немного, ну, очевидно , но самое простое решение - просто организовать явное построение C перед A или B.Таким образом, когда рекурсивный прогон для A и B запускается, C уже будет обновлен, и ни один из них не будет пытаться его построить.:

all: buildA buildB
buildA:
    $(MAKE) -C A

buildB:
    $(MAKE) -C B

Вы можете расширить его следующим образом:

all: buildA buildB
buildA: buildC
    $(MAKE) -C A

buildB: buildC
    $(MAKE) -C B

buildC:
    $(MAKE) -C C

Вы не предоставили много подробностей о вашей конкретной сборке, так что, вероятно, это не будет просто вставкаи работать, но, надеюсь, вы поняли.

1 голос
/ 23 августа 2013

Я решаю эту проблему, используя технику "mkdir":

SHELL = /bin/bash

all: targetC targetD

targetC: targetA
............

targetD: targetB
............

targetA targetB: source
    -mkdir source.lock && ( $(command) < source ; rm -r source.lock )
    $(SHELL) -c "while [ -d source.lock ] ; do sleep 0.1 ; done"

Я был бы рад увидеть более элегантное решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...