如何动态欺骗子文件夹中的 Make into 运行 命令

How to trick Make into running commands in subfolders dynamically

我正在尝试从根 makefile 中不知道的子文件夹中获取 Make to 运行 命令。

我在项目根目录下有以下 makefile:

ARGS=$(filter-out $@, $(MAKECMDGOALS))

.PHONY: build
build:
    @$(MAKE) -C ${ARGS} build

%:
    @$(MAKE) -C ${ARGS}

我在 ./folder

有以下内容
build:
    @echo "Mushrooms!"
.PHONY: build

badgers:
    @echo "Badgers!"
.PHONY: badger

所以,当我 运行 make build folder 我得到回声“蘑菇!”正如预期的那样。但是,当我 运行 make folder badgers 时,我得到了相同的回声。

我假设第一个 运行 正确 运行,但它似乎忽略了任何参数(即我想要 运行 的子命令)并且只是运行宁 ./folder/makefile 中的第一个条目。

有谁知道我如何欺骗 make 从子文件夹调用正确的命令?

如果您在顶级 makefile 中启用命令回显,您会看到在 make folder badgers 情况下,执行的递归 make 命令是 make -C folder,而不是 make -C folder badgers。为什么?因为当 ${ARGS} 在 match-anything 规则的上下文中扩展时,目标是 badgers,并且您显式地将目标从扩展中过滤掉!

您可能还注意到,您的两个 make 命令都会打印一条消息,说明 folder 是最新的。这告诉您它选择不执行构建 folder 的配方。在 make build folder 的情况下,顶级 make 只是 运行ning 目标 build 的配方,它将 'build' 重新引入目标列表子使。在 make folder badgers 的情况下,它只执行 badgers 的配方,不会将该目标重新引入 submake,因此 submake 构建默认目标。

我会建议一些不那么神奇的东西:依靠在命令行上定义宏。生成文件如下所示:

.PHONY: build

# Just for the purpose of having a default target
build:
    make -C $(subdir) "$@"

%:
    make -C $(subdir) "$@"

然后你会 运行 make 像这样:

make subdir=folder
make subdir=folder build
make subdir=folder badgers

这仍然存在一些漏洞,例如如果用户没有为 subdirs 指定值会发生什么,但它至少是一个更坚实的构建基础。