使用源/目标文件目录结构的Makefile编译问题求助
Makefile编译路径错误的解决方案
错误原因
你的模式规则写法有误。当Make处理$(OBJS): %.o: $(SRCDIR)/%.c时,$(OBJS)是Obj/one.o Obj/two.o,%会被匹配为Obj/one和Obj/two,导致Make去寻找Src/Obj/one.c这种不存在的路径,最终触发报错。
修正步骤
修正模式规则:将针对
$(OBJS)的模式规则改为匹配$(OBJDIR)下所有.o文件对应$(SRCDIR)下的.c文件,正确写法如下:$(OBJDIR)/%.o: $(SRCDIR)/%.c $(CC) $(CFLAGS) $< -o $@ @echo ****** OBJS ******** @echo $@ @echo $<此时
%会匹配one、two,对应寻找Src/one.c并生成Obj/one.o,路径逻辑正确。完善目标文件生成逻辑:原Makefile中
$(TARGET)规则只有打印操作,没有实际的链接和转hex流程。需要先将.o文件链接成可执行文件,再通过objcopy转换为hex格式(适配嵌入式平台的常见需求):$(TARGET): $(OBJS) @echo ****** TARGET ******** $(CC) $(OBJS) -o final.elf objcopy -O ihex final.elf $(TARGET) @echo Target.hex created添加Obj目录创建:如果
Obj目录不存在,编译会失败,可在all规则前添加目录创建步骤:$(OBJDIR): mkdir -p $(OBJDIR) all: $(OBJDIR) $(TARGET)可选:添加清理规则:方便快速清理生成的中间文件和目标文件:
.PHONY: clean clean: rm -rf $(OBJDIR) final.elf $(TARGET)
完整修正后的Makefile
TARGET = final.hex CC = gcc SRCDIR = Src OBJDIR = Obj # 自动获取Src目录下所有.c文件,无需手动列举 SRC = $(wildcard $(SRCDIR)/*.c) # 根据.c文件自动生成对应的.o文件路径 OBJS = $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SRC)) CFLAGS = -c LFLAGS = -Wl .PHONY: all clean all: $(OBJDIR) $(TARGET) $(OBJDIR): mkdir -p $(OBJDIR) $(TARGET): $(OBJS) @echo ****** TARGET ******** $(CC) $(OBJS) -o final.elf objcopy -O ihex final.elf $(TARGET) @echo Target.hex created $(OBJDIR)/%.o: $(SRCDIR)/%.c $(CC) $(CFLAGS) $< -o $@ @echo ****** OBJS ******** @echo $@ @echo $< clean: rm -rf $(OBJDIR) final.elf $(TARGET)
额外优化说明
- 使用
$(wildcard $(SRCDIR)/*.c)自动扫描Src目录下所有.c文件,后续新增源文件无需修改Makefile。 - 使用
$(patsubst ...)自动生成对应的.o文件路径,避免手动编写每个目标文件路径,提升灵活性。
内容的提问来源于stack exchange,提问作者learning_user
相关产品推荐
相关产品推荐

