首页 > 解决方案 > 如何在有和没有额外 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停止工作,因为它首先只运行make src/my-project,现在工作正常,然后说make: Nothing to be done for 'src/my-project';整体MAKECMDGOALS已经不用了。由于某种原因,看起来第一个目标不再使用。

有什么办法可以做到这一点?

标签: makefilegnu-make

解决方案


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

一些注意事项:您通常不想$(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。


推荐阅读