说我有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 foo
,d e f
,make bar
,如果我a b c d e f
,则调用make foo bar
如果我include
?
我无法使用Makefile.other
,因为clean
由我使用的工具自动生成,并且其本身包含生成的文件,并使T +=
目标太慢。我已尝试T =
而不是foo
,并且bar
和T
依赖于具有该规则的单独目标,但{{1}}是规则 - 本地,所以另一个目标只看到其中一个的信息。
答案 0 :(得分:1)
当您运行make foo bar
时,make 始终同时运行目标foo
和bar
,因此它将始终运行$(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)
不,只有目标foo
和bar
,你无法做到你想要的。
您要求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 bar
和make 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