Makefile: зачем всегда использовать `$(MAKE)` вместо `make`?

Я обычно использую систему сборки высокого уровня, такую ​​как cmake, для создания своего кода C/C++. Но по различным причинам я использую только GNU make.

Я делаю рекурсивную сборку, в которой каждый каталог имеет make-файл.

Недавно мне пришлось изменить все мои make-файлы с использования make на $(MAKE), после чего начали работать параллельные сборки.

Во всей литературе, которую я читал, говорится: «Всегда используйте $(MAKE)» (книга О'Рейли, более 5 решений на stackoverflow.com от людей, набравших более 10-40 тысяч баллов).

Почему в make-файлах всегда используется $(MAKE) вместо make?

(очевидно, ОДНА причина в том, что $(MAKE) каким-то образом позволяет выполнять параллельные сборки.)

Происходит ли что-то большее, чем простая замена $(MAKE) на make?


person Trevor Boyd Smith    schedule 24.05.2018    source источник


Ответы (2)


Ответ Матье правильный, но не полный.

Лучше всего прочитать раздел руководства GNU make связанные с использованием переменной MAKE.

В дополнение к использованию правильного исполняемого файла make (что является достаточной причиной), GNU пытается понять, какие рецепты вызывают рекурсивные экземпляры make. Любой рецепт, который делает это, обрабатывается особым образом несколькими способами:

Во-первых, этот рецепт вызывается, даже если вы запускаете make -n, make -q или make -t.

Во-вторых, для связи со своими подделками (например, чтобы позволить серверу заданий работать правильно) make поддерживает набор дескрипторов открытых файлов (для каналов). Для «обычных» (нерекурсивных) рецептов make закроет эти файловые дескрипторы перед созданием рецепта (так что (а) рецепты не могут случайно испортить эту коммуникацию, и (б) потому что некоторые программы/скрипты написаны, чтобы ожидать определенных файловые дескрипторы не используются). Для рецептов, которые определены как рекурсивные вызовы, make не будет закрывать эти файловые дескрипторы.

GNU make использует два разных способа определить, является ли рецепт рекурсивным make или нет. Один из них заключается в том, что вы можете добавить специальный символ + в начало рецепта. Второй — наличие в рецепте ссылок на переменные $(MAKE) (или ${MAKE}).

person MadScientist    schedule 24.05.2018

В некоторых системах исполняемый файл, вызывающий make, не называется make. Например, в системах, отличных от GNU, часто есть команда make, которая не является GNU Make, и пользователям приходится запускать gmake, если они хотят использовать файлы Makefile, разработанные для GNU Make. Если вы делаете рекурсивные вызовы как make в этих системах, рекурсивные вызовы не будут вызывать тот же исполняемый файл, что и файл верхнего уровня, введенный пользователем. Использование $(MAKE) гарантирует, что рекурсивные вызовы будут использовать тот же «make», что и верхний уровень.

person Matthieu Moy    schedule 24.05.2018