Автоматическое создание предварительных условий
Во многих правилах makefile для программы часто указывается лишь зависимость некоторого объектного файла от некоторого заголовочного файла. Например, если main.c использует defs.h через #include, вы напишите:
main.o: defs.h
Вам нужно это правило, чтобы make знал, что должен пересоздать main.o всякий раз, когда изменяется defs.h. Вы можете видеть, что для большой программы вам придётся писать десятки таких правил в вашем makefile. И вы всегда должны очень внимательно обновлять makefile каждый раз, когда добавляете или удаляете #include.
Чтобы избежать этих хлопот, большинство современных компиляторов C могут написать эти правила за вас, проанализировав #include строки в исходных файлах. Обычно это делается с помощью опции ‘-M’ компилятора. Например, команда:
cc -M main.c
генерирует вывод:
main.o : main.c defs.h
Таким образом, вам больше не нужно писать все эти правила самостоятельно. Компилятор сделает это за вас.
Обратите внимание, что такое правило подразумевает упоминание main.o в makefile, поэтому его нельзя считать промежуточным файлом при поиске по неявным правилам. Это означает, что make никогда не удалит файл после его использования; см. Цепочки неявных правил.
В старых make программах традиционно использовалась эта функция компилятора для генерации предварительных условий по запросу с помощью команды типа ‘make depend’. Эта команда создаст файл depend, содержащий все сгенерированные автоматически предварительные условия; затем makefile сможет использовать include для их чтения (см. Включение).
В GNU make, функция пересоздания makefile делает эту практику устаревшей — вам никогда не нужно указывать make явным образом перегенерировать предварительные условия, потому что он всегда пересоздаёт любой устаревший makefile. См. Пересоздание Makefiles.
Рекомендуемая практика для автоматического создания предварительных условий заключается в наличии одного makefile для каждого исходного файла. Для каждого исходного файла name.c существует makefile name.d, который перечисляет, от каких файлов зависит объектный файл name.o. Таким образом, для получения новых предварительных условий необходимо пересканировать только изменённые исходные файлы.
Вот шаблонное правило для генерации файла предварительных условий (т.е. makefile) с именем name.d из исходного файла C с именем name.c:
%.d: %.c
@set -e; rm -f $@; \
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
См. Шаблонные правила для получения информации о определении шаблонных правил. Флаг ‘-e’ для оболочки заставляет её немедленно завершиться, если команда $(CC) (или любая другая команда) завершается неудачно (выходит со статусом, отличным от нуля).
В GNU C-компиляторе вы можете использовать флаг ‘-MM’ вместо ‘-M’. Это опускает предварительные условия для системных заголовочных файлов. См. Параметры, управляющие препроцессором в Использование GNU CC для получения подробностей.
Цель команды sed состоит в том, чтобы перевести (например):
main.o : main.c defs.h
в:
main.o main.d : main.c defs.h
Это заставляет каждый файл ‘.d’ зависеть от всех исходных и заголовочных файлов, от которых зависит соответствующий файл ‘.o’. make тогда знает, что должен перегенерировать предварительные условия всякий раз, когда изменяется любой из исходных или заголовочных файлов.
После определения правила пересоздания файлов ‘.d’ вы затем используете директиву include для их чтения. См. Включение. Например:
sources = foo.c bar.c include $(sources:.c=.d)
(В этом примере используется ссылка на переменную подстановки для перевода списка исходных файлов ‘foo.c bar.c’ в список makefiles предварительных условий ‘foo.d bar.d’. См. Ссылок на подстановки для получения полной информации о ссылках на подстановки.) Поскольку файлы ‘.d’ — это makefiles, как и любые другие, make пересоздаст их по мере необходимости без дальнейшей вашей работы. См. Пересоздание Makefiles.
Обратите внимание, что файлы ‘.d’ содержат определения целей; вы должны убедиться, что размещаете директиву include после первой, по умолчанию цели в ваших makefiles, или рискуете сделать случайным объектный файл по умолчанию. См. Как работает Make.
Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html