Это можно сделать в GNUMake, я не знаю о других разновидностях.
Сначала мы определим макрос:
SOURCES = $(shell find $(1) -name "*.cpp" -type "f")
Затем мы можем вызвать его для каждого проекта:
PROJECT1_CPP := $(call SOURCES,$(PROJECT1))
PROJECT2_CPP := $(call SOURCES,$(PROJECT2))
PROJECT3_CPP := $(call SOURCES,$(PROJECT3))
Или если их много (или мы ленивы):
PROJECTS := PROJECT1 PROJECT2 PROJECT3
$(foreach proj,$(PROJECTS),$(eval $(proj)_CPP := $(call SOURCES,$($(proj)))))
Или если мы действительно ленивы:
$(foreach proj,1 2 3,$(eval PROJECT$(proj)_CPP := $(call SOURCES,$(PROJECT$(proj)))))
Теперь, чтобы построить их, вместо этого:
project1.lib: $(PROJECT1_OBJS)
do something with $(PROJECT1_OBJS)
project2.lib: $(PROJECT2_OBJS)
do something with $(PROJECT2_OBJS)
project3.lib: $(PROJECT3_OBJS)
do something with $(PROJECT3_OBJS)
мы изменим на это:
project1.lib: $(PROJECT1_OBJS)
do something with $^
project2.lib: $(PROJECT2_OBJS)
do something with $^
project3.lib: $(PROJECT3_OBJS)
do something with $^
А затем на это:
project1.lib: $(PROJECT1_OBJS)
project2.lib: $(PROJECT2_OBJS)
project3.lib: $(PROJECT3_OBJS)
project1.lib project2.lib project3.lib
do something with $^
Мы могли бы даже превратить это в другое $(foreach ... $(eval...))
, но давайте не будем за борт.
РЕДАКТИРОВАТЬ:
Вы хотите за борт?За вами идут:
PROJECT1 := /path/to/first
PROJECT2 := /path/to/second
PROJECT3 := /path/to/third
all:
@echo linking $^ somehow
define all_rules
PROJECT$(1)_CPP := $(shell find $(PROJECT$(1)) -name "*.cpp" -type "f")
project$(1).lib: $(PROJECT$(1)_CPP:.cpp=.o)
@echo making $$@ from $$^
all: project$(1).lib
endef
$(foreach proj,1 2 3,$(eval $(call all_rules,$(proj))))
%.o: %.cpp
@echo making $@ from $<