Зависимости у целей
Для сборки целей нужно выставить зависимости – т.е. прописать от чего зависит цель (файлы .cpp и .h)
Если зависимости проставлены, то может использоваться инкрементальная компиляция (т.е. не происходит повторной компиляции АКТУАЛЬНЫХ данных) что ускоряет сборку.
Актуальность проверяется по времени изменения. Т.е. если исходники старее чем собранный файл – то не производится пересборка.
Например в проекте 200 файлов, внесли изменения в 1, то пересобираться будет этот файл и те, которые от него зависят.
Важное уточнение – если неправильно прописать зависимости
Например если прописать что объектные файлы .o зависят от исходников кода .cpp
то изменения в header файлах будут игнорироваться, т.к. физически НЕ будет перекомпиляции пока не изменятся .cpp файлы или не будут удалены объектные
т.е. в идеале надо писать так:
FileName.o: FileName.cpp FileName.h
[tab] g++ -c -o FileName.o FileName.cpp
Для некоторого упрощения применяются неявные правила.
Неявные правила
Чтобы не прописывать явные зависимости когда file.o зависить от file.cpp и file.h
когда в makefile прописывается правило по типу
TARGET: file1.o file2.o
или просто объектный файл ___.o
то make будет просматривать зависимости по цепочкам неявных правил и неявно дописывать makefile.
т.е. для цели file.o make будет проверять ВСЕ ВОЗМОЖНЫЕ файлы с ИСХОДНЫМ кодом
file.c #для него вызовется $(CC) $(CPPFLAGS) $(CFLAFS) -c
file1.cc #для него вызовется (CXX) $(CPPFLAGS) $(CXXFLAFS) -c
file1.cpp #для него вызовется (CXX) $(CPPFLAGS) $(CXXFLAFS) -c
file1.p
…
Т.е. необходимо дописать только зависимости от header files
file.o : file.h file2.h
Если зависимостей от заголовочных файлов нет – это можно опустить
Плюс НЕЛЬЗЯ иметь файлы с одинаковым именем и разным расширением
Переменная LDFLAGS управяляет параметрами линковки
Примечание 1: Можно перечислять несколько целей в 1 правиле
file1.o file2.o … fileN.o : defines.h
В этом случае используется неявное правило и в добавок файл defines.h
Примечание 2: .PHONY запрещает выполнение неявных правил.