先看一个简单的例子:
$ cat Makefile
t:
make -C b
$ make -j2
make -C b
make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
可以看出,进到子目录执行的make抱怨,jobserver unavailable。添加一个+,就好了。
$ cat Makefile
t:
+make -C b
根据GNU Make数据手册:
make为了和子make交流信息,parent会传递一个信息给child,如果child是一个其它的程序或者其它的Make,这可能导致问题。因此parent只要在确定child和自己是同一个make的情况下,才会传递这些信息,这种情况下父子并行协同编译才生效。
那parent是如何确定child是同一个make的呢?有两个方法:
1 在recipe前,显示的加一个+。
2 recipe扩展了MAKE变量。
因此在recipe中,我们通常要使用$(MAKE),而不是make,上述问题,使用$(MAKE)替换make即解决。
在看第二个例子:
$ cat Makefile
define t
t:
$(MAKE) -C b
endef
$(eval $(t))
执行
$ make -j2
make -C b
make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
发现仍然抱怨,原来$(t)的时候,以及扩展$(MAKE)为make了,eval的时候,生成的recipe已经没有扩展MAKE了,修改一下,到eval的时候,在引用MAKE,问题解决:
$ cat Makefile
define t
t:
$$(MAKE) -C b
endef
$(eval $(t))