Параллельное создание - подпроекты вызываются несколько раз
На вопрос уже дан ответ на уровне файлов. Но у меня есть более крупный проект, который имеет довольно много межпроектных зависимостей (вызванных заголовками 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
И вы можете добавлять другие заказы по мере необходимости.