如何将目标名称传递给子makefile列表?

如何将目标名称传递给子makefile列表?,makefile,gnu-make,Makefile,Gnu Make,我有这样的设置: /Makefile /foo/Makefile /foo/bar/Makefile /foo/baz/Makefile $(INSTALL_DIRS): $(MAKE) -C $@ install clean: $(foreach DIR, $(SUB_DIRS), $(MAKE) -C $(DIR) $@;) 顶级Makefile包含一个调用/foo/Makefile的任务。此Makefiles在子目录中创建Makefiles列表(bar,baz)。对于

我有这样的设置:

/Makefile
/foo/Makefile
/foo/bar/Makefile
/foo/baz/Makefile
$(INSTALL_DIRS):
    $(MAKE) -C $@ install
clean:
    $(foreach DIR, $(SUB_DIRS), $(MAKE) -C $(DIR) $@;)
顶级Makefile包含一个调用
/foo/Makefile
的任务。此Makefiles在子目录中创建Makefiles列表(
bar
baz
)。对于每个子目录,它调用makefile:

$(SUB_DIRS):
    $(MAKE) -C $@
例如,对于
all
任务来说,这很好。但是如果我想做别的事情,我会被卡住是否可以将目标传递到子生成文件列表?例如:

$(SUB_DIRS):
    $(MAKE) -C $@ <task>

clean: $(SUB_DIRS)-clean # or something?
$(子目录):
$(MAKE)-C$@
干净:$(SUB_DIRS)-干净还是什么?

还是我的整个概念都错了?

是的,你只需按照规定去做,当你想做某件事并且可能再次发生时,乐趣就来自于在下一个级别处理

例如,我有一个递归安装,如下所示:

/Makefile
/foo/Makefile
/foo/bar/Makefile
/foo/baz/Makefile
$(INSTALL_DIRS):
    $(MAKE) -C $@ install
clean:
    $(foreach DIR, $(SUB_DIRS), $(MAKE) -C $(DIR) $@;)

我终于成功了。方法是:

SUB_DIRS        = $(wildcard */.)
SUB_DIRS_ALL    = $(SUB_DIRS:%=all-%)
SUB_DIRS_TEST   = $(SUB_DIRS:%=test-%)
SUB_DIRS_CLEAN  = $(SUB_DIRS:%=clean-%)

#
# Standard task
#
all: $(SUB_DIRS_ALL)

test_uml: $(SUB_DIRS_TEST)

clean: $(SUB_DIRS_CLEAN)

$(SUB_DIRS_ALL):
        @$(MAKE) $(MAKE_FLAGS) -C $(@:all-%=%)

$(SUB_DIRS_TEST):
        @$(MAKE) $(MAKE_FLAGS) -C $(@:test-%=%) test

$(SUB_DIRS_CLEAN):
        @$(MAKE) $(MAKE_FLAGS) -C $(@:clean-%=%) clean
我在这里找到了这个解决方案:

您可以简单地使用变量:

Make将特殊变量
MAKECMDGOALS
设置为您在命令行上指定的目标列表。如果命令行上没有给出目标,则此变量为空

+
符号很重要,因此底层还可以使用适当数量的线程/核心处理递归make调用


您还可以像这样使用
$(foreach)
功能:

/Makefile
/foo/Makefile
/foo/bar/Makefile
/foo/baz/Makefile
$(INSTALL_DIRS):
    $(MAKE) -C $@ install
clean:
    $(foreach DIR, $(SUB_DIRS), $(MAKE) -C $(DIR) $@;)

请注意,正如@musicmatze在评论中提到的那样,Make标志(如
-j
)不会正确地传递到此处的子Make流程。

我做过类似的事情,但我也对这个问题的其他解决方案感兴趣。你不可能“做类似的事情”,因为没有解决方案。我的示例根本不起作用。您使用的make版本是什么,我这样做是为了记录:这(MAKECMDGOALSone)是最干净的解决方案。我的解决方案也很有效。
foreach
方法确实有效,但是如果你想做
make-j4
(例如),
foreach
方法没有伸缩性,我猜。这基本上和我发布的内容是一样的,只是在你不能使用目录名的时候进一步推断出来。(您需要为其添加前缀/后缀,然后在执行时去掉前缀/后缀)。我经常完全按照你所描述的那样做,不想一字不差地发表,因为我希望有人能提出一些我还没有发现的东西,比如MAKECMDGOALS来真正解决问题,而我个人没有看到其中的价值超出了我所描述的。