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