如何在有和没有额外的 MAKECMDGOAL 的情况下进入子目录
How to descend into child directories with and without an additional MAKECMDGOAL
我有一个 Makefile,我在其中使用通配符进入所有 src/* 文件夹,并在这些子目录中 运行 make。
我想以两种形式在其中调用 make
:
make src/my-project
和 make 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。
我有一个 Makefile,我在其中使用通配符进入所有 src/* 文件夹,并在这些子目录中 运行 make。
我想以两种形式在其中调用 make
:
make src/my-project
和 make 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。