在子目录-makefile中收集所有.o

在子目录-makefile中收集所有.o,makefile,Makefile,我有以下层次结构: + makefile | + TT_Project1 | obj/ | makefile + TT_Project2 | obj/ | makefile + TT_Project3 | obj/ | makefile 顶级makefile递归调用它下面的所有makefile,每个makefile都将.cpp编译为.o,并将其置于/obj 我想收集顶层的所有.o,以创建一个静态库。失败,因为我的输出库太小 TT :=

我有以下层次结构:

+ makefile
|
+ TT_Project1
|      obj/
|      makefile
+ TT_Project2
|      obj/
|      makefile
+ TT_Project3
|      obj/
|      makefile
顶级makefile递归调用它下面的所有makefile,每个makefile都将.cpp编译为.o,并将其置于
/obj

我想收集顶层的所有
.o
,以创建一个静态库。失败,因为我的输出库太小

TT := libTT.a

SUBDIRS := $(wildcard */.)
OBJECTS := $(wildcard $(addsuffix *.o,$(SUBDIRS)/obj))

all: $(TT) $(OBJECTS)

$(TT) : $(OBJECTS)
    ar rcs $(TT) $(OBJECTS)

$(SUBDIRS):
    $(MAKE) -C $@
我可以清楚地看到,它正在运行它下面的makefile,并且他们正在按照预期将
*.o
放在它们的
/obj
下。但是我没能抓住所有的
.o
我想。。。感谢您的帮助。

首先,这是错误的:

OBJECTS := $(wildcard $(addsuffix *.o,$(SUBDIRS)/obj))
您不仅在
obj
*.o
之间缺少
/
,而且需要将
/obj
放在
addsuffix
的第一个参数中。假设
SUBDIRS
foo/结束。巴/。baz/
。然后
addsuffix
将扩展为:

$(addsuffix *.o,foo/. bar/. baz/./obj)
其中:

foo/.*o bar/.*.o baz/./obj*.o
这显然是错误的。你想要这个:

OBJECTS := $(wildcard $(addsuffix /obj/*.o,$(SUBDIRS)))
然而,这不是你想要的。它将不起作用,因为在执行任何操作之前,在读取makefile时会展开这些变量。在makefile实际构建任何内容之前,将不存在
.o
文件,这意味着
通配符
函数将不匹配任何内容

在您的情况下,这是一件好事,因为如果它确实匹配任何对象,您将得到错误,因为make不知道如何构建这些对象:它们是由子make构建的

但是,由于您没有依赖于
子目录的任何内容,因此无论如何都无法构建它们:这些配方永远不会运行

您可以做的最简单的事情如下:

TT := libTT.a

SUBDIRS := $(wildcard */.)

all: $(TT)

$(TT) : $(SUBDIRS)
        ar rcs $(TT) $(addsuffix /obj/*.o,$(SUBDIRS))

$(SUBDIRS):
        $(MAKE) -C $@
.PHONY: $(SUBDIRS)

这样做的缺点是,即使未更改任何对象,它也会在每次运行
make
时重建库。要解决这个问题,您必须增加一些复杂性。

一个问题,如果将来我决定添加其他目录,如何修改
子目录:=$(通配符*/)
以仅添加以
TT\ucode>开头的目录?
通配符
使用普通的shell全局搜索。所以您要使用
$(通配符TT.*/)