У вас есть как минимум две основные проблемы.
Первая - неправильные назначения переменных SOURCES
и OBJS
. Make выполняет прямую текстовую замену, когда расширяет переменные. Итак:
MODULES := foo bar biz
SOURCES := src/$(MODULES).c
OBJS := bin/$(MODULES).o
расширяется до просто:
SOURCES := src/foo bar biz.c
OBJS := bin/foo bar biz.o
, что явно не правильно. Если вы хотите использовать GNU make-speci c функции, которые работают индивидуально для каждого word в переменной, вы можете получить то, что вы хотите:
SOURCES := $(patsubst %,src/%.c,$(MODULES))
OBJS := $(patubst %,bin/%.o,$(MODULES))
Следующая проблема у вас есть это:
$(OBJS): $(SOURCES)
$(CXX) $(CXXFLAGS) -c $^ -o $@
, который расширяется до чего-то вроде этого:
bin/foo.o bin/bar.o bin/biz.o : src/foo.c src/bar.c src/biz.c
$(CXX) $(CXXFLAGS) -c $^ -o $@
Опять же, make не собирается каким-то образом делать вывод, что вы хотите, чтобы каждый объектный файл слева каким-то образом быть сопоставленным с некоторым исходным файлом справа, используя строку соответствия heuristi c. Это не так, как работает make. Если на левой стороне есть несколько целей, make создает отдельное правило для каждой, где каждая содержит все необходимые условия на правой стороне. Таким образом, вышеприведенный код такой же, как если бы вы написали:
bin/foo.o : src/foo.c src/bar.c src/biz.c
$(CXX) $(CXXFLAGS) -c $^ -o $@
bin/bar.o : src/foo.c src/bar.c src/biz.c
$(CXX) $(CXXFLAGS) -c $^ -o $@
bin/biz.o : src/foo.c src/bar.c src/biz.c
$(CXX) $(CXXFLAGS) -c $^ -o $@
, что означает, что он скомпилирует все исходные файлы для создания каждого объектного файла.
В make-файлах вы должны написать правило, которое строит одну цель за раз, исходя из предпосылок этой цели. Например, вы можете использовать шаблонное правило:
bin/%.o : src/%.c
$(CXX) $(CXXFLAGS) -c $< -o $@
Примечание. Я использовал $<
вместо $^
, потому что вы хотите только скомпилировать исходный файл. Обратите внимание, что это вызывает компилятор один раз для каждого исходного файла, чтобы сгенерировать этот выходной файл. Make не подходит для сред, в которых один вызов инструмента сборки генерирует много разных выходных данных (хотя, если вы хотите ограничиться GNU make версии 4.3 или выше, вы можете сделать это, если хотите).
Это не перестроит никакие объектные файлы, если заголовки изменятся, потому что вы не указали никаких заголовков в качестве предварительных условий.
Вы упомянули получение проблемы с моими включаемыми файлами на этапе компиляции , но это не полезная информация для нас. Если после исправления вашего make-файла у вас все еще остаются проблемы с компиляцией, вы можете открыть новый вопрос, но, пожалуйста, укажите точно (вырезайте и вставляйте) виды ошибок, которые вы видите, а также строку компиляции, которая печатает, что генерирует эти ошибки.