diff --git a/share/mk/dirdeps-targets.mk b/share/mk/dirdeps-targets.mk
index 6201efe1e402..821ae50e3ffa 100644
--- a/share/mk/dirdeps-targets.mk
+++ b/share/mk/dirdeps-targets.mk
@@ -1,172 +1,173 @@
 # RCSid:
-#       $Id: dirdeps-targets.mk,v 1.24 2020/12/11 18:15:43 sjg Exp $
+#       $Id: dirdeps-targets.mk,v 1.25 2023/05/11 05:07:28 sjg Exp $
 #
 #       @(#) Copyright (c) 2019-2020 Simon J. Gerraty
 #
 #       This file is provided in the hope that it will
 #       be of use.  There is absolutely NO WARRANTY.
 #       Permission to copy, redistribute or otherwise
 #       use this file is hereby granted provided that
 #       the above copyright notice and this notice are
 #       left intact.
 #
 #       Please send copies of changes and bug-fixes to:
 #       sjg@crufty.net
 #
 
 ##
 # This makefile is used to set initial DIRDEPS for top-level build
 # targets.
 #
 # The basic idea is that we have a list of directories in
 # DIRDEPS_TARGETS_DIRS which are relative to SRCTOP.
 # When asked to make 'foo' we look for any directory named 'foo'
 # under DIRDEPS_TARGETS_DIRS.
 # We then search those dirs for any Makefile.depend*
 # Finally we select any that match conditions like REQUESTED_MACHINE
 # or TARGET_SPEC and initialize DIRDEPS accordingly.
 #
 # We will check each of the initial DIRDEPS for Makefile.dirdeps.options
 # and include any found.
 # This makes it feasible to tweak options like MK_DIRDEPS_CACHE
 # for a specific target.
 #
 # If MK_STATIC_DIRDEPS_CACHE is defined we will check if the
 # initial DIRDEPS has a static cache (Makefile.dirdeps.cache).
 # This only makes sense for seriously expensive targets.
 #
 
 .if ${.MAKE.LEVEL} == 0
 # pickup customizations
 .-include <local.dirdeps-targets.mk>
 
 # for DIRDEPS_BUILD this is how we prime the pump
 # include . to allow any directory to work as a target
 DIRDEPS_TARGETS_DIRS ?= targets targets/pseudo
 # these prefixes can modify how we behave
 # they need to be stripped when looking for target dirs
 DIRDEPS_TARGETS_PREFIX_LIST ?= pkg- build-
 
 # some .TARGETS need filtering
 DIRDEPS_TARGETS_FILTER += Nall
 
 # matching target dirs if any
 tdirs := ${.TARGETS:${DIRDEPS_TARGETS_FILTER:ts:}:${DIRDEPS_TARGETS_PREFIX_LIST:@p@S,^$p,,@:ts:}:@t@${DIRDEPS_TARGETS_DIRS:@d@$d/$t@}@:@d@${exists(${SRCTOP}/$d):?$d:}@}
 
 .if !empty(DEBUG_DIRDEPS_TARGETS)
 .info tdirs=${tdirs}
 .endif
 
 .if !empty(tdirs)
 # some things we know we want to ignore
 DIRDEPS_TARGETS_SKIP_LIST += \
 	*~ \
 	*.bak \
 	*.inc \
 	*.old \
 	*.options \
 	*.orig \
 	*.rej \
 
 # the list of MACHINEs we consider
 DIRDEPS_TARGETS_MACHINE_LIST += \
 	${ALL_MACHINE_LIST:U} \
 	${PSEUDO_MACHINE_LIST:Ucommon host host32} \
 	${TARGET_MACHINE_LIST}
 
 DIRDEPS_TARGETS_MACHINE_LIST := ${DIRDEPS_TARGETS_MACHINE_LIST:O:u}
 
 # raw Makefile.depend* list
 tdeps != 'cd' ${SRCTOP} && 'ls' -1 ${tdirs:O:u:@d@$d/${.MAKE.DEPENDFILE_PREFIX}*@:S,^./,,} 2> /dev/null; echo
 .if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
 .info tdeps=${tdeps}
 .endif
 # remove things we know we don't want
 tdeps := ${tdeps:${DIRDEPS_TARGETS_SKIP_LIST:${M_ListToSkip}}}
 .if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
 .info tdeps=${tdeps}
 .endif
 
 # plain entries (no qualifiers) these apply to any TARGET_SPEC
 ptdeps := ${tdeps:M*${.MAKE.DEPENDFILE_PREFIX}:S,/${.MAKE.DEPENDFILE_PREFIX},,}
 
 # MACHINE qualified entries
 mqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
 
 tqtdeps =
 .if ${TARGET_SPEC_VARS:[#]} > 1
 # TARGET_SPEC qualified entries
 .if !empty(TARGET_SPEC_LIST)
 # we have a list of valid TARGET_SPECS; use it
 tqtdeps := ${TARGET_SPEC_LIST:U:O:u:@t@${tdeps:M*.$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
 .else
 # do we have a list of valid tuple members for at least
 # the last tupple element? if so match on that
 TARGET_SPEC_LAST_LIST ?= ${${TARGET_SPEC_VARS:[-1]}_LIST}
 .if !empty(TARGET_SPEC_LAST_LIST)
 tqtdeps := ${TARGET_SPEC_LAST_LIST:U:O:u:@t@${tdeps:M*,$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
 .else
 # this is sub-optimal match MACHINE,
 tqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m,*}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
 .endif
 .endif
 .endif
 
 # now work out what we want in DIRDEPS
+DIRDEPS = ${ptdeps}
 .if empty(REQUESTED_MACHINE)
 # we want them all just as found
-DIRDEPS = ${ptdeps} ${mqtdeps} ${tqtdeps}
+DIRDEPS += ${mqtdeps} ${tqtdeps}
 .else
 # we only want those that match REQUESTED_MACHINE/REQUESTED_TARGET_SPEC
 # or REQUESTED_TARGET_SPEC (TARGET_SPEC)
-DIRDEPS = \
-	${ptdeps:@d@$d.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC:U${REQUESTED_MACHINE}}}@} \
+DIRDEPS += \
 	${mqtdeps:M*.${REQUESTED_MACHINE}} \
-	${tqtdeps:M*.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC}}}
+	${tqtdeps:M*.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC}}} \
+
 .endif
 # clean up
 DIRDEPS := ${DIRDEPS:O:u}
 
 .if !empty(DEBUG_DIRDEPS_TARGETS)
 .for x in tdeps ptdeps mqtdeps tqtdeps DIRDEPS
 .info $x=${$x}
 .endfor
 .endif
 .endif
 # if we got DIRDEPS get to work
 .if !empty(DIRDEPS)
 DIRDEPS.dirs := ${DIRDEPS:S,^,${SRCTOP}/,:@d@${exists($d):?$d:${d:R}}@}
 # some targets want to tweak options we might want to process now
 .for m in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.options,}
 .-include <$m>
 .endfor
 .if defined(MK_STATIC_DIRDEPS_CACHE)
 # some targets are very expensive to compute dirdeps for
 # so we may have a static cache
 .for c in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.cache,}
 .if exists($c)
 STATIC_DIRDEPS_CACHE ?= $c
 .if ${MK_STATIC_DIRDEPS_CACHE} == "yes"
 DIRDEPS_CACHE ?= $c
 MK_DIRDEPS_CACHE = yes
 .endif
 .endif
 .endfor
 .if defined(STATIC_DIRDEPS_CACHE)
 .export STATIC_DIRDEPS_CACHE
 .endif
 .endif
 
 # allow a top-level makefile to do other stuff
 # before including dirdeps.mk
 .if ${MK_DIRDEPS_TARGETS_INCLUDE_DIRDEPS:Uyes} == "yes"
 .include <dirdeps.mk>
 .endif
 
 DIRDEPS_TARGETS_SKIP += all clean* destroy*
 
 .for t in ${.TARGETS:${DIRDEPS_TARGETS_SKIP:${M_ListToSkip}}}
 $t: dirdeps
 .endfor
 .endif
 .endif
