Вот очень простой пример с одним файлом src/main.cpp
, скомпилированным в объектный файл в obj/main.o
:
OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
build: $(OBJS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
gcc -c $< -o $@
Как и в вашем make-файле, вы указываете каталоги obj и src. Затем вы указываете объектный файл (файлы), который хотите создать, в переменной OBJS
.
Но тогда вам нужна цель для вызова make. Make использует первую цель, с которой сталкивается, если вы не передаете параметр. Поэтому здесь я добавил build:
, который зависит от OBJS
. Поэтому, когда я запускаю make
, он запускает цель build
, а затем пытается построить каждый из элементов в OBJS
.
Наконец, нам нужно шаблонное правило, которое говорит:
Такие вещи выглядят как obj/%.o
(% - это подстановочный знак), они зависят от исходного файла src/%.cpp
(замените .cpp на .c или .cxx или что-то еще). В теле правила мы добавляем нашу линию make.
gcc -c $< -o $@
где $ <- зависимость (исходный файл), а $ @ - цель (объектный файл). </p>
Примечание: Я не указываю список источников (SRCS), потому что они подразумеваются сопоставлением с шаблоном объекта. То есть если я хочу создать файл obj/test.o
, то это зависит от существующего файла src/test.cpp
- на основе введенного мной здесь шаблона-правила. Поэтому я могу изменить свой make-файл, добавив больше исходных файлов, выполнив:
OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
OBJS += $(OBJDIR)/fred.o
OBJS += $(OBJDIR)/bob.o
$(info objs: $(OBJS))
build: $(OBJS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
gcc -c $< -o $@
Выход из режима работы make
:
$ make
objs: obj/main.o obj/fred.o obj/bob.o
gcc -c src/main.cpp -o obj/main.o
gcc -c src/fred.cpp -o obj/fred.o
gcc -c src/bob.cpp -o obj/bob.o
Примечание: Я добавил строку $(info objs: $(OBJS))
, чтобы распечатать значение OBJS
UPDATE
Это просто простая версия, как иметь более одной исходной папки - но вы захотите продолжать улучшать ее, так как она довольно проста
OBJ_DIR = obj
SOURCES = src1/bob.cpp
SOURCES += src2/fred.cpp
SOURCES += src3/main.cpp
OUT_DIRS = $(sort $(dir $(SOURCES)))
# Calculate the objects files - should be:
# obj/src1/bob.o
# obj/src2/fred.o
# obj/src3/main.o
OBJS = $(addprefix $(OBJ_DIR)/,$(addsuffix .0,$(basename $(pathsubst %,%,$(SOURCES)))))
$(info objs: $(OBJS))
build: $(OBJS)
# Now this rule also requres the object sub-dirs to be created first
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OUT_DIRS)
gcc -c $< -o $@
# Rule to create the object dir folders
$(OUT_DIRS):
mkdir -p $@
примечание: Я не тестировал этот - но я объяснил, как должен формироваться список OBJS - он "должен" работать. Так что здесь мы все еще используем то же правило шаблона, но теперь мы включаем исходные подпапки в пути к объектам, чтобы шаблон все равно совпадал. Вы получите структуру каталогов внутри obj/
, как описано в комментарии.
Вы можете увидеть, добавив немного, если «интеллект» в make-файл станет более сложным, но теперь вы можете добавлять исходные файлы в любое количество подпапок или подпапок и т. Д. ...