如何在有和没有额外的 MAKECMDGOAL 的情况下进入子目录

How to descend into child directories with and without an additional MAKECMDGOAL

我有一个 Makefile,我在其中使用通配符进入所有 src/* 文件夹,并在这些子目录中 运行 make。 我想以两种形式在其中调用 make

make src/my-projectmake upload src/my-project

只有 upload 目标,它按预期工作,如下所示:

SUBDIRS := $(wildcard src/*)
UNAME_S := $(shell uname -s)
TOPTARGETS := upload

ifeq ($(UNAME_S),Linux)
    MKFILE = Makefile-Linux.mk
endif
ifeq ($(UNAME_S),Darwin)
    MKFILE = Makefile-OSX.mk
endif

$(TOPTARGETS): $(SUBDIRS)
$(SUBDIRS):
    $(shell cp ${MKFILE} $@/Makefile)
    $(MAKE) -C $@ $(MAKECMDGOALS)

.PHONY: $(TOPTARGETS) $(SUBDIRS)

但是如果我通过附加以下内容为 make src/my-project 添加第二个目标:

$(SUBDIRS):
    $(shell cp ${MKFILE} $@/Makefile)
    $(MAKE) -C $@

.PHONY: $(SUBDIRS)

make upload src/my-project 停止工作,因为它首先只有 运行s make src/my-project,现在工作正常,但随后显示 make: Nothing to be done for 'src/my-project';整个 MAKECMDGOALS 不再被使用。由于某种原因,第一个目标似乎不再使用了。

有什么办法可以实现吗?

您可以将两者结合在同一规则中。

一些注意事项:您通常不想 运行 $(shell) 在食谱中。食谱已经 运行 在 shell 中,所以它不仅多余,而且还会导致一些意想不到的副作用(它实际上会尝试 运行 里面的命令吐出...... ).

接下来,在生成的文件不是目标的配方中复制 ${MKFILE} 不是好的做法。

您可能想尝试以下方法:

$(TOPTARGETS): $(SUBDIRS)

#rule to copy makefile over
$(SUBDIRS:=/Makefile) : ${MKFILE}
        cp $< $@

NONSUBDIRGOALS:=$(filter-out $(SUBDIRS),$(MAKECMDGOALS))

#static pattern rule to do both builds, which depends on makefile
$(SUBDIRS): % : %/Makefile
        $(MAKE) -C $@
        [ "$(NONSUBDIRGOALS)" ] && $(MAKE) -C $@ $(NONSUBDIRGOALS)

.PHONY: $(TOPTARGETS) $(SUBDIRS)

---- 编辑 ----

已更新以创建 NONSUBDIRGOALS,这是所有非子目录目标的列表。我还使用了一个 [] && 结构来确保如果 NONSUBDIRGOALS 为空则它不会第二次调用 make。