Самый простой способ сделать то, что вы хотите, это, вероятно, просто использовать escape-команду и вызвать find
:
SOURCES := $(shell find $(SOURCEDIR) -name '*.c')
Это дает вам список исходных файлов с путями. Обратите внимание, что здесь важно использовать немедленное присвоение :=
, а не рекурсивное присвоение =
: вы не хотите запускать экранирование оболочки каждый раз, когда SOURCES
проверяется командой make (что происходит намного больше, чем вы думаете в Makefiles). Общее правило, которое я считаю полезным, заключается в том, чтобы всегда использовал немедленное назначение, если только мне не нужно рекурсивное расширение (что редко; похоже, что все ваши назначения в этом примере могут быть немедленными). Это означает, что использование рекурсивного присваивания также является полезным сигналом о том, что переменную необходимо использовать осторожно.
Вернемся к вашей проблеме. То, что вы будете делать дальше, зависит от того, хотите ли вы в своем дереве компоновки создать зеркало своего исходного кода, или же каталог сборки должен содержать плоский список объектных файлов для всех ваших исходных файлов, или же вы хотите отдельный каталог сборки. под каждым источником dir на дереве.
Предполагая, что вам нужно зеркальное дерево сборки, вы можете сделать что-то вроде следующего:
# Get list of object files, with paths
OBJECTS := $(addprefix $(BUILDDIR)/,$(SOURCES:%.c=%.o))
$(BINARY): $(OBJECTS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $(BINARY)
$(BUILDDIR)/%.o: %.c
$(CC) $(CFLAGS) $(LDFLAGS) -I$(HEADERDIR) -I$(dir $<) -c $< -o $@
Это не совсем учитывает всю сложность работы, так как не гарантирует, что каталоги в дереве сборки действительно существуют (что было бы умеренно болезненно делать в синтаксисе Makefile).
Я удалил директивы -I из вашего правила сборки $ (BINARY); они вам действительно нужны при связывании объектов? Причина, по которой я их не оставил, заключается в том, что у вас больше нет только одного исходного каталога, и нетривиально получить список исходных каталогов из списка объектов (как в синтаксисе Makefile, это было бы выполнимо, но очень раздражает).