将目标文件存储在构建目录(Makefile)中

时间:2016-09-07 19:53:15

标签: c makefile

我知道这已被问了很多,我看了几个回答,但无法弄清楚出了什么问题。我正在尝试将所有目标文件存储在构建目录中。在根文件夹中,我有我的Makefile,以及以下目录:include,bin,build,src和rsrc。我希望存储在构建目录中的目标文件和存储在bin中的可执行文件。这是我的Makefile。

CFLAGS = -Wall -Werror
DIRS = -I $(IDIR) -I $(SRCDIR) -I $(ODIR)

IDIR = include
SRCDIR = src
ODIR = build


DEPS = include/map_reduce.h include/const.h

BINS = mapreduce

all: $(BINS)

_OBJ = map_reduce.o main.o
OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))

$(ODIR)/%.o: %.c $(DEPS)
    gcc -c -o $@ $< $(CFLAGS)

mapreduce: $(OBJ)
    gcc $(CFLAGS) $(DIRS) $^ -o $@ 


clean:
    rm -f *.o $(BINS)

我目前没有将可执行文件存储在bin文件夹中的规则,但我想如果我能理解如何在构建中存储目标文件那么该部分应该不难。

我收到错误“mapreduce需要制作目标构建/ map_reduce.o没有规则”

任何有助于我了解这里发生的事情的见解都将非常感谢!

1 个答案:

答案 0 :(得分:2)

考虑这条规则:

$(ODIR)/%.o: %.c $(DEPS)
    gcc -c -o $@ $< $(CFLAGS)

这是一个模式规则(这是GNU make特有的一个特性),描述了如何根据表单$(ODIR)/%.o的文件和各种文件构建名称格式为%.c的文件列在变量$(DEPS)中。

假设您的文件按照您的描述进行排列,并且您使用包含make的目录作为初始工作目录运行Makefile,该规则永远不会适用,即使其中一个中间需要构建的目标确实与该规则中的目标模式匹配。这是因为规则所表达的依赖关系并非全部存在,而make无法确定构建遗失的依赖关系

问题是您想要的依赖项存在于子目录中,但编写规则是为了期望.c文件直接存在于工作目录中。你想要更像这样的东西:

$(ODIR)/%.o: $(SRCDIR)/%.c $(DEPS)
    gcc -c -o $@ $(DIRS) $(CFLAGS) $<