自动为多核机器设置作业(-j)标志?

我在一个拥有大量内核的机器上有一个Makefile,但是编译我的项目时似乎总是忘记写-jX ,并且它比预期的要长。

有什么办法可以通过环境variables或其他持久化configuration文件来设置-j标志,这样make就可以在这台机器上自动执行多个作业?

看来MAKEFLAGS环境variables可以传递每个make运行的标志(至less对于GNU make来说)。 我自己也没有太多的运气,但可以使用-l而不是-j来自动运行尽可能多的作业,而这些作业适合于可用核心的数量。

我假设你正在使用Linux。 这是从我的~/.bashrc

 # parallel make export NUMCPUS=`grep -c '^processor' /proc/cpuinfo` alias pmake='time nice make -j$NUMCPUS --load-average=$NUMCPUS' 

样本用法

 samm@host src> echo $NUMCPUS 8 samm@host src> pmake 

成为time nice make -j8 --load-average=8

为了回答你把这个问题放到一个Makefile ,我觉得把这个逻辑遍布在我的Makefiles上是不现实的。 把它放到顶层Makefile中也不是一个好的解决scheme,因为我经常从子目录构build,并且希望并行构build它们。 但是,如果你有一个相当平坦的源代码层次结构,它可能适合你。

正如Jeremiah Willcock所说,使用MAKEFLAGS ,但是这里是如何做到的:

 export MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)" 

或者你可以像这样设置一个固定值:

 export MAKEFLAGS="-j 8" 

如果你真的想要提高性能,你应该使用ccache ,在你的Makefile添加如下内容:

 CCACHE_EXISTS := $(shell ccache -V) ifdef CCACHE_EXISTS CC := ccache $(CC) CXX := ccache $(CXX) endif 

我通常在我的bash脚本中如下所示:

 make -j$(nproc) 

您可以添加一行到您的生成文件类似于以下内容:

 NUMJOBS=${NUMJOBS:-" -j4 "} 

然后在规则中添加${NUMJOBS}行,或将其添加到另一个Makefile var(如MAKEFLAGS )中。 这将使用NUMJOBS envvar(如果存在); 如果没有,则自动使用-j4 。 您可以调整或重命名为您的口味。

(注:就个人而言,我宁愿默认设置为-j1"" ,特别是如果要分配给其他人,因为虽然我也有多个内核,但是我在许多不同的平台上编译,能够使用-jX设置。)

脚本中不会扩展别名 。 最好创build一个单独的make脚本并将其放置到$PATH目录之一中:

 #!/bin/sh if [ -f /proc/cpuinfo ]; then CPUS=`grep processor /proc/cpuinfo | wc -l` else CPUS=1 fi /usr/bin/make -j`expr $CPUS + 1` "$@" 

直到去年的某个时候,你可以在你的makefile中做这个:(GNU make testing)

 MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES) 

(其中NUM_PPROCS根据这里的许多其他答案之一计算或设置)并且,砰! 你有多进程的build设。

鉴于这已经停止工作,我可以想到的最好的事情是这样的,makefile调用自己,但与-jX-lX

 # add parallelism equal to number of cores every time. # it seems that adding -jX to MAKEFLAGS directly doesn't work any more. # included some "random" strings to ensure uniqueness ifneq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done) NUM_CORES ?= $(shell grep -c "vendor_id" /proc/cpuinfo) MAKEFLAGS +=" -j$(NUM_CORES) -l$(NUM_CORES) " # for the default target case parallel_wrapper_default_target_anthsqjkshbeohcbmeuthnoethoaeou: $(MAKE) PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB=done # catches everything else % : $(MAKE) $@ PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB=done # the match for this else is at the end of the file else ##### rest of makefile here ##### all: ... ... other_target: ... ... ##### etc. ##### endif 

在使用所有CPU核心的Ubuntu 16.4上:

 export MAKEFLAGS='-j$(nproc)' 

要么

 export MAKEFLAGS='-j 2' 

我只会放

 alias make='make -j' 

~/.profile~/.bashrc

根据手册 :

如果在'-j'选项之后没有看起来像整数,那么作业槽的数量没有限制。