传递规则以递归

时间:2015-01-22 19:08:07

标签: recursion makefile

这样做可能微不足道,但我无法理解。

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

即,我希望能够通过以下方式调用我的主Makefile:

make some_rule TARGET=a

make some_rule TARGET=b

让我的主Makefile根据TARGET的值决定调用makefile来运行make some_rule。 (例如,决定是否调用sub_directory_a / Makefile或sub_directory_b / Makefile来执行规则some_rule。)

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

1 个答案:

答案 0 :(得分:2)

你可以用

做你所描述的
default_target:

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

%:规则是一种模式规则,其中模式匹配所有规则(GNU make手册称为匹配任何规则); $@是当前的目标。请注意,default_target:规则没有配方,因此在没有目标的情况下调用make将使用match-anything规则的配方(唯一适用且具有配方的规则)尝试构建default_target

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

PHONY_TARGETS = all clean distclean

.PHONY: $(PHONY_TARGETS)

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

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

不幸的是,我不知道宣布所有目标虚假的伎俩,这是你真正想做的事情。

请注意,如果要为ifeq提供比目录名称更多的花哨值,可以使用TARGET等与在命令行中设置的变量,例如

%:
ifeq ($(TARGET),gibson)
    echo 'Planet $@ was successfully hacked.'
else
    $(MAKE) -C some_directory_$(TARGET) $@
endif

另请注意,为许多Makefile设置公共变量的更常见方法是将它们放入文件中,通常是common.mk,并将include放在其他Makefile中:

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

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