diff --git a/share/mk/jobs.mk b/share/mk/jobs.mk
index 62fe9eeae030..0643e6481082 100644
--- a/share/mk/jobs.mk
+++ b/share/mk/jobs.mk
@@ -1,97 +1,105 @@
-# $Id: jobs.mk,v 1.9 2023/04/27 18:10:27 sjg Exp $
+# $Id: jobs.mk,v 1.14 2023/09/11 16:52:44 sjg Exp $
 #
 #	@(#) Copyright (c) 2012-2023, Simon J. Gerraty
 #
 #	This file is provided in the hope that it will
 #	be of use.  There is absolutely NO WARRANTY.
 #	Permission to copy, redistribute or otherwise
 #	use this file is hereby granted provided that
 #	the above copyright notice and this notice are
 #	left intact.
 #
 #	Please send copies of changes and bug-fixes to:
 #	sjg@crufty.net
 #
 
 # This makefile is used by top-level makefile.
 # With the following:
 #
 #	.if make(*-jobs)
 #	.include <jobs.mk>
 #	.endif
 #
 # 
 # Then if you do:
 #
 #	mk target-jobs
 #
 # We will run:
 #
 #	${MAKE} -j${JOB_MAX} target > ${JOB_LOGDIR}/target.log 2>&1
 #
