如何在Makefile中指定默认的作业数量?

7

Consider the following contrived Makefile:

.PHONY: all one two
SLEEP = 2

all: one two

one two:
    @sleep $(SLEEP)
    @echo $@

make -j 2 all运行可以同时完成两项工作,而且时间与单独执行任意一项工作的时间相同,这是因为它们同时进行。如果您控制make的调用并记得每次都这样做,那么效果非常好,但如果您只控制Makefile,则不适用。
设置MAKEFLAGS环境变量也可以控制此功能:
$ export MAKEFLAGS="-j 2"
$ make all

然而,在Makefile中设置这个值似乎没有效果:
MAKEFLAGS = -j 2

失败。

export MAKEFLAGS="-j 2"

失败。

设置 JOBS 也似乎没有任何作用。有没有办法控制在 Makefile 中运行的默认作业数?

注意,我知道我可以使用一个虚拟配方并从其中调用递归 make,但这会引入大量混乱,因为我需要为整个可能的目标设置它,并且我正在处理不一定与递归相容的包含 Makefile。


除非你递归调用make,否则没有其他方法,唉。 (但是包装一个递归调用并不是那么糟糕,尽管有些棘手:只需使用“eval”为MAKECMDGOALS中的所有内容定义虚假目标,并使这些目标依赖于包装的调用目标。而且像“-q”之类的东西会破坏,除非你愿意深入分析“MAKEFLAGS”等等。) - Michael Livshin
或者使用一个包装脚本... - Michael Livshin
@MichaelLivshin 这些评论可以作为一个答案。 - Caleb
问题在于当make完成解析makefile时,它已经配置了其环境,包括设置作业服务器等。因此,在makefile中出现的MAKEFLAGS更改并不能总是影响当前make实例的所有内容。我不确定为什么必须这样,但这就是今天的情况。 - MadScientist
1个回答

16

在 GNU Make 4.3(于2020年1月19日发布)之前,这是不可能的。在新闻文件中有这个条目:

  • Makefile现在可以在它们的MAKEFLAGS变量中指定“-j”选项,这将使make启用并行模式。

现在应该可以解决问题了(当然,您也可以硬编码一个值):

MAKEFLAGS := --jobs=$(shell nproc)

您可能希望将其与缓冲命令输出并一起输出结果的选项相结合(而不是可能混杂在一起的行):

MAKEFLAGS += --output-sync=target

有没有办法我们可以使用环境变量来完成同样的工作? - xiaojueguan
@xiaojueguan 确定,设置MAKEFLAGS,它会在从Makefiles或CLI参数中找到的任何内容被修改之前从主机环境中读取。 - Caleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接