Есть несколько проблем с этим make-файлом. По сути, у вас есть правила, целью которых не являются файлы, которые они на самом деле производят, и правило, предварительными условиями которого не являются файлы, которые ему действительно нужны.
Предположим, вы изменили Src/main.c
и попытаетесь восстановить Output/Program.elf
, используя это правило:
%elf: $(OBJECTS)
$(CC) $(LDFLAGS) $(OFILES) -o $@
Предварительные условия ($(OBJECTS)
) на самом деле Src/main.o Src/App/Source/EOL.o
и так далее. Эти файлы не существуют - они никогда не существуют - но для них есть правило:
.c.o:
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $(OBJDIR)/$(notdir $@)
Make видит, что Src/main.o
зависит от Src/main.c
и поэтому должен быть восстановлен, как и Output/Program.elf
. Таким образом, он вызывает это правило - которое фактически строит Output/main.o
. Но правило эльфов требует всех (мнимых) объектных файлов, поэтому все источники должны быть перекомпилированы - в объектные файлы, которые уже существуют и не устарели, но которые Make не платил внимание к.
Первое, что нужно сделать, это исправить правила объекта, но есть проблема: хотя правила имеют недостатки, они имеют преимущество в том, чтобы помочь Make найти соответствующие исходные файлы (перед их неправильным использованием), например:
Src/App/Source/EOL.o: Src/App/Source/EOL.c
...
Как мы можем сказать Make, где найти исходный файл, соответствующий Output/EOL.o
? Есть несколько способов, но хороший способ - использовать vpath :
vpath %.c Src/App/Source
Output/EOL.o: EOL.c
...
Все, что нам нужно сделать, это создать список исходных каталогов, передать его в vpath и изменить правило шаблона:
SRCDIRS := $(dir $(SOURCES))
vpath %.c $(SRCDIRS)
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $@
(Правило .S.o
можно исправить таким же образом.)
Затем измените правило elf
, чтобы назвать и использовать его реальные предпосылки:
%elf: $(OFILES)
$(CC) $(LDFLAGS) $^ -o $@