Recursion 递归地传递规则以生成

Recursion 递归地传递规则以生成,recursion,makefile,Recursion,Makefile,这样做可能很琐碎,但我不知道怎么做 我希望有一个父Makefile来根据在命令行中传递的变量值决定递归调用哪个Makefile 也就是说,我希望能够通过以下方式调用我的主Makefile: make some_rule TARGET=a 或 让我的主Makefile根据TARGET的值来决定调用哪个Makefile来运行makesome_规则。(例如,决定是调用sub_directory_a/Makefile还是sub_directory_b/Makefile来执行规则some_rule。)

这样做可能很琐碎,但我不知道怎么做

我希望有一个父Makefile来根据在命令行中传递的变量值决定递归调用哪个Makefile

也就是说,我希望能够通过以下方式调用我的主Makefile:

make some_rule TARGET=a

让我的主Makefile根据TARGET的值来决定调用哪个Makefile来运行makesome_规则。(例如,决定是调用sub_directory_a/Makefile还是sub_directory_b/Makefile来执行规则some_rule。)


注意:我有许多不同的规则,所以我不希望我的主Makefile列出所有可能的规则,并为每个规则递归调用正确的Makefile。我希望我的主Makefile只能有几行,并且不必在我创建新规则时进行更新。

您可以使用

default_target:

%:
    $(MAKE) -C some_directory_$(TARGET) $@
%:
规则是一种模式规则,其中模式匹配所有规则(GNU make手册称为匹配任何规则)<代码>$@是当前目标。请注意,
default\u目标:
规则没有配方,因此在没有目标的情况下调用
make
将使用match anything规则的配方(唯一适用且有配方的规则)来尝试构建
default\u目标

这种方法的警告是,目标不能被宣布为虚假的。例如,如果您想要有虚假的目标,您必须再次指定这些目标的配方

PHONY_TARGETS = all clean distclean

.PHONY: $(PHONY_TARGETS)

$(PHONY_TARGETS):
    $(MAKE) -C some_directory_$(TARGET) $@

%:
    $(MAKE) -C some_directory_$(TARGET) $@
不幸的是,我不知道一个把戏来宣布所有的目标都是假的,这是你真正想做的

请注意,如果希望为
TARGET
提供比部分目录名(如

%:
ifeq ($(TARGET),gibson)
    echo 'Planet $@ was successfully hacked.'
else
    $(MAKE) -C some_directory_$(TARGET) $@
endif
还要注意,为许多Makefiles设置公共变量的一种更常见的方法是将它们放入一个文件中,通常是
common.mk
,并且
从其他Makefiles中包含它:

include ../common.mk    # to include common.mk from some_directory_a/Makefile

但是你必须自己决定哪种方法更适合你的项目。

我想在这里可能对你有用。也就是说,您是否希望您的顶级makefile为您做任何事情,或者只是选择正确的子文件夹来调用Makein?因为如果它对你没有任何帮助,那么也许仅仅使用
make-C sub_directory_a
是正确的想法。嗯,这是个好主意,但是是的,我想使用我的主make设置所有其他make文件共享的变量。解决我的问题的一种方法是,无论用户请求什么规则,都可以告诉make运行相同的规则。也就是说,无论我调用make rule_1还是make rule_2,主make都会在内部执行相同的规则,设置需要设置的变量,并决定调用哪个makefile并传递用户提供的规则。我不知道这是否可能,但这将解决我所追求的问题。在我刚才所说的基础上,也许我应该明确列出公共make中所有专用makefile支持的所有规则,并调用相同的“默认”目标。这应该行得通,如果我必须列出所有支持的规则,那也不是世界末日。我希望我能将你的答案标记为正确的两次,因为你不仅回答了我的问题,而且还回答了我要问的下一个问题:如何在多个makefiles可以共享的单独文件中声明变量。这太棒了。非常感谢。
include ../common.mk    # to include common.mk from some_directory_a/Makefile