Este es otro truco.
En main 'Makefile', defina SRCDIR para cada directorio de origen e incluya 'makef.mk' para cada valor de SRCDIR. En cada directorio de origen, coloque el archivo 'files.mk' con una lista de archivos de origen y opciones de compilación para algunos de ellos. En el principal 'Makefile' uno puede definir opciones de compilación y excluir archivos para cada valor de 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 [email protected]
%.lst: $(OBJDIR)/%.elf
[email protected] [email protected] 2> /dev/nul
$(OBJDUMP) -h -s -S $< > [email protected]
%.hex: $(OBJDIR)/%.elf
[email protected] [email protected] 2> /dev/nul
$(OBJCOPY) -j .text -j .data -O ihex $< [email protected]
$(C_OBJS) : $(OBJDIR)/%.o : %.c Makefile
$(CC) -MMD -MF [email protected] -c $(C_FLAGS) $(C_FLAGS_$(call clear_name,$<)) $< -o [email protected]
@sed -e 's,.*:,SRC_FILES += ,g' < [email protected] > [email protected]
@sed -e "\$$s/$$/ $(subst /,\/,$(dir $<))files.mk\n/" < [email protected] >> [email protected]
@sed -e 's,^[^:]*: *,,' -e 's,^[ \t]*,,' -e 's, \\$$,,' -e 's,$$, :,' < [email protected] >> [email protected]
[email protected] -f [email protected]
$(CPP_OBJS) : $(OBJDIR)/%.o : %.cpp Makefile
$(CC) -MMD -MF [email protected] -c $(CPP_FLAGS) $(CPP_FLAGS_$(call clear_name,$<)) $< -o [email protected]
@sed -e 's,.*:,SRC_FILES += ,g' < [email protected] > [email protected]
@sed -e "\$$s/$$/ $(subst /,\/,$(dir $<))files.mk\n/" < [email protected] >> [email protected]
@sed -e 's,^[^:]*: *,,' -e 's,^[ \t]*,,' -e 's, \\$$,,' -e 's,$$, :,' < [email protected] >> [email protected]
[email protected] -f [email protected]
$(AS_OBJS) : $(OBJDIR)/%.o : %.S Makefile
$(CC) -MMD -MF [email protected] -c $(AS_FLAGS) $(AS_FLAGS_$(call clear_name,$<)) $< -o [email protected]
@sed -e 's,.*:,SRC_FILES += ,g' < [email protected] > [email protected]
@sed -e "\$$s/$$/ $(subst /,\/,$(dir $<))files.mk\n/" < [email protected] >> [email protected]
@sed -e 's,^[^:]*: *,,' -e 's,^[ \t]*,,' -e 's, \\$$,,' -e 's,$$, :,' < [email protected] >> [email protected]
[email protected] -f [email protected]
clean:
[email protected] -rf $(OBJDIR)/$(PRG).elf
[email protected] -rf $(PRG).lst $(OBJDIR)/$(PRG).map
[email protected] -rf $(PRG).hex $(PRG).bin $(PRG).srec
[email protected] -rf $(PRG)_eeprom.hex $(PRG)_eeprom.bin $(PRG)_eeprom.srec
[email protected] -rf $(MK_DIRS:%=%/*.o) $(MK_DIRS:%=%/*.o.d)
[email protected] -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
'VPATH' no le permite tener diferentes archivos de origen con el mismo nombre en directorios diferentes, lo que en primer lugar frustra el propósito de los directorios. –
Eh, no, no creo que lo haga. Organizar su código fuente en diferentes directorios tiene más beneficios que permitir múltiples archivos fuente con el mismo nombre. – JesperE
He intentado seguir su solución y he creado objetivos de la forma '.build/cwrapper /%. O:% .c% .cpp'. Sin embargo, cuando los uso como dependencia, p. Ej. 'cwrapper: .build/cwrapper /%. o',' make' se queja: "No hay regla para hacer objetivo' .build/cwrapper /%. o '". ¿Qué estoy haciendo mal? – Raphael