Параллельное создание - подпроекты вызываются несколько раз

На вопрос уже дан ответ на уровне файлов. Но у меня есть более крупный проект, который имеет довольно много межпроектных зависимостей (вызванных заголовками DBus, которые генерировались динамически).

Я создал следующий пример ( файлы примеров в виде ZIP - реальный проект намного сложнее).

Верхний уровень Makefile является следующим:

sub-%:
    $(MAKE) -C $(patsubst sub-%,%,$@)

default:
    $(MAKE) -j12 sub-p1 sub-p2 sub-p3

Makefile подпроекта выглядит так (p1, p2 а также p3):

all: p1

../lib/lib.a:
    $(MAKE) -C ../lib lib.a

p1: ../lib/lib.a
    cp -f ../lib/lib.a p1

И Makefile из lib выглядит так:

lib.a:
    sleep 2
    date > $@
    echo Done with building $@

ПРОБЛЕМА: библиотека построена для каждого p*-проектировать отдельно параллельно - в этом примере это не проблема, но в нашем случае это вызывает неразрешимые проблемы.

Когда я звоню make на верхнем уровне я получаю следующий вывод:

$ make
make -j12 sub-p1 sub-p2 sub-p3
make[1]: Entering directory '/home/kkr/tmp/parallelmake'
make -C p1
make -C p2
make -C p3
make[2]: Entering directory '/home/kkr/tmp/parallelmake/p1'
make -C ../lib lib.a
make[2]: Entering directory '/home/kkr/tmp/parallelmake/p2'
make -C ../lib lib.a
make[2]: Entering directory '/home/kkr/tmp/parallelmake/p3'
make -C ../lib lib.a
make[3]: Entering directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Entering directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Entering directory '/home/kkr/tmp/parallelmake/lib'
sleep 2
sleep 2
sleep 2
date > lib.a
date > lib.a
date > lib.a
make[3]: Leaving directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Leaving directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Leaving directory '/home/kkr/tmp/parallelmake/lib'
cp -f ../lib/lib.a p3
cp -f ../lib/lib.a p1
cp -f ../lib/lib.a p2
make[2]: Leaving directory '/home/kkr/tmp/parallelmake/p3'
make[2]: Leaving directory '/home/kkr/tmp/parallelmake/p1'
make[2]: Leaving directory '/home/kkr/tmp/parallelmake/p2'
make[1]: Leaving directory '/home/kkr/tmp/parallelmake'

ВОПРОС: Можно ли как-то автоматически синхронизировать подпроекты?

Так как real project имеет 13 подпроектов - большинство из которых имеют межпроектные зависимости - ручная синхронизация будет довольно сложной.

1 ответ

У рекурсивной системы make явно нет возможности "автоматически" синхронизировать это; они являются совершенно отдельными процессами и не могут сказать друг другу, что у них заданная цель.

У вас есть два варианта. Первое, что лучше, но может потребовать много работы, - это переработать вашу систему сборки, чтобы она не была рекурсивной. Если у вас есть один вызов make, который собирает всю систему, тогда существует только один экземпляр make, и он будет глобально координировать создание всех целей. Вам не понадобится $(MAKE) -C ../lib lib.a правила вообще.

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

default: p1 p2 p3

p%: ; $(MAKE) -C $@

.PHONY: default p1 p2 p3

Теперь предположим, что вы хотите убедиться, что p1 работает до p2 а также p3 потому что ты хочешь p1 построить все общие цели; тогда вы добавите такое правило в make-файл верхнего уровня:

p2 p3: p1

И вы можете добавлять другие заказы по мере необходимости.

Другие вопросы по тегам