-# JOB_MAX defaults to 8 but should normally be derrived based on the
-# number of cpus available.  The wrapper script 'mk' makes that easy.
+# JOB_MAX should be something like 1.2 - 1.5 times the number of
+# available CPUs.
+# If bmake sets .MAKE.JOBS.C=yes we can use -jC and
+# JOB_MAX defaults to JOB_MAX_C (default 1.33C).
+# Otherwise we use 8.
 #
 
-now_utc ?= ${%s:L:gmtime}
+now_utc ?= ${%s:L:localtime}
 .if !defined(start_utc)
 start_utc := ${now_utc}
 .endif
 
 .if make(*-jobs)
 .info ${.newline}${TIME_STAMP} Start ${.TARGETS}
 
 JOB_LOGDIR ?= ${SRCTOP:H}
 JOB_LOG = ${JOB_LOGDIR}/${.TARGET:S,-jobs,,:S,/,_,g}.log
 JOB_LOG_GENS ?= 4
 # we like to rotate logs
 .if empty(NEWLOG_SH)
 .for d in ${.SYSPATH:U${.PARSEDIR}:@x@$x $x/scripts@}
 .if exists($d/newlog.sh)
 NEWLOG_SH := $d/newlog.sh
 .if ${MAKE_VERSION} > 20220924
 .break
 .endif
 .endif
 .endfor
 .if empty(NEWLOG_SH)
 .ifdef M_whence
 NEWLOG_SH := ${newlog.sh:L:${M_whence}}
 .else
 NEWLOG_SH := ${(type newlog.sh) 2> /dev/null:L:sh:M/*}
 .endif
 .endif
 .endif
 .if !empty(NEWLOG_SH) && exists(${NEWLOG_SH})
 NEWLOG := sh ${NEWLOG_SH}
 JOB_NEWLOG_ARGS ?= -S -n ${JOB_LOG_GENS}
 .else
 NEWLOG = :
 .endif
 
 .if ${.MAKE.JOBS:U0} > 0
-JOB_MAX= ${.MAKE.JOBS}
+JOB_MAX = ${.MAKE.JOBS}
 .else
 # This should be derrived from number of cpu's
-JOB_MAX?= 8
-JOB_ARGS+= -j${JOB_MAX}
+.if ${.MAKE.JOBS.C:Uno} == "yes"
+# 1.2 - 1.5 times nCPU works well on most machines that support -jC
+JOB_MAX_C ?= 1.33C
+JOB_MAX ?= ${JOB_MAX_C}
+.endif
+JOB_MAX ?= 8
+JOB_ARGS += -j${JOB_MAX}
 .endif
 
-# we need to reset .MAKE.LEVEL to 0 do that
+# we need to reset .MAKE.LEVEL to 0 so that
 # build orchestration works as expected (DIRDEPS_BUILD)
 ${.TARGETS:M*-jobs}:
 	@${NEWLOG} ${JOB_NEWLOG_ARGS} ${JOB_LOG}
 	@echo "${TIME_STAMP} Start ${.TARGET:S,-jobs,,} ${JOB_ARGS} ${JOB_LOG_START} log=${JOB_LOG}" | tee ${JOB_LOG}
 	@cd ${.CURDIR} && env MAKELEVEL=0 \
 	${.MAKE} ${JOB_ARGS} _TARGETS=${.TARGET:S,-jobs,,} ${.TARGET:S,-jobs,,} >> ${JOB_LOG} 2>&1
 
 .endif
 
 .END: _build_finish
 .ERROR: _build_failed
 
 _build_finish:  .NOMETA
 	@echo "${TIME_STAMP} Finished ${.TARGETS} seconds=`expr ${now_utc} - ${start_utc}`"
 
 _build_failed: .NOMETA
 	@echo "${TIME_STAMP} Failed ${.TARGETS} seconds=`expr ${now_utc} - ${start_utc}`"
diff --git a/share/mk/local.sys.mk b/share/mk/local.sys.mk
index 2f684ba0975c..59b1a7c14a7c 100644
--- a/share/mk/local.sys.mk
+++ b/share/mk/local.sys.mk
@@ -1,118 +1,98 @@
 
 .if !target(_${_this}_)
 _${_this}_: .NOTMAIN
 
 .if ${MK_DIRDEPS_BUILD} == "yes" || ${MK_META_MODE} == "yes"
 
 # Not in the below list as it may make sense for non-meta mode
 # eventually.  meta.sys.mk (DIRDEPS_BUILD) also already adds these in.
 .if ${MK_DIRDEPS_BUILD} == "no" && ${MK_META_MODE} == "yes"
 MAKE_PRINT_VAR_ON_ERROR += \
 	.ERROR_TARGET \
 	.ERROR_META_FILE \
 	.MAKE.LEVEL \
 	MAKEFILE \
 	.MAKE.MODE
 .endif
 
 _ERROR_CMD_EXEC=	${sed -n '/^CMD/s,^CMD \(.*\),\1;,p' ${.ERROR_META_FILE}:L:sh}
 _ERROR_CMD=		${!empty(.ERROR_META_FILE):?${_ERROR_CMD_EXEC}:.PHONY}
 MAKE_PRINT_VAR_ON_ERROR+= \
 	_ERROR_CMD \
 	.CURDIR \
 	.MAKE \
 	.OBJDIR \
 	.TARGETS \
 	CPUTYPE \
 	DESTDIR \
 	LD_LIBRARY_PATH \
 	MACHINE \
 	MACHINE_ARCH \
 	MACHINE_CPUARCH \
 	MAKEOBJDIRPREFIX \
 	MAKESYSPATH \
 	MAKE_VERSION \
 	PATH \
 	SRCTOP \
 	OBJTOP \
 	${MAKE_PRINT_VAR_ON_ERROR_XTRAS}
 
 # Meta mode may rebuild targets that then fail. The next build won't detect
 # the meta mode change. Not all targets have a 'rm ${.TARGET}' in them
 # so force it.
 .DELETE_ON_ERROR:
 
 .if ${.MAKE.LEVEL} > 0
 MAKE_PRINT_VAR_ON_ERROR += .MAKE.MAKEFILES .PATH
 .endif
 .endif
 
 .if !empty(.OBJDIR)
 OBJTOP?= ${.OBJDIR:S,${.CURDIR},,}${SRCTOP}
 .endif
 
 .if !empty(LIBDIR)
 _PREMK_LIBDIR:=	${LIBDIR}
 .endif
 
 .include "src.sys.mk"
 .-include <site.sys.mk>
 
-.if make(*-jobs) && empty(JOB_MAX)
-# provide a reasonable? default for JOB_MAX based on ncpu
-JOB_MAX_FACTOR?= 1.33
-NPROC?= ${(type nproc || true) 2> /dev/null:L:sh:M/*:[1]}
-NPROC:= ${NPROC}
-.if !empty(NPROC)
-ncpu!= ${NPROC}
-.elif ${.MAKE.OS:NDarwin:NFreeBSD} == ""
-ncpu!= sysctl -n hw.ncpu
-.endif
-.if ${ncpu:U0} > 1
-.if ${JOB_MAX_FACTOR} == 1
-JOB_MAX:= ${ncpu}
-.else
-jm!= echo ${ncpu} \* ${JOB_MAX_FACTOR} | bc
-JOB_MAX:= ${jm:R}
-.endif
-.endif
-.endif
-
 # this will be set via local.meta.sys.env.mk if appropriate
 MK_host_egacy?= no
 
 .if ${.MAKE.MODE:Mmeta*} != ""
 # we can afford to use cookies to prevent some targets
 # re-running needlessly but only when using filemon.
 # Targets that should support the meta mode cookie handling should just be
 # added to META_TARGETS.  If bsd.sys.mk cannot be included then ${META_DEPS}
 # should be added as a target dependency as well.  Otherwise the target
 # is added to in bsd.sys.mk since it comes last.
 .if ${.MAKE.MODE:Mnofilemon} == ""
 # Prepend .OBJDIR if not already there.
 _META_COOKIE_COND=	"${.TARGET:M${.OBJDIR}/*}" == ""
 _META_COOKIE_DEFAULT=	${${_META_COOKIE_COND}:?${.OBJDIR}/${.TARGET}:${.TARGET}}
 # Use the default if COOKIE.${.TARGET} is not defined.
 META_COOKIE=		${COOKIE.${.TARGET}:U${_META_COOKIE_DEFAULT}}
 META_COOKIE_RM=		@rm -f ${META_COOKIE}
 META_COOKIE_TOUCH=	@touch ${META_COOKIE}
 CLEANFILES+=		${META_TARGETS}
 _meta_dep_before:	.USEBEFORE .NOTMAIN
 	${META_COOKIE_RM}
 _meta_dep_after:	.USE .NOTMAIN
 	${META_COOKIE_TOUCH}
 # Attach this to a target to allow it to benefit from meta mode's
 # not rerunning a command if it doesn't need to be considering its
 # metafile/filemon-tracked dependencies.
 META_DEPS=	_meta_dep_before _meta_dep_after .META
 .endif
 .else
 # some targets need to be .PHONY - but not in meta mode
 META_NOPHONY=	.PHONY
 .endif
 META_NOPHONY?=
 META_COOKIE_RM?=
 META_COOKIE_TOUCH?=
 META_DEPS+=	${META_NOPHONY}
 
 .endif
diff --git a/share/mk/meta.autodep.mk b/share/mk/meta.autodep.mk
index cd08ac3b3520..6785d2ebf874 100644
--- a/share/mk/meta.autodep.mk
+++ b/share/mk/meta.autodep.mk
@@ -1,329 +1,334 @@
-# $Id: meta.autodep.mk,v 1.56 2022/09/09 17:44:29 sjg Exp $
+# $Id: meta.autodep.mk,v 1.59 2023/08/19 17:35:32 sjg Exp $
 
 #
 #	@(#) Copyright (c) 2010, Simon J. Gerraty
 #
 #	This file is provided in the hope that it will
 #	be of use.  There is absolutely NO WARRANTY.
 #	Permission to copy, redistribute or otherwise
 #	use this file is hereby granted provided that
 #	the above copyright notice and this notice are
 #	left intact.
 #
 #	Please send copies of changes and bug-fixes to:
 #	sjg@crufty.net
 #
 
 _this ?= ${.PARSEFILE}
 .if !target(__${_this}__)
 __${_this}__: .NOTMAIN
 
 .-include <local.autodep.mk>
 
 PICO?= .pico
 
 .if defined(SRCS)
 .if ${MAKE_VERSION:U0} >= 20211212
 OBJ_EXTENSIONS += ${.SUFFIXES:M*o}
 .else
 # it would be nice to be able to query .SUFFIXES
 OBJ_EXTENSIONS += .o .po .lo ${PICO}
 .endif
 
 # explicit dependencies help short-circuit .SUFFIX searches
 SRCS_DEP_FILTER+= N*.[hly]
 .for s in ${SRCS:${SRCS_DEP_FILTER:O:u:ts:}}
 .for e in ${OBJ_EXTENSIONS:O:u}
 .if !target(${s:T:R}$e)
 ${s:T:R}$e: $s
 .endif
 .endfor
 .endfor
 .endif
 
 .if make(gendirdeps)
 # you are supposed to know what you are doing!
 UPDATE_DEPENDFILE = yes
 .elif !empty(.TARGETS) && !make(all)
 # do not update the *depend* files
 # unless we are building the entire directory or the default target.
 # NO means don't update .depend - or Makefile.depend*
 # no means update .depend but not Makefile.depend*
 UPDATE_DEPENDFILE = NO
 .elif ${.MAKEFLAGS:M-k} != ""
 # it is a bad idea to update anything
 UPDATE_DEPENDFILE = NO
 .endif
 
 _CURDIR ?= ${.CURDIR}
 _OBJDIR ?= ${.OBJDIR}
 _OBJTOP ?= ${OBJTOP}
 _OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
 _DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
 
 .if ${.MAKE.LEVEL} > 0
 # do not allow auto update if we ever built this dir without filemon
 NO_FILEMON_COOKIE = .nofilemon
 CLEANFILES += ${NO_FILEMON_COOKIE}
 .if ${.MAKE.MODE:Uno:Mnofilemon} != ""
 UPDATE_DEPENDFILE = NO
 all: ${NO_FILEMON_COOKIE}
 ${NO_FILEMON_COOKIE}: .NOMETA
 	@echo UPDATE_DEPENDFILE=NO > ${.TARGET}
 .elif exists(${NO_FILEMON_COOKIE})
 UPDATE_DEPENDFILE = NO
 .warning ${RELDIR} built with nofilemon; UPDATE_DEPENDFILE=NO
 .endif
 .endif
 
 .if ${.MAKE.LEVEL} == 0
 UPDATE_DEPENDFILE = NO
 .endif
 .if !exists(${_DEPENDFILE})
 _bootstrap_dirdeps = yes
 .endif
 _bootstrap_dirdeps ?= no
 UPDATE_DEPENDFILE ?= yes
 
 .if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
 .info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
 .endif
 
 .if !empty(XMAKE_META_FILE)
 .if exists(${.OBJDIR}/${XMAKE_META_FILE})
 # we cannot get accurate dependencies from an update build
 UPDATE_DEPENDFILE = NO
 .else
 META_XTRAS += ${XMAKE_META_FILE}
 .endif
 .endif
 
 .if ${_bootstrap_dirdeps} == "yes" || exists(${_DEPENDFILE})
 # if it isn't supposed to be touched by us the Makefile should have
 # UPDATE_DEPENDFILE = no
 WANT_UPDATE_DEPENDFILE ?= yes
 .endif
 
 .if ${WANT_UPDATE_DEPENDFILE:Uno:tl} != "no"
 .if ${.MAKE.MODE:Uno:Mmeta*} == "" || ${.MAKE.MODE:Uno:M*read*} != ""
 UPDATE_DEPENDFILE = no
 .endif
 
 .if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
 .info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
 .endif
 
 .if ${UPDATE_DEPENDFILE:tl} == "yes"
 # sometimes we want .meta files generated to aid debugging/error detection
 # but do not want to consider them for dependencies
 # for example the result of running configure
 # just make sure this is not empty
 META_FILE_FILTER ?= N.meta
 # never consider these
 META_FILE_FILTER += Ndirdeps.cache*
 
 .if !empty(DPADD)
 # if we have any non-libs in DPADD,
 # they probably need to be paid attention to
 .if !empty(DPLIBS)
 FORCE_DPADD = ${DPADD:${DPLIBS:${M_ListToSkip}}:${DPADD_LAST:${M_ListToSkip}}}
 .else
 _nonlibs := ${DPADD:T:Nlib*:N*include}
 .if !empty(_nonlibs)
 FORCE_DPADD += ${_nonlibs:@x@${DPADD:M*/$x}@}
 .endif
 .endif
 .endif
 
 .if !make(gendirdeps)
 .END:	gendirdeps
 .endif
 
