1

我必须为一个有几个文件夹的程序编写一个“好的”makefile:bin、inc、obj、src。这是我的制作文件。如果我键入 make 它只是说尽管程序根本没有编译,但什么也做不了。猜猜我在某个地方有错误,但我真的找不到。(ps我是新手)。非常感谢你的帮助!

bin文件夹中的makefile:

vpath %.o ../obj/
$(prog): $(objs)
$(cc) $(ccflags) -o $@ $^ $(ldflags)

obj文件夹中的makefile:

vpath %.c ../src
vpath %.h ../inc
all: $(objs)
%.o: %.c %.h
$(cc) $(ccflags) -c $<
-include *.d    

通用makefile:

export prog := inv_svn
export objs := $(patsubst %.c, %.o, $(wildcard src/*.c)))
export src_dir := src
export inc_dir := inc
export obj_dir := obj
export bin_dir := bin
export cc := gcc
export ccflags := -I $(PWD)/$(inc_dir) -MMD -g -Wall
export ldflags := -lcurses -lgdbm

test := ./$(prog)

all: $(prog)
$(prog): $(bin_dir)
$(bin_dir): $(obj_dir)
$(bin_dir):
make -C $@
$(obj_dir):
make -C $@

.PHONY: clean 

clean: 
rm -f $(obj_dir)/*.[od]$(prog)
4

1 回答 1

0

这里有太多的问题要一次性解决。让我们从小而简单的开始,然后建立起来。

首先,当你真的不需要时,你正在递归地使用 Make。稍后,您应该重新考虑这种设计。现在,让我们看看我们是否可以开始obj/makefile工作。

其次,子 makefile 依赖于objs从调用 makefile 传递下来的变量(如 ),这些变量也可以自己构造。这是一个糟糕的设计。我们将把作业放在obj/makefile

objs := $(patsubst %.c, %.o, $(wildcard ../src/*.c))

(请注意,我已经删除了一个)让事情变得混乱的额外内容。)

第三,当我们测试这个时,我们得到../src/foo.o ../src/bar.o了,这可能不是我们想要的;我们想在 中构建对象obj/,而不是src/(主 makefile 中的分配有同样的问题)。所以我们改变它:

objs := $(patsubst ../src/%.c, %.o, $(wildcard ../src/*.c))

(还有更优雅的方式,但暂时不要介意。)

第四,我相信您可以对bin/makefile.

第五,在主 Makefile 中,您将子目录视为目标,而实际上它们不是;这些规则的重点不是构建子目录,而是在其中运行 Make。如果它们已经存在(它们确实存在),Make 会感到满意,并得出结论$(prog)并且all不需要重建。我们可以通过一些 PHONY 目标来解决这个问题:

.PHONY: RUN_IN_$(obj_dir) RUN_IN_$(bin_dir)

$(prog):  RUN_IN_$(bin_dir)
RUN_IN_$(bin_dir): RUN_IN_$(obj_dir)
RUN_IN_$(bin_dir):
    make -C $(bin_dir)
RUN_IN_$(obj_dir):
    make -C $(obj_dir)

粗鲁但有效。

这应该足以让你离开地面。

于 2012-10-24T19:21:12.687 回答