Вы можете разделить выполнение на непараллельную (для release
) и параллельную (для остальных целей) фазы.
ifneq ($(filter release,$(MAKECMDGOALS)),)
.NOTPARALLEL:
endif
release: clean
$(MAKE) test1
.NOTPARALLEL
цель будет подавлять параллельвыполнение, если в командной строке указана цель release
.Сама цель release
будет перезапущена Make после очистки и параллельной сборки test1
.
UPD.
Более умное решение также повторно вызовет Make для каждой отдельной цели в случае, если их большечем одна цель, указанная в командной строке, так что присутствие цели release
не заставит остальных выполнять также непараллельно.
ifneq ($(words $(MAKECMDGOALS)),1)
.NOTPARALLEL:
$(sort all $(MAKECMDGOALS)):
@$(MAKE) -f $(firstword $(MAKEFILE_LIST)) $@
else
# ...
endif
Приведенное выше умное решение не работает с версиями GNU make, которые не поддерживают серверы заданий.Например, выпущенные версии MinGW / native GNU make до версии 4.0 не поддерживают серверы заданий.(Сборки Cygwin / MSYS GNU делают.) Приведенный ниже код использует переменную .FEATURES
, введенную в make 3.81, чтобы определить, поддерживаются ли серверы заданий.Признак неиспользования этого обходного пути, когда это необходимо, заключается в том, что ваша «параллельная» сборка будет сериализована.
# Check if job server supported:
ifeq ($(filter jobserver, $(.FEATURES)),)
# Job server not supported: sub-makes will only start one job unless
# you specify a higher number here. Here we use a MS Windows environment
# variable specifying number of processors.
JOBSARG := -j $(NUMBER_OF_PROCESSORS)
else
# Job server is supported; let GNU Make work as normal.
JOBSARG :=
endif
# .FEATURES only works in GNU Make 3.81+.
# If GNU make is older, assume job server support.
ifneq ($(firstword $(sort 3.81 $(MAKE_VERSION))),3.81)
# If you are using GNU Make < 3.81 that does not support job servers, you
# might want to specify -jN parameter here instead.
JOBSARG :=
endif
ifneq ($(words $(MAKECMDGOALS)),1)
.NOTPARALLEL:
# The "all" target is required in the list,
# in case user invokes make with no targets.
$(sort all $(MAKECMDGOALS)):
@$(MAKE) $(JOBSARG) -f $(firstword $(MAKEFILE_LIST)) $@
else
# Put remainder of your makefile here.
endif