+.if ${LOCAL_DEPENDS_GUARD:U} == "no"
+.depend:
+.endif
+
 # if we don't have OBJS, then .depend isn't useful
 .if !target(.depend) && (!empty(OBJS) || ${.ALLTARGETS:M*.o} != "")
 # some makefiles and/or targets contain
 # circular dependencies if you dig too deep
 # (as meta mode is apt to do)
 # so we provide a means of suppressing them.
 # the input to the loop below is target: dependency
 # with just one dependency per line.
 # Also some targets are not really local, or use random names.
 # Use local.autodep.mk to provide local additions!
 SUPPRESS_DEPEND += \
 	${SB:S,/,_,g}* \
 	*:y.tab.c \
 	*.c:*.c \
 	*.h:*.h
 
 .NOPATH:	.depend
 # we use ${.MAKE.META.CREATED} to trigger an update but
 # we process using ${.MAKE.META.FILES}
 # the double $$ defers initial evaluation
 # if necessary, we fake .po dependencies, just so the result
 # in Makefile.depend* is stable
 # The current objdir may be referred to in various ways
 OBJDIR_REFS += ${.OBJDIR} ${.OBJDIR:tA} ${_OBJDIR} ${RELOBJTOP}/${RELDIR}
 _depend = .depend
 # it would be nice to be able to get .SUFFIXES as ${.SUFFIXES}
 # we actually only care about the .SUFFIXES of files that might be
 # generated by tools like yacc.
 .if ${MAKE_VERSION:U0} >= 20211212
 DEPEND_SUFFIXES += ${.SUFFIXES:N.sh:N*[0-9aFfglopmnrSsty]}
 .else
 DEPEND_SUFFIXES += .c .h .cpp .hpp .cxx .hxx .cc .hh
 .endif
 .depend: .NOMETA $${.MAKE.META.CREATED} ${_this}
 	@echo "Updating $@: ${.OODATE:T:[1..8]}"
 	@${EGREP:Uegrep} -i '^R .*\.(${DEPEND_SUFFIXES:tl:O:u:S,^.,,:ts|})$$' /dev/null ${.MAKE.META.FILES:T:O:u:${META_FILE_FILTER:ts:}:M*o.meta} | \
 	sed -e 's, \./, ,${OBJDIR_REFS:O:u:@d@;s, $d/, ,@};/\//d' \
 		-e 's,^\([^/][^/]*\).meta...[0-9]* ,\1: ,' | \
 	sort -u | \
 	while read t d; do \
 		case "$$d:" in $$t) continue;; esac; \
 		case "$$t$$d" in ${SUPPRESS_DEPEND:U.:O:u:ts|}) continue;; esac; \
 		echo $$t $$d; \
 	done > $@.${.MAKE.PID}
 	@case "${.MAKE.META.FILES:T:M*.po.*}" in \
 	*.po.*) mv $@.${.MAKE.PID} $@;; \
 	*) { cat $@.${.MAKE.PID}; \
 	sed ${OBJ_EXTENSIONS:N.o:N.po:@o@-e 's,\$o:,.o:,'@} \
 		-e 's,\.o:,.po:,' $@.${.MAKE.PID}; } | sort -u > $@; \
 	rm -f $@.${.MAKE.PID};; \
 	esac
 .else
 # make sure this exists
 .depend:
 # do _not_ assume that .depend is in any fit state for us to use
 CAT_DEPEND = /dev/null
 .if ${.MAKE.LEVEL} > 0
 .export CAT_DEPEND
 .endif
 _depend =
 .endif
 
 .if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
 .info ${_DEPENDFILE:S,${SRCTOP}/,,} _depend=${_depend}
 .endif
 
 .if ${UPDATE_DEPENDFILE} == "yes"
