我的机器上有一个包含大量核心的Makefile,但在编译项目时我似乎总是忘记编写-jX
并且它需要的时间比它应该的长。
有什么方法可以通过环境变量或其他一些持久配置文件设置-j
标志,这样make会在这台机器上自动并行执行多个作业吗?
答案 0 :(得分:36)
我假设您正在使用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
的具体问题,我觉得在我的Makefile上撒上这个逻辑并不实际。把它放到顶级Makefile也不是一个很好的解决方案,因为我经常从子目录构建并希望并行构建它们。但是,如果您有一个相当平坦的源层次结构,它可能适合您。
答案 1 :(得分:33)
MAKEFLAGS
环境变量似乎可以传递属于每个make
运行的标志(至少对于GNU make)。我自己也没有太多运气,但可以使用-l
而不是-j
来自动运行适合您可用核心数量的多个作业。
答案 2 :(得分:26)
正如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
答案 3 :(得分:15)
我通常在我的bash脚本中执行以下操作:
make -j$(nproc)
答案 4 :(得分:6)
您可以在Makefile中添加一行,类似于以下内容:
NUMJOBS=${NUMJOBS:-" -j4 "}
然后在规则中添加${NUMJOBS}
行,或将其添加到另一个Makefile
var(如MAKEFLAGS
)中。这将使用NUMJOBS envvar(如果存在);如果没有,则自动使用-j4
。您可以根据自己的喜好调整或重命名。
(注意:个人而言,我更喜欢默认为-j1
或""
,特别是如果要将其分发给其他人,因为虽然我也有多个核心,但我会编译很多不同的平台,往往忘记 dis - -jX
设置。)
答案 5 :(得分:6)
Aliases are not expanded inside scripts。最好创建一个单独的menuconfig
脚本并将其放入make
目录之一:
$PATH
答案 6 :(得分:2)
在2016年的某个时候,你可以把它放在你的makefile中:( GNU make tests)
MAKEFLAGS += "-j$(NUM_CORES) -l$(NUM_CORES)
(其中NUM_PPROCS
是根据这里的许多其他答案之一计算或设定的)而且,bam!你正在进行多进程建设。
鉴于这已经停止工作,我能想到的最好的事情是,makefile调用自身,但使用-jX
和-lX
。
ifeq ($(PARALELL_WRAPPER_ABXCOEOEKCOEBMQJKHTOEUB),done)
all: ...
...
other_target: ...
...
else
# add parallelism equal to number of cores every time.
# "random" strings are to ensure uniqueness
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
endif
答案 7 :(得分:2)
在使用所有CPU内核的Ubuntu 16.4上:
export MAKEFLAGS='-j$(nproc)'
或
export MAKEFLAGS='-j 2'
答案 8 :(得分:1)
在Makefile的开头:
MAKEFLAGS+="j"
任何版本的GNU Make before 4.2都不会使用数字参数。 4.2 you can do之后:
MAKEFLAGS+="j2"
对于早于4.2的版本,如果碰巧某些作业内存不足,则可以使用util-linux-ng中的flock
一次只运行一个作业。例如,ImageMagick中的convert
实用程序将使用它在用于optimize images according to Google's recommendations时可以获得的所有资源,因此没有必要让它并行运行。
%.min.jpg: %.jpg
@flock --wait 600 Makefile convert $< -sampling-factor 4:2:0 -strip $@
设置较长的等待时间非常重要,因为make仍将并行运行大多数这些命令。因此,等待时间必须是最深的队列执行时间。如果您有八个核心,并且需要一分钟来优化八个大图像,则必须将等待时间设置为至少一分钟。
有数百个核心和巨大的图像,上面设置的六百秒可能还不够。
答案 9 :(得分:-1)