Makefile 使用源文件和目标文件的目录结构
问题描述
这是我的文件夹结构:
Project : Makefile, final.hex
|- Src : one.c two.c
|- Obj : one.o two.o
这是我的Makefile:
TARGET = final.hex
CC = gcc
SRCDIR = Src
OBJDIR = Obj
SRC = one.c two.c
OBJS = (OBJDIR)/one.o(OBJDIR)/two.o
CFLAGS = -c
LFLAGS = -Wl
.PHONY: all
all: (TARGET)(TARGET): (OBJS)
@echo ****** TARGET ********
@echo Target.hex created(OBJS): %.o: (SRCDIR)/%.c(CC) (CFLAGS)< -o @
@echo ****** OBJS ********
@echo@
@echo $<
当我尝试运行makefile时,它报错:make: *** No rule to make target Src/Obj/one.c', needed by Obj/one.o'. Stop
问题是,有没有方法或其他解决方案可以告诉makefile在$(SRCDIR)中寻找*.c
文件进行编译,即使*.o
文件仍然留在$(OBJDIR)中。
解决方案
您只需要查看变量的扩展及其与模式的匹配方式。让我们看一下您的makefile的内容:
$(OBJS): %.o: $(SRCDIR)/%.c
将展开为以下内容:
Obj/one.o Obj/two.o: %.o: Src/%.c
当使用规则 Obj/one.o
与%.o
进行匹配时,通配符(%
)的取值会是Obj/one
。
然后make
会将这个通配符的取值代入Src/%.c
,因此会得到Src/Obj/one.c
,这不是你想要的结果。
你想要通配符的取值(即匹配 %
的部分)只是文件名,不包含文件路径:one
。因此,你必须写出相应的规则来实现这一点。使用如下的规则:
$(OBJS): $(OBJDIR)/%.o: $(SRCDIR)/%.c
这会展开为:
Obj/one.o Obj/two.o: Obj/%.o: Src/%.c
现在,当进行匹配时,就会匹配到 Obj/one.o
以及 Obj/%.o
,因此匹配结果就只有 one
,所以先决条件将是 Src/one.c
这正是你想要的。