File GNU Make包含多个文件夹和文件

File GNU Make包含多个文件夹和文件,file,makefile,gnu,File,Makefile,Gnu,我必须为一个有多个文件夹的程序编写一个“好”的makefile: 宾公司,obj,src。这是我的制作文件。如果我输入make,它只是说尽管程序根本没有编译,但什么也做不了。我想我在什么地方出错了,但我真的找不到。(注:我是个新手)。 非常感谢你的帮助 bin文件夹中的makefile: vpath %.o ../obj/ $(prog): $(objs) $(cc) $(ccflags) -o $@ $^ $(ldflags) obj文件夹中的makefile: vpath %.c ../s

我必须为一个有多个文件夹的程序编写一个“好”的makefile: 宾公司,obj,src。这是我的制作文件。如果我输入make,它只是说尽管程序根本没有编译,但什么也做不了。我想我在什么地方出错了,但我真的找不到。(注:我是个新手)。 非常感谢你的帮助

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    

这里的问题太多,无法一次解决。让我们从小处做起,简单地积累经验

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

其次,子makefile依赖于从调用makefile传下来的变量(如
objs
),这些变量也可以自己构造。这是个糟糕的设计。我们将把作业放入
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)
所有的
。我们可以通过一些虚假目标来解决这个问题:

.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)
粗糙但有效

这应该足够让你离开地面了

.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)