You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Makefile避免编译未修改源码的问题求助

多目录源码Makefile编译目标文件失败问题解决

问题背景

需要编写适配多目录及子目录源码的Makefile,将所有源码编译为目标文件后链接生成二进制文件。当前make all可正常完成编译,但执行make bad时会报错。原始Makefile通过手动列举所有源文件实现多目录编译,修改后尝试自动查找所有.c和.S文件,但目标文件的编译规则存在问题。

错误原因分析

  1. 目录变量处理错误:使用ASM_DIRNAME := $(shell dirname $(ASM_SOURCES))和GCC_DIRNAME := $(shell dirname $(GCC_SOURCES))时,若存在多目录源文件,dirname会返回空格分隔的多个目录路径,导致后续patsubst和模式规则(如$(ASM_DIRNAME)/%.o: $(ASM_DIRNAME)/%.S)变成无效的多目录拼接格式,Make无法匹配正确的文件路径。
  2. 变量引用错误:bad目标中使用了未定义的$(GCC)变量,正确应使用已定义的$(CC);链接输出文件名与all目标的$(TARGET).elf不一致,且编译目标文件时缺少头文件路径INCLUDES。
  3. 模式规则不通用:原规则仅针对单一目录设计,无法适配多目录下的源文件编译。

修正后的Makefile

TARGET=analyser
CC=arm-none-eabi-gcc
OBJCPY=arm-none-eabi-objcopy
CFLAGS= -DNDEBUG -DCPU_MK64FN1M0VLL12 -DUSE_RTOS=1 -DPRINTF_ADVANCED_ENABLE=1 \
-DFRDM_K64F -DFREEDOM -DFSL_RTOS_FREE_RTOS -Os -Wall -fno-common \
-ffunction-sections -fdata-sections -ffreestanding -fno-builtin \
-mthumb -mapcs -std=gnu99 -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MMD -MP \
--specs=nano.specs --specs=nosys.specs -Wall -fno-common -ffunction-sections \
-fdata-sections -ffreestanding -fno-builtin -mthumb -mapcs -Xlinker --gc-sections \
-Xlinker -static -Xlinker -z -Xlinker muldefs -Xlinker -Map=output.map -mcpu=cortex-m4 \
-mfloat-abi=hard -mfpu=fpv4-sp-d16 -Xlinker --defsym=__stack_size__=2048 -Xlinker \
--defsym=__heap_size__=25600 -Wall

LDSCRIPT=linker/MK64FN1M0xxx12_flash.ld

# 自动查找所有.c和.S文件
ASM_SOURCES := $(shell find . -name "*.S")
GCC_SOURCES := $(shell find . -name "*.c")

# 将源文件路径替换为对应的目标文件路径
ASM_OBJECTS := $(ASM_SOURCES:.S=.o)
GCC_OBJECTS := $(GCC_SOURCES:.c=.o)

INCLUDES=\
    -Iapp/include \
    -ICMSIS \
    -Ifsl \
    -IFreeRTOS/include \
    -IFreeRTOS/include/private \
    -IFreeRTOS/src/portable/GCC/ARM_CM4F \
    -Iinclude \
    -Idrivers/uart \
    -Idrivers/serial_manager \
    -Idrivers/lists \
    -Ilwip/port \
    -Ilwip/src \
    -Ilwip/src/include \

all: $(TARGET).elf $(TARGET).bin

# 直接编译所有源文件生成elf
$(TARGET).elf:
    $(CC) $(INCLUDES) $(GCC_SOURCES) $(ASM_SOURCES) $(CFLAGS) -T $(LDSCRIPT) -o $@

$(TARGET).bin: $(TARGET).elf
    $(OBJCPY) $< $@ -O binary

# 通过目标文件链接生成elf
bad: $(TARGET).elf

$(TARGET).elf: $(GCC_OBJECTS) $(ASM_OBJECTS)
    $(CC) $(CFLAGS) -T $(LDSCRIPT) $^ -o $@

# 通用模式规则:编译任意目录下的.c文件为.o
%.o: %.c
    $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@

# 通用模式规则:编译任意目录下的.S文件为.o
%.o: %.S
    $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(TARGET).elf $(TARGET).bin $(TARGET).d output.map $(GCC_OBJECTS) $(ASM_OBJECTS)

关键修正点

  • 目标文件路径生成:直接使用$(ASM_SOURCES:.S=.o)和$(GCC_SOURCES:.c=.o)将每个源文件替换为同目录下的目标文件,无需手动提取目录。
  • 通用模式规则:使用%.o: %.c和%.o: %.S匹配任意目录下的源文件,自动生成对应的目标文件。
  • 修正bad目标:将$(GCC)改为$(CC),统一输出文件名为$(TARGET).elf,并依赖所有目标文件完成链接。
  • 增强clean目标:添加删除所有目标文件的命令,确保清理彻底。

内容的提问来源于stack exchange,提问作者IceDefcon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:34:52