-gendirdeps:	${_DEPENDFILE}
+gendirdeps:	beforegendirdeps .WAIT ${_DEPENDFILE}
+beforegendirdeps:
 .endif
 
 .if !target(${_DEPENDFILE})
 .if ${_bootstrap_dirdeps} == "yes"
 # We are boot-strapping a new directory
 # Use DPADD to seed DIRDEPS
 .if !empty(DPADD)
 # anything which matches ${_OBJROOT}* but not ${_OBJTOP}*
 # needs to be qualified in DIRDEPS
 # The pseudo machine "host" is used for HOST_TARGET
 DIRDEPS += \
 	${DPADD:M${_OBJTOP}*:H:C,${_OBJTOP}[^/]*/,,:N.:O:u} \
 	${DPADD:M${_OBJROOT}*:N${_OBJTOP}*:N${STAGE_ROOT:U${_OBJTOP}}/*:H:S,${_OBJROOT},,:C,^([^/]+)/(.*),\2.\1,:S,${HOST_TARGET}$,host,:N.*:O:u}
 
 .endif
 .endif
 
 _gendirdeps_mutex =
 .if defined(NEED_GENDIRDEPS_MUTEX)
 # If a src dir gets built with multiple object dirs,
 # we need a mutex.  Obviously, this is best avoided.
 # Note if .MAKE.DEPENDFILE is common for all ${MACHINE}
 # you either need to mutex, or ensure only one machine builds at a time!
 # lockf is an example of a suitable tool
 LOCKF ?= /usr/bin/lockf
 .if exists(${LOCKF})
 GENDIRDEPS_MUTEXER ?= ${LOCKF} -k
 .endif
 .if empty(GENDIRDEPS_MUTEXER)
 .error NEED_GENDIRDEPS_MUTEX defined, but GENDIRDEPS_MUTEXER not set
 .else
 _gendirdeps_mutex = ${GENDIRDEPS_MUTEXER} ${GENDIRDEPS_MUTEX:U${_CURDIR}/Makefile}
 .endif
 .endif
 
 # If we have META_XTRAS we most likely did not create them
 # but we need to behave as if we did.
 # Avoid adding glob patterns to .MAKE.META.CREATED though.
 .MAKE.META.CREATED += ${META_XTRAS:N*\**:O:u}
 
 .if make(gendirdeps)
 META_FILES = *.meta
 .elif ${OPTIMIZE_OBJECT_META_FILES:Uno:tl} == "no"
 META_FILES = ${.MAKE.META.FILES:T:N.depend*:O:u}
 .else
 # if we have 1000's of .o.meta, ${PICO}.meta etc we need only look at one set
 # it is left as an exercise for the reader to work out what this does
 META_FILES = ${.MAKE.META.FILES:T:N.depend*:N*o.meta:O:u} \
 	${.MAKE.META.FILES:T:M*.${.MAKE.META.FILES:M*o.meta:R:E:O:u:[1]}.meta:O:u}
 .endif
 
 .if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
 .info ${_DEPENDFILE:S,${SRCTOP}/,,}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} xtras=${META_XTRAS}
 .endif
 
 .if ${.MAKE.LEVEL} > 0
 .if ${UPDATE_DEPENDFILE} == "yes"
 .-include <${.CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.options>
 .endif
 .if !empty(GENDIRDEPS_FILTER)
 .export GENDIRDEPS_FILTER
 .endif
 # export to avoid blowing command line limit
 META_FILES := ${META_XTRAS:U:O:u} ${META_FILES:U:T:O:u:${META_FILE_FILTER:ts:}}
 .export META_FILES
 .endif
 
 # we might have .../ in MAKESYSPATH
 _makesyspath:= ${_PARSEDIR}
 ${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk  ${META2DEPS} $${.MAKE.META.CREATED}
 	@echo Checking $@: ${.OODATE:T:[1..8]}
 	@(cd . && ${GENDIRDEPS_ENV} \
 	SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS:O:u}' \
 	DPADD='${FORCE_DPADD:O:u}' ${_gendirdeps_mutex} \
 	MAKESYSPATH=${_makesyspath} \
 	${.MAKE} -f gendirdeps.mk RELDIR=${RELDIR} _DEPENDFILE=${_DEPENDFILE})
 	@test -s $@ && touch $@; :
 .endif
 
 .endif
 .endif
 
 .if ${_bootstrap_dirdeps} == "yes"
 DIRDEPS+= ${RELDIR}.${TARGET_SPEC:U${MACHINE}}
 # make sure this is included at least once
 .include <dirdeps.mk>
 .else
 ${_DEPENDFILE}: .PRECIOUS
 .endif
 
 CLEANFILES += *.meta filemon.* *.db
 
 # these make it easy to gather some stats
-now_utc = ${%s:L:gmtime}
+now_utc = ${%s:L:localtime}
 start_utc := ${now_utc}
 
 meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \
 	created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}}
 
 .if !target(_reldir_finish)
 #.END: _reldir_finish
 .if target(gendirdeps)
 _reldir_finish: gendirdeps
 .endif
 _reldir_finish: .NOMETA
 	@echo "${TIME_STAMP} Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
 .endif
 
 .if !target(_reldir_failed)
 #.ERROR: _reldir_failed
 _reldir_failed: .NOMETA
 	@echo "${TIME_STAMP} Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
 .endif
 
 .if !defined(WITHOUT_META_STATS) && ${.MAKE.LEVEL} > 0
 .END: _reldir_finish
 .ERROR: _reldir_failed
 .endif
 
 .endif
diff --git a/share/mk/meta.subdir.mk b/share/mk/meta.subdir.mk
index 39cf875d6b77..d9caae4edbcc 100644
--- a/share/mk/meta.subdir.mk
+++ b/share/mk/meta.subdir.mk
@@ -1,79 +1,79 @@
-# $Id: meta.subdir.mk,v 1.12 2020/08/19 17:51:53 sjg Exp $
+# $Id: meta.subdir.mk,v 1.13 2021/01/05 22:24:37 sjg Exp $
 
 #
 #	@(#) Copyright (c) 2010, Simon J. Gerraty
 #
 #	This file is provided in the hope that it will
 #	be of use.  There is absolutely NO WARRANTY.
 #	Permission to copy, redistribute or otherwise
 #	use this file is hereby granted provided that
 #	the above copyright notice and this notice are
 #	left intact.
 #
 #	Please send copies of changes and bug-fixes to:
 #	sjg@crufty.net
 #
 
 .if !defined(NO_SUBDIR) && !empty(SUBDIR)
 .if make(destroy*) || make(clean*)
 .MAKE.MODE = compat
-.if !commands(destroy)
+.if !commands(obj)
 .-include <bsd.obj.mk>
 .endif
 .elif ${.MAKE.LEVEL} == 0
 
 .MAIN: all
 
 .if !exists(${.CURDIR}/${.MAKE.DEPENDFILE:T}) || make(gendirdeps)
 # start with this
 DIRDEPS = ${SUBDIR:N.WAIT:O:u:@d@${RELDIR}/$d@}
 
 .if make(gendirdeps)
 .include <meta.autodep.mk>
 .else
 # this is the cunning bit
 # actually it is probably a bit risky
 # since we may pickup subdirs which are not relevant
 # the alternative is a walk through the tree though
 # which is difficult without a sub-make.
 
 .if defined(BOOTSTRAP_DEPENDFILES)
 _find_name = ${.MAKE.MAKEFILE_PREFERENCE:@m@-o -name $m@:S,^-o,,1}
 DIRDEPS = ${_subdeps:H:O:u:@d@${RELDIR}/$d@}
 .elif ${.MAKE.DEPENDFILE:E} == ${MACHINE} && defined(ALL_MACHINES)
 # we want to find Makefile.depend.* ie for all machines
 # and turn the dirs into dir.<machine>
 _find_name = -name '${.MAKE.DEPENDFILE:T:R}*'
 DIRDEPS = ${_subdeps:O:u:${NIgnoreFiles}:@d@${RELDIR}/${d:H}.${d:E}@:S,.${MACHINE}$,,:S,.depend$,,}
 .else
 # much simpler
 _find_name = -name ${.MAKE.DEPENDFILE:T}
 .if ${.MAKE.DEPENDFILE:E} == ${MACHINE}
 _find_name += -o -name ${.MAKE.DEPENDFILE:T:R}
 .endif
 DIRDEPS = ${_subdeps:H:O:u:@d@${RELDIR}/$d@}
 .endif
 
 _subdeps != cd ${.CURDIR} && \
 	find ${SUBDIR:N.WAIT} -type f \( ${_find_name} \) -print -o \
 	-name .svn -prune 2> /dev/null; echo
 
 .if empty(_subdeps)
 DIRDEPS =
 .else
 # clean up if needed
 DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIRDEPS_FILTER:Uu}}
 .endif
 # we just dealt with it, if we leave it defined,
 # dirdeps.mk will compute some interesting combinations.
 .undef ALL_MACHINES
 
 DEP_RELDIR = ${RELDIR}
 .include <dirdeps.mk>
 .endif
 .endif
 .else
 all: .PHONY
 .endif
 
 .endif