Один из способов, который не зависит от платформы (я имею в виду независимость от оболочки в Windows или Linux), таков:
DIRS = relative/path1\
relative/path2
dd = absolute/path/to/subdirectories
all:
@$(foreach dir, $(DIRS), $(MAKE) -C $(dd)$(dir) build -f ../../Makefile ;)
build:
... build here
обратите внимание, что здесь важны пробелы, а также точка с запятой, также важно указать абсолютные пути, а также указать в конце путь к соответствующему Makefile (в этом случае я использую только один Makefile в папке grandparent)
Но есть и лучший подход, включающий цели PHONY, он лучше отображает ход выполнения и ошибки и останавливает сборку, если в одной папке возникла проблема, вместо перехода к другим целям:
.PHONY: subdirs $(DIRS)
subdirs: $(DIRS)
$(DIRS):
$(MAKE) -C $@ build -f ../../Makefile
all : prepare subdirs
...
build :
... build here
Опять же, здесь я использую только один Makefile, который должен быть применим ко всем подпроектам. Для каждого подпроекта в папке grandchild целевая «сборка» создается с использованием одного Makefile в корне.