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