This is another trick.
In main 'Makefile' define SRCDIR for each source dir and include 'makef.mk' for each value of SRCDIR. In each source dir put file 'files.mk' with list of source files and compile options for some of them. In main 'Makefile' one can define compile options and exclude files for each value of SRCDIR.
Makefile:
PRG := prog-name
OPTIMIZE := -O2 -fomit-frame-pointer
CFLAGS += -finline-functions-called-once
LDFLAGS += -Wl,--gc-section,--reduce-memory-overheads,--relax
.DEFAULT_GOAL := hex
OBJDIR := obj
MK_DIRS := $(OBJDIR)
SRCDIR := .
include makef.mk
SRCDIR := crc
CFLAGS_crc := -DCRC8_BY_TABLE -DMODBUS_CRC_BY_TABLE
ASFLAGS_crc := -DCRC8_BY_TABLE -DMODBUS_CRC_BY_TABLE
include makef.mk
################################################################
CC := avr-gcc -mmcu=$(MCU_TARGET) -I.
OBJCOPY := avr-objcopy
OBJDUMP := avr-objdump
C_FLAGS := $(CFLAGS) $(REGS) $(OPTIMIZE)
CPP_FLAGS := $(CPPFLAGS) $(REGS) $(OPTIMIZE)
AS_FLAGS := $(ASFLAGS)
LD_FLAGS := $(LDFLAGS) -Wl,-Map,$(OBJDIR)/$(PRG).map
C_OBJS := $(C_SRC:%.c=$(OBJDIR)/%.o)
CPP_OBJS := $(CPP_SRC:%.cpp=$(OBJDIR)/%.o)
AS_OBJS := $(AS_SRC:%.S=$(OBJDIR)/%.o)
C_DEPS := $(C_OBJS:%=%.d)
CPP_DEPS := $(CPP_OBJS:%=%.d)
AS_DEPS := $(AS_OBJS:%=%.d)
OBJS := $(C_OBJS) $(CPP_OBJS) $(AS_OBJS)
DEPS := $(C_DEPS) $(CPP_DEPS) $(AS_DEPS)
hex: $(PRG).hex
lst: $(PRG).lst
$(OBJDIR)/$(PRG).elf : $(OBJS)
$(CC) $(C_FLAGS) $(LD_FLAGS) $^ -o $@
%.lst: $(OBJDIR)/%.elf
-@rm $@ 2> /dev/nul
$(OBJDUMP) -h -s -S $< > $@
%.hex: $(OBJDIR)/%.elf
-@rm $@ 2> /dev/nul
$(OBJCOPY) -j .text -j .data -O ihex $< $@
$(C_OBJS) : $(OBJDIR)/%.o : %.c Makefile
$(CC) -MMD -MF $@.p.d -c $(C_FLAGS) $(C_FLAGS_$(call clear_name,$<)) $< -o $@
@sed -e 's,.*:,SRC_FILES += ,g' < $@.p.d > $@.d
@sed -e "\$$s/$$/ $(subst /,\/,$(dir $<))files.mk\n/" < $@.p.d >> $@.d
@sed -e 's,^[^:]*: *,,' -e 's,^[ \t]*,,' -e 's, \\$$,,' -e 's,$$, :,' < $@.p.d >> $@.d
-@rm -f $@.p.d
$(CPP_OBJS) : $(OBJDIR)/%.o : %.cpp Makefile
$(CC) -MMD -MF $@.p.d -c $(CPP_FLAGS) $(CPP_FLAGS_$(call clear_name,$<)) $< -o $@
@sed -e 's,.*:,SRC_FILES += ,g' < $@.p.d > $@.d
@sed -e "\$$s/$$/ $(subst /,\/,$(dir $<))files.mk\n/" < $@.p.d >> $@.d
@sed -e 's,^[^:]*: *,,' -e 's,^[ \t]*,,' -e 's, \\$$,,' -e 's,$$, :,' < $@.p.d >> $@.d
-@rm -f $@.p.d
$(AS_OBJS) : $(OBJDIR)/%.o : %.S Makefile
$(CC) -MMD -MF $@.p.d -c $(AS_FLAGS) $(AS_FLAGS_$(call clear_name,$<)) $< -o $@
@sed -e 's,.*:,SRC_FILES += ,g' < $@.p.d > $@.d
@sed -e "\$$s/$$/ $(subst /,\/,$(dir $<))files.mk\n/" < $@.p.d >> $@.d
@sed -e 's,^[^:]*: *,,' -e 's,^[ \t]*,,' -e 's, \\$$,,' -e 's,$$, :,' < $@.p.d >> $@.d
-@rm -f $@.p.d
clean:
-@rm -rf $(OBJDIR)/$(PRG).elf
-@rm -rf $(PRG).lst $(OBJDIR)/$(PRG).map
-@rm -rf $(PRG).hex $(PRG).bin $(PRG).srec
-@rm -rf $(PRG)_eeprom.hex $(PRG)_eeprom.bin $(PRG)_eeprom.srec
-@rm -rf $(MK_DIRS:%=%/*.o) $(MK_DIRS:%=%/*.o.d)
-@rm -f tags cscope.out
# -rm -rf $(OBJDIR)/*
# -rm -rf $(OBJDIR)
# -rm $(PRG)
tag: tags
tags: $(SRC_FILES)
if [ -e tags ] ; then ctags -u $? ; else ctags $^ ; fi
cscope -U -b $^
# include dep. files
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEPS)
endif
# Create directory
$(shell mkdir $(MK_DIRS) 2>/dev/null)
makef.mk
SAVE_C_SRC := $(C_SRC)
SAVE_CPP_SRC := $(CPP_SRC)
SAVE_AS_SRC := $(AS_SRC)
C_SRC :=
CPP_SRC :=
AS_SRC :=
include $(SRCDIR)/files.mk
MK_DIRS += $(OBJDIR)/$(SRCDIR)
clear_name = $(subst /,_,$(1))
define rename_var
$(2)_$(call clear_name,$(SRCDIR))_$(call clear_name,$(1)) := \
$($(subst _,,$(2))_$(call clear_name,$(SRCDIR))) $($(call clear_name,$(1)))
$(call clear_name,$(1)) :=
endef
define proc_lang
ORIGIN_SRC_FILES := $($(1)_SRC)
ifneq ($(strip $($(1)_ONLY_FILES)),)
$(1)_SRC := $(filter $($(1)_ONLY_FILES),$($(1)_SRC))
else
ifneq ($(strip $(ONLY_FILES)),)
$(1)_SRC := $(filter $(ONLY_FILES),$($(1)_SRC))
else
$(1)_SRC := $(filter-out $(EXCLUDE_FILES),$($(1)_SRC))
endif
endif
$(1)_ONLY_FILES :=
$(foreach name,$($(1)_SRC),$(eval $(call rename_var,$(name),$(1)_FLAGS)))
$(foreach name,$(ORIGIN_SRC_FILES),$(eval $(call clear_name,$(name)) :=))
endef
$(foreach lang,C CPP AS, $(eval $(call proc_lang,$(lang))))
EXCLUDE_FILES :=
ONLY_FILES :=
SAVE_C_SRC += $(C_SRC:%=$(SRCDIR)/%)
SAVE_CPP_SRC += $(CPP_SRC:%=$(SRCDIR)/%)
SAVE_AS_SRC += $(AS_SRC:%=$(SRCDIR)/%)
C_SRC := $(SAVE_C_SRC)
CPP_SRC := $(SAVE_CPP_SRC)
AS_SRC := $(SAVE_AS_SRC)
./files.mk
C_SRC := main.c
CPP_SRC :=
AS_SRC := timer.S
main.c += -DDEBUG
./crc/files.mk
C_SRC := byte-modbus-crc.c byte-crc8.c
AS_SRC := modbus-crc.S crc8.S modbus-crc-table.S crc8-table.S
byte-modbus-crc.c += --std=gnu99
byte-crc8.c += --std=gnu99