1# $Id: jobs.mk,v 1.20 2025/08/09 22:42:24 sjg Exp $ 2# 3# @(#) Copyright (c) 2012-2025, Simon J. Gerraty 4# 5# SPDX-License-Identifier: BSD-2-Clause 6# 7# Please send copies of changes and bug-fixes to: 8# sjg@crufty.net 9# 10 11# This makefile is used by top-level makefile. 12# With the following: 13# 14# .if make(*-jobs) 15# .include <jobs.mk> 16# .endif 17# 18# 19# Then if you do: 20# 21# mk target-jobs 22# 23# We will run: 24# 25# ${MAKE} -j${JOB_MAX} target > ${JOB_LOGDIR}/target.log 2>&1 26# 27# JOB_MAX should be something like 1.2 - 1.5 times the number of 28# available CPUs. 29# If bmake sets .MAKE.JOBS.C=yes we can use -jC and 30# JOB_MAX defaults to JOB_MAX_C (default 1.33C). 31# Otherwise we use 8. 32# 33 34now_utc ?= ${%s:L:localtime} 35.if !defined(start_utc) 36start_utc := ${now_utc} 37.endif 38 39.if make(*-jobs) 40.info ${.newline}${TIME_STAMP} Start ${.TARGETS} 41 42JOB_LOGDIR ?= ${SRCTOP:H} 43JOB_LOG = ${JOB_LOGDIR}/${.TARGET:S,-jobs,,:S,/,_,g}.log 44JOB_LOG_GENS ?= 4 45# we like to rotate logs 46.if empty(NEWLOG_SH) 47.for d in ${.SYSPATH:U${.PARSEDIR}:@x@$x $x/scripts@} 48.if exists($d/newlog.sh) 49NEWLOG_SH := $d/newlog.sh 50.if ${MAKE_VERSION} > 20220924 51.break 52.endif 53.endif 54.endfor 55.if empty(NEWLOG_SH) 56.ifdef M_whence 57NEWLOG_SH := ${newlog.sh:L:${M_whence}} 58.else 59NEWLOG_SH := ${(type newlog.sh) 2> /dev/null:L:sh:M/*} 60.endif 61.endif 62.endif 63.if !empty(NEWLOG_SH) && exists(${NEWLOG_SH}) 64NEWLOG := ${.SHELL:Ush} ${NEWLOG_SH} 65JOB_NEWLOG_ARGS ?= -S -n ${JOB_LOG_GENS} 66.else 67NEWLOG = : 68.endif 69 70.if ${.MAKE.JOBS:U0} > 0 71JOB_MAX = ${.MAKE.JOBS} 72.else 73# This should be derrived from number of cpu's 74.if ${.MAKE.JOBS.C:Uno} == "yes" 75# 1.2 - 1.5 times nCPU works well on most machines that support -jC 76# if the factor is floating point, the C suffix isn't needed 77JOB_MAX_C ?= 1.33 78JOB_MAX ?= ${JOB_MAX_C} 79.endif 80JOB_MAX ?= 8 81JOB_ARGS += -j${JOB_MAX} 82.endif 83 84# we need to reset .MAKE.LEVEL to 0 so that 85# build orchestration works as expected (DIRDEPS_BUILD) 86${.TARGETS:M*-jobs}: 87 @${NEWLOG} ${JOB_NEWLOG_ARGS} ${JOB_LOG} 88 @echo "${TIME_STAMP} Start ${.TARGET:S,-jobs,,} ${JOB_ARGS} ${JOB_LOG_START} log=${JOB_LOG}" | tee ${JOB_LOG} 89 @cd ${.CURDIR} && env MAKELEVEL=0 \ 90 ${.MAKE} ${JOB_ARGS} _TARGETS=${.TARGET:S,-jobs,,} ${.TARGET:S,-jobs,,} >> ${JOB_LOG} 2>&1 91 92.endif 93 94.END: _build_finish 95.ERROR: _build_failed 96 97_build_finish: .NOMETA 98 @echo "${TIME_STAMP} Finished ${.TARGETS} seconds=`expr ${now_utc} - ${start_utc}`" 99 100_build_failed: .NOMETA 101 @echo "${TIME_STAMP} Failed ${.TARGETS} seconds=`expr ${now_utc} - ${start_utc}`" 102