xref: /freebsd/share/mk/jobs.mk (revision 40b9b299)
1# $Id: jobs.mk,v 1.14 2023/09/11 16:52:44 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
81JOB_MAX_C ?= 1.33C
82JOB_MAX ?= ${JOB_MAX_C}
83.endif
84JOB_MAX ?= 8
85JOB_ARGS += -j${JOB_MAX}
86.endif
87
88# we need to reset .MAKE.LEVEL to 0 so that
89# build orchestration works as expected (DIRDEPS_BUILD)
90${.TARGETS:M*-jobs}:
91	@${NEWLOG} ${JOB_NEWLOG_ARGS} ${JOB_LOG}
92	@echo "${TIME_STAMP} Start ${.TARGET:S,-jobs,,} ${JOB_ARGS} ${JOB_LOG_START} log=${JOB_LOG}" | tee ${JOB_LOG}
93	@cd ${.CURDIR} && env MAKELEVEL=0 \
94	${.MAKE} ${JOB_ARGS} _TARGETS=${.TARGET:S,-jobs,,} ${.TARGET:S,-jobs,,} >> ${JOB_LOG} 2>&1
95
96.endif
97
98.END: _build_finish
99.ERROR: _build_failed
100
101_build_finish:  .NOMETA
102	@echo "${TIME_STAMP} Finished ${.TARGETS} seconds=`expr ${now_utc} - ${start_utc}`"
103
104_build_failed: .NOMETA
105	@echo "${TIME_STAMP} Failed ${.TARGETS} seconds=`expr ${now_utc} - ${start_utc}`"
106