警告:作业服务器不可用:使用 -j1。将“+”添加到父生成规则

ant*_*_rh 11 makefile

这是我的 Makefile:

.PHONY: test%

test1:
    # jobserver is UNavailable
    make -C sub

test2:
    # jobserver is available, ok
    +make -C sub

test3:
    # jobserver is available, ok
    $(MAKE) -C sub

test4:
    # jobserver is available, ok
    +$(MAKE) -C sub
Run Code Online (Sandbox Code Playgroud)

sub 是包含另一个Makefile(子make)的子目录。

当我运行test1规则时:

$ make -j8 test1
make -C sub
make[1]: warning: jobserver unavailable: using -j1.  Add '+' to parent make rule.
Run Code Online (Sandbox Code Playgroud)

我收到警告说 jobserver 不可用并且sub/Makefile确实在单线程中运行(就像-j1)。

他们说我应该添加+,所以我运行了一个test2包含+beforemake命令的目标。现在我没有看到警告并且sub/Makefile实际上是并行运行的。但是根据this answer,该+标志不是用于并行运行,而是用于强制运行命令,即使make使用-n, -t,-q标志运行。但是为什么+启用 jobserver 呢?

当我运行test3不使用+$(MAKE)用于运行的目标时sub/Makefile,它也不会发出作业服务器警告(并行执行有效)。那么make和之间有什么区别$(MAKE)?我认为这仅仅是允许替代默认的化妆与用户定义的补充。当我不覆盖MAKE变量时,我看到的make命令与我在test1目标中看到的命令相同。但是为什么$(MAKE)启用 jobserver 而make没有呢?

运行test4目标也不会发出作业服务器警告(并行工作)。

请注意,我的问题与不同。这是关于cmake,我的问题是关于make。还有相关的问题,但它没有回答我的问题。

osh*_*das 16

GNU make 手册对这个错误有很好的解释。关键是:'make' 不会将有关 jobserver 的信息传递给被调用的进程,除非确定被调用的进程也是 'make'。

'警告:作业服务器不可用:使用 -j1。将“+”添加到父生成规则。

为了使进程进行通信,父进程将信息传递给子进程。因为如果子进程实际上不是一个 make,这可能会导致问题,所以父进程只有在它认为子进程是一个 make 时才会这样做。父级使用普通算法来确定这一点(请参阅MAKE 变量的工作原理)。如果 makefile 的构造使得父进程不知道子进程是一个 make 进程,那么子进程将只收到部分必要的信息。在这种情况下,子进程将生成此警告消息并按顺序进行构建。

错误描述中引用的 MAKE 变量如何工作部分指定了两种告诉 'make' 调用的进程是 'make' 的另一个实例的方法:使用$(MAKE)+。它指出:

  1. $(MAKE)在配方中调用“make”时应该使用变量。

    递归 make 命令应始终使用变量 MAKE,而不是显式命令名称“make”,如下所示:

    subsystem:
            cd subdir && $(MAKE)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在配方中调用“make”的行之前使用$(MAKE)和放置 a+具有相同的效果。

    使用 MAKE 变量与在配方行的开头使用“+”字符具有相同的效果。

  3. 只有当您明确输入MAKE配方时,魔法才会发生。如果不是这种情况,请使用+.

    仅当 MAKE 变量直接出现在配方中时才启用此特殊功能:如果 MAKE 变量是通过扩展另一个变量引用的,则它不适用。在后一种情况下,您必须使用“+”标记来获得这些特殊效果。