make make只重新编译未更改的源文件

时间:2015-11-03 06:53:46

标签: makefile

我正在尝试让我的Makefile只编译已更改的源文件。在下面的Makefile中,如果源文件已更改,或者相应的.o对象文件不存在,我希望目标:%.o : ${SOURCE_DIR}/%.c%.o : ${SOURCE_DIR}/%.s编译。

不完全确定这里有什么问题,有人可以提供一些建议吗?

# Project name
# ---------------------------------------------------------------------------------------------------------------------

PROJECT_NAME = stm32f4_template

# Source configuration
# ---------------------------------------------------------------------------------------------------------------------

OUT_DIR = ./Build
SOURCE_DIR = ./Src

SOURCES  = main.c
SOURCES += startup.s

C_SOURCES  = $(filter %.c, $(SOURCES))
ASM_SOURCES +=  $(filter %.s, $(SOURCES))

OBJECTS  = $(C_SOURCES:.c=.o)
OBJECTS += $(ASM_SOURCES:.s=.o)

# Tools 
# ---------------------------------------------------------------------------------------------------------------------

CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld -v
CP = arm-none-eabi-objcopy
OD = arm-none-eabi-objdump

# Compilation, linker and other tool flags
# ---------------------------------------------------------------------------------------------------------------------

CFLAGS  =  -I./ -c -fno-common -O0 -g -mcpu=cortex-m4 -mthumb
LFLAGS  = -nostartfiles -TLinker/memory.ld -TLinker/sections.ld
CPFLAGS = -Obinary
ODFLAGS = -S

# Target: all ---------------------------------------------------------------------------------------------------------
#
all: setup $(PROJECT_NAME).elf
    @echo "Done! $?"

# Target: setup -------------------------------------------------------------------------------------------------------
#
setup:
    @mkdir -p $(OUT_DIR)

# Target: $(PROJECT_NAME).elf 
# ---------------------------------------------------------------------------------------------------------------------

$(PROJECT_NAME).elf: $(OBJECTS)
    @echo "Linking $@"
    $(LD) $(LFLAGS) -o ${OUT_DIR}/main.elf $(OUT_DIR)/main.o
    @echo

# Target %.o (.c sources)
# ---------------------------------------------------------------------------------------------------------------------
%.o : ${SOURCE_DIR}/%.c # --> Execute only if source changed!!!
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $< -o $(OUT_DIR)/$@
    @echo

# Target %.o (.s sources)
# ---------------------------------------------------------------------------------------------------------------------
%.o : ${SOURCE_DIR}/%.s # --> Execute only if source changed!!!
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $< -o $(OUT_DIR)/$@
    @echo

# Target: clean
# --------------------------------------------------------------------------------------------------------------------- 
clean:
    @echo "Cleaning build output..."
    @rm -rf $(OUT_DIR)

1 个答案:

答案 0 :(得分:2)

这条规则:

%.o : ${SOURCE_DIR}/%.c # --> Execute only if source changed!!!
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $< -o $(OUT_DIR)/$@

问题在于此规则的目标是main.o,因此Make使用它来构建main.o,因为另一个目标要求 main.o ,但这条规则实际构建的是Build/main.o。 Make继续运行此规则,因为它看到main.o不存在(并且elf文件的规则使用Build/main.o,Make使得重建不知不觉)。

我建议你改变它:

OBJECTS  = $(patsubst %.c, $(OUT_DIR)/%.o, $(C_SOURCES))

$(OUT_DIR)/%.o : ${SOURCE_DIR}/%.c # --> this should work
    @echo "Compiling $<"
    $(CC) $(CFLAGS) $< -o $@

其他%.o规则也是如此。