CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
устанавливает четыре переменные в качестве постоянных строк.Для остальной части make-файла, где бы ни появлялось (например, $(CC)
), он будет заменен на g++
OBJECTS=$(SOURCES:.cpp=.o)
, который устанавливает переменную OBJECTS такой же, как SOURCES, за исключением случаев, когда шаблон .cpp
появляется в словах SOURCES, его заменяют на .o
EXECUTABLE=hello
устанавливает другую постоянную строку var
all: $(SOURCES) $(EXECUTABLE)
Первое действительное правило в make-файле. Это говорит make, чточтобы построить all
, он должен сначала собрать все в $(SOURCES)
и $(EXECUTABLE)
, а затем ничего не делать.Поскольку это первое, оно становится целью по умолчанию, поэтому запуск make
эквивалентен make all
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
Другое правило: чтобы создать $(EXECUTABLE)
(который расширяется до hello
), он должен сначаласоберите все в $(OBJECTS)
(эквивалентно main.o hello.o factorial.o
) и затем выполните команду $(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) -o $@ $<
Шаблонное правило: для создания файла, заканчивающегося на .o
, сначала пересоберите / создайте/ найдите соответствующий файл, оканчивающийся на .cpp, а затем выполните команду $(CC) $(CFLAGS) -o $@ $<
.
Эти последние два правила содержат специальные переменные $@
и $<
, которые действительны только в действиях правила, и расширяются доцель и первая зависимость соответственно
Поэтому, когда вы запускаете make
, он читает все это и затем пытается построить цель по умолчанию (все).Поскольку он не существует, он пытается собрать файлы main.cpp, hello.cpp, factorial.cpp и hello.Поскольку первые 3 (предположительно) существуют, он ищет для них правила / зависимости, но не находит их, поэтому решает, что им нечего делать.Если бы они не существовали, make выдаст сообщение об ошибке: «нет правила для создания цели 'main.cpp'"
В случае "hello" это зависит от main.o, hello.o и factorial.о, так это выглядит в них.Для main.o шаблонное правило говорит, что оно зависит от main.cpp, поэтому, если main.o не существует или если main.cpp новее, он запускает команду g++ -c -Wall -o main.o main.cpp
.То же самое происходит для hello.o и factorial.o.
После того, как это сделано, если hello
не существует или старше любого из этих файлов .o (которые, возможно, только что изменились, поэтомувозможно, довольно новый), он запустит эту команду, чтобы связать ее.Наконец, он выполнит пустую команду (ничего не делая), чтобы «перестроить» все.