Makefile 如何在有和没有其他MAKECMDGOAL的情况下进入子目录

Makefile 如何在有和没有其他MAKECMDGOAL的情况下进入子目录,makefile,gnu-make,Makefile,Gnu Make,我有一个Makefile,在其中使用通配符进入所有src/*文件夹,并在这些子目录中运行make。 我想以两种形式调用make: make src/my project和make upload src/my project 仅使用上传目标,其工作方式与预期一致,如下所示: SUBDIRS := $(wildcard src/*) UNAME_S := $(shell uname -s) TOPTARGETS := upload ifeq ($(UNAME_S),Linux) MKFIL

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

make src/my project
make upload src/my project

仅使用
上传
目标,其工作方式与预期一致,如下所示:

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: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)
$(顶级目标):$(细分目标)
#复制转换文件的规则
$(子目录:=/Makefile):${MKFILE}
cp$<$@
非SubdirGoals:=$(筛选出$(子项),$(MAKECMDGOALS))
#静态模式规则执行两个构建,这取决于makefile
$(子目录):%:%/Makefile
$(MAKE)-C$@
[“$(非次级目标)”]&&$(制造)-C$@$(非次级目标)
.PHONY:$(顶级目标)$(细分市场)
----编辑----


更新以创建
非次级目标
,该目标是所有非次级目标的列表。我还使用了
[]&&
构造来确保如果
非SubdirGoals
为空,那么它将不会第二次调用make。

我必须交换配方中的行以使其工作,因为当我调用
make src/my project
时,make文件实际上执行
make-C src/my project src/my project
,由于
没有规则使目标src/my project
失败。交换行可以解决这个问题。但即便如此,它还是会进入
src/myproject
,执行一个简单的
make
(它可以工作),然后
make src/myproject
。第二个失败了。有没有办法将规则更改为只调用
make-C src/my project
make-C src/my project upload
,而不添加另一个
src/my project
目标?在调用submake之前,您需要从
$(MAKECMDGOALS)
中正确筛选出目录。我将编辑我的答案。