我正在尝试让我的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)
答案 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规则也是如此。