Может ли кто-нибудь объяснить этот файл?

Я нашел этот make файл на этом сайте. Они не объясняют этот пример, поэтому мне было интересно, кто-нибудь новый, что происходит.

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected]

.cpp.o:
    $(CC) $(CFLAGS) $< -o [email protected]

Ответы

Ответ 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 файлов (которые, возможно, только что изменились, возможно, совсем новые), он запустит эту команду, чтобы повторно связать его. Наконец, он будет запускать пустую команду (ничего не делать), чтобы "перестроить" все.