Предупреждение принудительно в submake при параллельном выполнении make

Когда я запускаю make -j3 для параллельной сборки, я получаю

warning: -jN forced in submake: disabling jobserver mode.

В документации я обнаружил, что выдается предупреждение

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

Что это за условия ошибки? Что я могу сделать, чтобы вылечить их или подавить сообщение об ошибке?

Makefile генерируется из CMake, поэтому я не могу (= не хочу) редактировать makefile.


person usr1234567    schedule 18.07.2014    source источник
comment
Как вы запускаете дочерний Makefile в вашем CMakeLists.txt?   -  person anton_rh    schedule 18.03.2020
comment
Я думаю, что только CMake вызывает make и submake. Но после вашего вопроса я уже не уверен на 100%.   -  person usr1234567    schedule 18.03.2020


Ответы (4)


Обычно это сообщение появляется, если вы вызываете make из вашего Makefile не по переменной $(MAKE)

Пример:

Сдача

foo:
     cd foo/ && make foo

to

foo:
     cd foo && $(MAKE) foo
person arved    schedule 18.07.2014
comment
Я не писал make-файл сам, он автоматически генерируется CMake. - person usr1234567; 06.07.2015
comment
cmake обычно делает это правильно, возможно, вы вызываете make из CMakeLists.txt - person arved; 06.07.2015
comment
Что ж, в моем случае я именно так и называю подделку. У меня есть функция sub_make = $(MAKE) -C $(TOPDIR)/subdir/$(1) $(2), а затем я делаю, например. $(call subproject,all). Так что это $(MAKE), как вы говорите. И все же я получаю предупреждение. - person Hi-Angel; 15.09.2020
comment
Хорошо, я понял причину. Оказывается, по какой-то причине вызов $(MAKE) не будет работать должным образом, если вы вызываете его из функции Make. В таких случаях функция должна иметь @+ символов после знака равенства. Итак, учитывая мой предыдущий пример, чтобы заставить его работать, мне нужно объявить его как sub_make = @+$(MAKE) -C $(TOPDIR)/subdir/$(1) $(2) - person Hi-Angel; 16.09.2020

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

Это можно исправить параметром -j.

make -j 1

Приведенный выше код позволит избежать нескольких потоков и удалит предупреждения.

Опять же, мы можем использовать параметр -j в make-файле.

target:
    $(MAKE) -j 1 -C ${SUBDIR} $@

Приведенное выше правило не будет создавать темы для submake и позволит избежать предупреждения.

person shuva    schedule 12.05.2017
comment
Спасибо, что поделились этими знаниями. Но с CMake генерирует Makefiles, и я не могу их контролировать. Поскольку это, по-видимому, исправлено в вышестоящем CMake и/или GNU make, я в порядке с этой темой. - person usr1234567; 13.05.2017

Вы вызываете make -j3 для своего Makefile верхнего уровня, что означает, что одновременно может быть построено до 3 целей (make использует для сборки 3 потока). Ваш Makefile верхнего уровня (сгенерированный CMake) запускает другой make (который называется sub-make). И в этом вызове используется еще одна опция -jN. Таким образом, вместо того, чтобы использовать общий сервер заданий для обоих make, sub-make использует другие N потоков для создания своих целей. Таким образом, для построения используется до 3 + N потоков. Так вот о чем это предупреждение.

Чтобы включить общий сервер заданий для родительского make и подчиненного make, необходимо выполнить 2 требования:

  • Явная опция -jN не должна передаваться в sub-make. Вызовите sub-make без этого аргумента.
  • Sub-make должен вызываться с использованием выражения $(MAKE) (а не просто make). В качестве альтернативы можно добавить префикс + перед командой make. Подробности см. в этом ответе.

Если оба требования выполнены, то при запуске make -jN для файла Makefile верхнего уровня родительский make и дочерний make используют для сборки N общих потоков.

person anton_rh    schedule 18.03.2020

С более новыми версиями GNU make (4.0) и CMake (2.8.6 и 3.3) я больше не могу воспроизводить предупреждение. Тем временем один из них был исправлен.

person usr1234567    schedule 16.11.2015