STM32F103C8T6裸机项目arm-none-eabi-gcc编译无执行文件如何修复
问题原因及修复方案
核心问题点
你的Makefile存在3个关键错误导致无法生成可执行文件:
- CFLAGS中全局携带了
-c参数:该参数的作用是只编译不链接,仅生成.o目标文件。你在生成最终可执行文件的步骤中仍然传入了带-c的CFLAGS,因此gcc不会执行链接逻辑,直接报「linker input file unused because linking not done」警告。 - 最终目标链接只引入了第一个依赖文件:生成
all的规则中你使用了自动变量$<,该变量仅代表第一个依赖文件(也就是main.o),其余的led.o、stm32f1xx_startup.o都没有参与链接,即使去掉-c也会报符号缺失错误。 - 目标文件依赖规则不合理:你强制要求每个.c文件必须有同名.h文件才能编译,但项目中的stm32f1xx_startup.c没有对应的头文件,后续编译可能触发缺失依赖的报错。
修复后的完整Makefile
CC = arm-none-eabi-gcc OBJCOPY = arm-none-eabi-objcopy MARCH = cortex-m3 # 编译选项:仅保留编译相关参数,-c移到目标文件规则中 CFLAGS = -mcpu=$(MARCH) -mthumb -std=gnu11 -Wall -O0 # 链接选项:指定架构、裸机链接参数、链接脚本(需自行准备对应STM32F103C8T6的ld脚本) LDFLAGS = -mcpu=$(MARCH) -mthumb -nostdlib -T stm32f103c8t6.ld RM = rm -rf OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) INCS = $(wildcard *.h) # 最终生成elf、可烧录的bin和hex文件 all: $(OBJS) $(CC) $(LDFLAGS) $^ -o firmware.elf $(OBJCOPY) -O binary firmware.elf firmware.bin $(OBJCOPY) -O ihex firmware.elf firmware.hex # 生成目标文件的规则,-c放在此处,仅编译阶段生效 %.o: %.c $(INCS) $(CC) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: $(RM) *.o firmware.elf firmware.bin firmware.hex
注意:Makefile中所有命令行必须以Tab键开头,不能用空格代替。
修改说明
- 拆分编译和链接参数:将
-c从全局CFLAGS移到目标文件生成规则中,仅编译.o的时候生效,链接阶段不再携带。新增LDFLAGS专门存放链接参数,加入了裸机开发常用的-nostdlib参数,同时指定链接脚本。 - 修正链接逻辑:用
$^自动变量代替$<,将所有.o目标文件都传入链接器,不会遗漏启动文件、外设驱动文件。 - 优化依赖规则:将每个.c的依赖改为所有头文件,只要任意头文件修改就会重新编译所有.c,避免单个.c缺失对应.h的报错。
- 新增二进制转换步骤:用arm-none-eabi-objcopy把elf格式的可执行文件转成可直接烧录到STM32的bin和hex文件。
额外注意事项
你需要提前准备STM32F103C8T6对应的链接脚本(stm32f103c8t6.ld)放在项目根目录,脚本中需要正确配置:
- FLASH起始地址为0x08000000,大小64KB
- RAM起始地址为0x20000000,大小20KB
如果没有现成的链接脚本,可以直接从STM32CubeMX生成的同型号项目中复制使用。
内容的提问来源于stack exchange,提问作者Văn Minh Lý
相关产品推荐
相关产品推荐

