【问题标题】:How to descend into child directories with and without an additional MAKECMDGOAL如何在有和没有额外 MAKECMDGOAL 的情况下进入子目录
【发布时间】:2019-07-26 11:38:45
【问题描述】:

我有一个 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 不再被使用。由于某种原因,第一个目标似乎不再使用了。

有什么方法可以实现吗?

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

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

    一些注意事项:您通常不想在配方中运行$(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,它是所有非子目录的目标的列表。我还使用了[] &amp;&amp; 构造来确保如果NONSUBDIRGOALS 为空,那么它不会第二次调用make。

    【讨论】:

    • 我不得不交换配方中的行以使其工作,因为当我调用make src/my-project 时,makefile 实际上执行make -C src/my-project src/my-project,它以no rule to make target src/my-project 失败。换行可以解决这个问题。但即便如此,它也会下降到src/my-project 并执行一个普通的make(有效),然后是make src/my-project。第二个失败。有没有办法将规则更改为只调用make -C src/my-projectmake -C src/my-project upload 而无需添加另一个src/my-project 目标?
    • 在调用 submake 之前,您需要从 $(MAKECMDGOALS) 中正确过滤掉您的目录。我将编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    相关资源
    最近更新 更多