josef.van.niekerk
josef.van.niekerk

Reputation: 12121

Combining makefile targets into a more reusable target

My Makefile has the following macros defined:

# Output location
OUT_DIR = Build

# Source location
SOURCE_DIR = Src

# Complete list of source files to be compiled
SOURCES  = $(SOURCE_DIR)/main.c
SOURCES += $(SOURCE_DIR)/startup.s
SOURCES += System/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c

# Separate out .c and .s source files
C_SOURCES = $(filter %.c, $(SOURCES))
ASM_SOURCES = $(filter %.s, $(SOURCES))

# Rename .c to .o, and replace the path with $(OUT_DIR)/
# For example Src/main.c becomes Build/main.o
OBJECTS  = $(addprefix $(OUT_DIR)/, $(notdir $(C_SOURCES:.c=.o)))
OBJECTS += $(addprefix $(OUT_DIR)/, $(notdir $(ASM_SOURCES:.s=.o)))

...and I have the following target that's bugging me a bit:

$(OUT_DIR)/%.o : $(SOURCE_DIR)/%.c
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $(OUT_DIR)/$(notdir $@)
    @echo

$(OUT_DIR)/%.o : System/CMSIS/Device/ST/STM32F4xx/Source/Templates/%.c
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $(OUT_DIR)/$(notdir $@)
    @echo

Is there a way I can have the target defined one, without having to specify the path? Seems like too much repetition...

The targets both work fine, but I just feel that it's unnecessary to repeat targets like this.

Upvotes: 3

Views: 1243

Answers (1)

Etan Reisner
Etan Reisner

Reputation: 81022

You can use a Canned Recipe which contains the body of the recipe and use that in each rule but you can't combine rules that have such wildly different prerequisite patterns.

define JVN_COMPILE
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $(OUT_DIR)/$(notdir $@)
    @echo
endef

$(OUT_DIR)/%.o : $(SOURCE_DIR)/%.c
    $(JVN_COMPILE)

$(OUT_DIR)/%.o : System/CMSIS/Device/ST/STM32F4xx/Source/Templates/%.c
    $(JVN_COMPILE)

or, set VPATH and do the following:

VPATH = Src:System/CMSIS/Device/ST/STM32F4xx/Source/Templates

define JVN_COMPILE
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) $< -o $(OUT_DIR)/$(notdir $@)
    @echo
endef

$(OUT_DIR)/%.o : %.c
    $(JVN_COMPILE)

Upvotes: 2

Related Questions