Ответ 1
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
устанавливает четыре переменные как постоянные строки. Для остальной части make файла, где бы не появлялся $(CC)
, он будет заменен на g++
OBJECTS=$(SOURCES:.cpp=.o)
устанавливает переменные OBJECTS такими же, как ИСТОЧНИКИ, за исключением тех случаев, когда шаблон .cpp
появляется словами SOURCES, его заменяет на .o
EXECUTABLE=hello
устанавливает другую константу string var
all: $(SOURCES) $(EXECUTABLE)
Первое фактическое правило в make файле. Это говорит о том, что для сборки all
он должен сначала построить все в $(SOURCES)
и $(EXECUTABLE)
, а затем ничего не делать. Поскольку это первый, он становится целевой по умолчанию, поэтому запуск make
эквивалентен make all
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o [email protected]
Другое правило: для создания $(EXECUTABLE)
(который расширяется до hello
) он должен сначала построить все в $(OBJECTS)
(эквивалентно main.o hello.o factorial.o
), а затем запустить команду $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected]
.cpp.o:
$(CC) $(CFLAGS) -o [email protected] $<
Правило шаблона: чтобы построить файл, заканчивающийся на .o
, сначала перестройте/создайте/найдите соответствующий файл, заканчивающийся на .cpp, а затем запустите команду $(CC) $(CFLAGS) -o [email protected] $<
.
Эти два последних правила содержат специальные переменные [email protected]
и $<
, которые действительны только в действиях правила и расширяются до целевой и первой зависимости соответственно
Поэтому, когда вы запускаете make
, он считывает все это, а затем пытается создать цель по умолчанию (все).
Поскольку он не существует, он пытается создать файлы main.cpp, hello.cpp, factorial.cpp и hello. Поскольку первые 3 (предположительно) существуют, он ищет для них правила/зависимости, но не находит их, поэтому решает, что им нечего делать. Если бы они не существовали, make сделал бы ошибку, говоря "no rule to make target" main.cpp '"
В случае "привет" это зависит от main.o, hello.o и factorial.o, поэтому он смотрит на них. Для main.o правило шаблона говорит, что оно зависит от main.cpp, поэтому, если main.o не существует или если main.cpp новее, он выполнит команду g++ -c -Wall -o main.o main.cpp
. То же самое происходит и с hello.o и factorial.o.
Как только это будет сделано, если hello
не существует или старше любого из этих .o файлов (которые, возможно, только что изменились, возможно, совсем новые), он запустит эту команду, чтобы повторно связать его. Наконец, он будет запускать пустую команду (ничего не делать), чтобы "перестроить" все.