如果您在 GNU/Linux(或任何带有 find 实用程序的类 UNIX 操作系统)下使用 GNU make,目录名称中不要有空格,并且所有 makefile 都命名为 Makefile,以下可能是开始观点。将其添加到您的顶级 makefile 并键入 make all 以构建所有子目录:
SUBDIRS := $(dir $(shell find . -mindepth 2 -type f -name 'Makefile'))
.PHONY: $(SUBDIRS) all
all: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
解释:
find . -mindepth 2 -type f -name 'Makefile' 是一个 shell 命令,它在当前目录的任何子目录 (-mindepth 2) 中查找所有名为 Makefile (-name 'Makefile') 的文件 (-type f)。
$(shell CMD) 是将shell 命令CMD 传递给shell 并返回结果的make 函数。
$(dir LIST)返回LIST的所有路径的目录部分。
SUBDIRS := $(dir ...) 将所有这些分配给 make 变量 SUBDIRS(将 SUBDIRS 替换为您想要的任何名称,它只是一个名称)。所以,如果你有两个名为foo 和bar/baz 的子目录,并且如果它们包含一个名为Makefile 的文件,find . -mindepth 2 -type f -name 'Makefile' 返回foo/Makefile bar/baz/Makefile,而SUBDIRS := $(dir $(shell find . ...)) 将foo bar/baz 分配给make 变量SUBDIRS .
.PHONY: $(SUBDIRS) all 声明 make 变量 SUBDIRS 的值中的任何名称加上 all 都是 假 目标:也就是说,它们不是真正的文件名(即使文件或具有这些名称的目录实际上存在),并且当被要求时,make 将重建它们,即使它们已经存在并且就其先决条件而言是最新的。
all: $(SUBDIRS) 告诉 make all 目标依赖于 make 变量 SUBDIRS 的值中的所有名称;为了使all make 应首先使make 变量SUBDIRS 的值中的所有名称。
最后:
$(SUBDIRS):
$(MAKE) -C $@
是一个 make 规则,它解释了如何在 make 变量 SUBDIRS 的值中创建任何名称。配方 ($(MAKE) -C $@) 只包含再次调用 make ($(MAKE)) 但在 $@ 目录 (-C $@) 中。您必须使用$(MAKE) 而不仅仅是make 的原因可以在GNU make 文档中找到。 $@ 是许多 make 自动变量之一。在配方中它扩展为当前目标。所以,如果SUBDIRS make 变量的值是foo bar/baz,则这条规则与两条单独的规则相同:
foo:
$(MAKE) -C foo
bar/baz:
$(MAKE) -C bar/baz