将目标并行委派给其他make文件,不包含

时间:2015-02-21 05:26:09

标签: makefile gnu-make

说我有Makefile

foo: T = a b c
bar: T = d e f

foo bar:
        $(MAKE) -f Makefile.other $(T)

如果make -j foo bar对b c和d e f之间的依赖关系信息进行编码,则Makefile.other会出错。有没有办法让它做到'#34;对"事情?也就是说,在所有情况下,只执行$(MAKE) -f ...一次,如果a b c make food e fmake bar,如果我a b c d e f,则调用make foo bar如果我include

我无法使用Makefile.other,因为clean由我使用的工具自动生成,并且其本身包含生成的文件,并使T +=目标太慢。我已尝试T =而不是foo,并且barT依赖于具有该规则的单独目标,但{{1}}是规则 - 本地,所以另一个目标只看到其中一个的信息。

2 个答案:

答案 0 :(得分:1)

当您运行make foo bar时,make 始终同时运行目标foobar,因此它将始终运行$(MAKE) ...个配方两次:一次用于foo,一次用于bar。当您运行make foo bar时,您无法只运行一个食谱。

所以,我可以告诉你如何将T设置为正确的值,具体取决于正在构建的目标,但这不会有帮助,因为sub-make始终运行两次,无论如何。 那是那个棘手的部分。

如果你真的想要这样做,你可以这样做:

SUBMAKE = $(MAKE) -f Makefile.other $(T)

T :=
ifeq ($(filter foo,$(MAKECMDGOALS)),foo)
    T += a b c
endif
ifeq ($(filter bar,$(MAKECMDGOALS)),bar)
    T += d e f
endif

foo bar:
        +$(SUBMAKE)$(eval SUBMAKE :=)

这是做什么的?首先,它根据命令行上的值计算T(存储在MAKECMDGOALS中。

其次,在配方中,它首先扩展为SUBMAKE的值,然后使用eval函数将SUBMAKE设置为空。这意味着第一次运行此配方时,它将调用子制表,但随后所有变量都为空,因此它不执行任何操作。

它非常漂亮,而且我不确定它会做你真正想要的东西,但它能满足你的要求。

答案 1 :(得分:0)

不,只有目标foobar,你无法做到你想要的。

您要求make foo bar执行制作 foo 以外的其他操作并制作 bar

规则:

foo bar:
        $(MAKE) -f Makefile.other $(T)

只是简写:

foo :
    $(MAKE) -f Makefile.other $(T)

bar:
    $(MAKE) -f Makefile.other $(T)

因此,举例来说,如果Makefile.other是:

.phony: a b c d e f

a b c d e f:
    @echo $@

然后make foo bar不能有任何结果,但是:

$ make foo bar
make -f Makefile.other a b c
make[1]: Entering directory `/home/imk/develop/SO/scrap'
a
b
c
make[1]: Leaving directory `/home/imk/develop/SO/scrap'
make -f Makefile.other d e f
make[1]: Entering directory `/home/imk/develop/SO/scrap'
d
e
f
make[1]: Leaving directory `/home/imk/develop/SO/scrap'

make根据订单生成foo,然后生成bar。这个“正确的东西”。

如果你想制作a b c d e f,那么你必须定义一个 第三个​​ make目标,需要制作所有目标。例如:

foo_todo = a b c
bar_todo = d e f
foobar_todo = $(foo_todo) $(bar_todo)

foo bar foobar:
    $(MAKE) -f Makefile.other $($@_todo)

然后make foo make barmake foo bar表现得像以前一样 和make foobar输出:

make -f Makefile.other a b c d e f
make[1]: Entering directory `/home/imk/develop/SO/scrap'
a
b
c
d
e
f