修改可执行文件目录后AVR项目调试信息丢失求助
AVR项目Makefile修改后调试信息丢失问题排查
问题背景
我正在学习Makefile,编写了一个通用Makefile用于构建简单AVR项目,使用Proteus进行仿真。原Makefile可正常调试,但将生成文件的目录改为build/bin后,调试信息丢失。我已添加-g、-ggdb等调试所需的编译标志,不清楚问题出在哪里。
原Makefile内容
# =============================================== # Toolchain # =============================================== CC = avr-gcc OBJCOPY = avr-objcopy OBJDUMP = avr-objdump AVRSIZE = avr-size # =============================================== # Directories # =============================================== BUILDDIR = build OBJDIR = $(BUILDDIR)/obj BINDIR = $(BUILDDIR)/bin # =============================================== # Files # =============================================== TARGET = atmega32 SOURCES = $(shell find src/ -name "*.c") OBJS = $(SOURCES:%.c=$(OBJDIR)/%.o) HEADERS = $(shell find . -name "*.h") # =============================================== # Flags # =============================================== DEVICE = atmega32 F_CPU = 1000000 BAUD = 9600 CFLAGS = -mmcu=$(DEVICE) -DF_CPU=$(F_CPU)UL -DBAUD=$(BAUD) -Os CFLAGS += -Wall -Wextra -Werror -Wshadow -Wstrict-prototypes CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax CFLAGS += -g -ggdb CFLAGS += -std=gnu99 -Wl,-Map,"main.map" # =============================================== # Compiling & Linking # =============================================== all: $(TARGET).hex %.hex: %.elf $(OBJCOPY) -R .eeprom -O ihex $< $@ %.elf: $(SOURCES) $(HEADERS) @$(CC) $(CFLAGS) $(SOURCES) --output $@ size : $(TARGET).elf @$(AVRSIZE) -C --mcu=$(DEVICE) $^ # =============================================== # Phonies # =============================================== .PHONY: all flash clean size clean: @rm -f *.elf *.hex *.map
修改后的Makefile(仅编译链接部分改动)
# =============================================== # Toolchain # =============================================== CC = avr-gcc OBJCOPY = avr-objcopy OBJDUMP = avr-objdump AVRSIZE = avr-size # =============================================== # Directories # =============================================== BUILDDIR = build OBJDIR = $(BUILDDIR)/obj BINDIR = $(BUILDDIR)/bin # =============================================== # Files # =============================================== TARGET = atmega32 SOURCES = $(shell find src/ -name "*.c") OBJS = $(SOURCES:%.c=$(OBJDIR)/%.o) HEADERS = $(shell find . -name "*.h") # =============================================== # Flags # =============================================== DEVICE = atmega32 F_CPU = 1000000 BAUD = 9600 CFLAGS = -mmcu=$(DEVICE) -DF_CPU=$(F_CPU)UL -DBAUD=$(BAUD) -Os CFLAGS += -Wall -Wextra -Werror -Wshadow -Wstrict-prototypes CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax CFLAGS += -g -ggdb CFLAGS += -std=gnu99 -Wl,-Map,"$(BUILDDIR)/main.map" # =============================================== # Compiling & Linking # =============================================== all: $(BUILDDIR)/$(TARGET).hex %.hex: %.elf $(OBJCOPY) -R .eeprom -O ihex $< $@ %.elf: $(SOURCES) $(HEADERS) @$(CC) $(CFLAGS) $(SOURCES) --output $@ size : $(BUILDDIR)/$(TARGET).elf @$(AVRSIZE) -C --mcu=$(DEVICE) $^ # =============================================== # Phonies # =============================================== .PHONY: all flash clean size clean: @rm -f $(BUILDDIR)/*.elf $(BUILDDIR)/*.hex $(BUILDDIR)/*.map
问题排查与解决
1. 目标目录与实际生成路径不匹配
你提到要将生成文件放到build/bin,但修改后的Makefile并未使用定义好的BINDIR,而是将文件生成到build目录下。这会导致Proteus调试时找不到正确路径下的elf文件(调试信息仅存储在elf文件中,hex文件不含调试符号)。
修正方法:将所有生成文件的路径改为使用BINDIR,同时确保目录自动创建:
# 编译链接部分修改 all: $(BINDIR)/$(TARGET).hex %.hex: %.elf $(OBJCOPY) -R .eeprom -O ihex $< $@ $(BINDIR)/%.elf: $(SOURCES) $(HEADERS) @mkdir -p $(BINDIR) # 确保目标目录存在 @$(CC) $(CFLAGS) $(SOURCES) --output $@ size : $(BINDIR)/$(TARGET).elf @$(AVRSIZE) -C --mcu=$(DEVICE) $^ clean: @rm -rf $(BUILDDIR)/*
2. 确认elf文件是否包含调试信息
用以下命令检查生成的elf文件是否包含调试信息:
avr-objdump -S $(BINDIR)/atmega32.elf
如果输出中能看到源代码与汇编的对应关系,说明调试信息存在,问题出在Proteus的配置上。
3. 更新Proteus调试文件路径
打开Proteus工程,找到调试配置选项,将调试目标文件的路径更新为build/bin/atmega32.elf,替换原来的当前目录路径。
4. 模式规则的匹配问题
原Makefile中的%.elf通用规则在目标文件位于子目录时,Make的模式匹配可能出现歧义。改为明确的$(BINDIR)/%.elf路径匹配规则,可以避免这个问题。
额外建议
Os优化会让调试时的变量显示略有异常,但不影响基本调试。如果需要更清晰的调试体验,可以临时将-Os改为-O0关闭优化。- 添加
mkdir -p $(OBJDIR)到编译规则前,避免因中间文件目录不存在导致编译失败。
内容的提问来源于stack exchange,提问作者Nabil Yasser
相关产品推荐
相关产品推荐

