Структура исходного кода Geting в Makefile

Я работаю над проектом C, и я решил поместить исходный код и его объекты в разные каталоги. Корневой каталог имеет что-то вроде этого:

SmartC ▶ tree -L 1 . ├── built ├── doc ├── Makefile ├── README.md ├── src ├── tests └── trash 

Итак, внутри обоих src и построенных каталогов я поставил два других Makefile, чтобы выполнить компиляцию и ссылки.

Каталог src (где я помещаю исходный код) имеет следующую структуру:

 src ├── graph.c ├── graph.h ├── list.c ├── list.h ├── main.c ├── Makefile ├── node.c ├── node.h ├── tree.c ├── tree.h └── types ├── complex.c ├── complex.h ├── matrix.c └── matrix.h 

и построенный имеет ту же структуру, но предназначен для хранения всех объектов, созданных компиляцией.

Мой вопрос о моем src / Makefile:

 BINDIR = ../built/src CC = gcc CFLAGS = -g -Wall -O3 OBJECTS = \ $(BINDIR)/main.o \ $(BINDIR)/node.o \ $(BINDIR)/list.o \ $(BINDIR)/graph.o \ $(BINDIR)/tree.o \ $(BINDIR)/types/complex.o \ $(BINDIR)/types/matrix.o \ compile: $(OBJECTS) $(BINDIR)/%.o: %.c $(CC) -c $< -o $@ $(CFLAGS) 

Этот Makefile создает все объекты исходного кода, внутри каталога src и перемещает их в built / src. Но каждый раз, когда я создаю новый файл исходного кода (* .c), я должен поместить имя его объекта в этот файл makefile, чтобы его можно было скомпилировать. Я хотел бы сделать автоматический поиск внутри каталога src и заполнить переменную «OBJECTS» этим поиском.

Кто-нибудь знает, как это сделать? Я имею в виду, автоматический поиск исходного кода внутри определенного каталога?

Я даже принимаю любую другую страtagsю, а не то, что я делаю.

=========== Ответ ===============

Я получил подсказку (в комментариях) о подстановочных знаках. Так я и сделал. Вот решение, которое я нашел.

SRC / Makefile

 BINDIR = ../built/src CC = gcc CFLAGS = -g -Wall -O3 OBJECTS := $(patsubst %.c,$(BINDIR)/%.o,$(wildcard *.c */*.c)) compile: $(OBJECTS) $(BINDIR)/%.o: %.c $(CC) -c $< -o $@ $(CFLAGS) 

EDIT [Разрешено]

Мне нравится делать следующее.

Создание переменных для каждой директории проекта

 SRCDIR = src OBJDIR = obj LIBDIR = lib DOCDIR = doc HDRDIR = include CFLAGS = -g -Wall -O3 

Получить только внутреннюю структуру SRCDIR рекурсивно

 STRUCTURE := $(shell find $(SRCDIR) -type d) 

Получить все файлы внутри СТРУКТУРЫ Переменная

 CODEFILES := $(addsuffix /*,$(STRUCTURE)) CODEFILES := $(wildcard $(CODEFILES)) 

Отфильтровать только определенные файлы

 # Filter Only Specific Files SRCFILES := $(filter %.c,$(CODEFILES)) HDRFILES := $(filter %.h,$(CODEFILES)) OBJFILES := $(subst $(SRCDIR),$(OBJDIR),$(SRCFILES:%.c=%.o)) # Filter Out Function main for Libraries LIBDEPS := $(filter-out $(OBJDIR)/main.o,$(OBJFILES)) 

Теперь пришло время создать Правила

 compile: $(OBJFILES) $(OBJDIR)/%.o: $(addprefix $(SRCDIR)/,%.c %.h) $(CC) -c $< -o $@ $(CFLAGS) 

При таком подходе вы можете увидеть, что я использую переменную STRUCTURE только для того, чтобы получить файлы внутри каталога SRCDIR, но ее можно использовать и для других целей, например, зеркально отобразить SRCDIR внутри OBJDIR, когда STRUCTURE хранит только внутренние подкаталоги, каталоги. Это очень полезно после чистых операций, таких как:

 clean: -rm -r $(OBJDIR)/* 

ПРИМЕЧАНИЕ. Правило компиляции работает хорошо, если для каждого * .c есть соответствующий * .h файл (с тем же базовым именем, я имею в виду).