Общие соглашения для Makefiles
Каждый Makefile должен содержать эту строку:
SHELL = /bin/sh
чтобы избежать проблем на системах, где переменная SHELL может быть унаследована из среды. (Это никогда не проблема с GNU make)
У разных программ make несовместимые списки суффиксов и неявные правила, что иногда приводит к путанице или неправильному поведению. Поэтому рекомендуется явно задать список суффиксов, используя только необходимые вам суффиксы в конкретном Makefile, например так:
.SUFFIXES: .SUFFIXES: .c .o
Первая строка очищает список суффиксов, вторая вводит все суффиксы, которые могут быть подвержены неявным правилам в данном Makefile.
Не предполагайте, что . находится в пути для выполнения команд. Когда вам нужно запустить программы, которые являются частью вашего пакета во время make, убедитесь, что используется ./, если программа построена как часть make, или $(srcdir)/, если файл является неизменяемой частью исходного кода. Без одного из этих префиксов используется текущий путь поиска.
Различие между ./ (каталог построения) и $(srcdir)/ (каталог исходного кода) важно, потому что пользователи могут строить в отдельном каталоге, используя опцию «--srcdir» для configure. Правило вида:
foo.1 : foo.man sedscript
sed -f sedscript foo.man > foo.1
будет выполняться с ошибкой, когда каталог построения не совпадает с каталогом исходного кода, так как foo.man и sedscript находятся в каталоге исходного кода.
При использовании GNU make, полагаясь на «VPATH» для поиска исходного файла, будет работать в случае наличия одного файла зависимости, так как автоматическая переменная make «$<» будет представлять исходный файл независимо от его расположения. (Во многих версиях make переменная «$<» задаётся только в неявных правилах.) Цель Makefile, например:
foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
должна быть переписана как
foo.o : bar.c
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
чтобы позволить «VPATH» работать корректно. Когда у цели несколько зависимостей, использование явного «$(srcdir)» является наиболее простым способом сделать правило работоспособным. Например, цель выше для foo.1 лучше переписать так:
foo.1 : foo.man sedscript
sed -f $(srcdir)/sedscript $(srcdir)/foo.man > $@
GNU-дистрибутивы обычно содержат некоторые файлы, которые не являются исходными файлами — например, файлы Info и выходные данные из Autoconf, Automake, Bison или Flex. Поскольку эти файлы обычно находятся в каталоге исходного кода, они всегда должны располагаться в каталоге исходного кода, а не в каталоге построения. Поэтому правила Makefile для их обновления должны сохранять обновленные файлы в каталоге исходного кода.
Однако, если файл не входит в дистрибутив, Makefile не должен помещать его в каталог исходного кода, так как построение программы в обычных условиях не должно каким-либо образом изменять каталог исходного кода.
Старайтесь, чтобы цели построения и установки, по крайней мере (и все их подцели) работали корректно с параллельным 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/Makefile-Basics.html