summaryrefslogtreecommitdiff
path: root/mk/dirdeps-cache-update.mk
diff options
context:
space:
mode:
Diffstat (limited to 'mk/dirdeps-cache-update.mk')
-rw-r--r--mk/dirdeps-cache-update.mk179
1 files changed, 179 insertions, 0 deletions
diff --git a/mk/dirdeps-cache-update.mk b/mk/dirdeps-cache-update.mk
new file mode 100644
index 000000000000..eb992e936eb8
--- /dev/null
+++ b/mk/dirdeps-cache-update.mk
@@ -0,0 +1,179 @@
+# $Id: dirdeps-cache-update.mk,v 1.21 2020/08/19 17:51:53 sjg Exp $
+#
+# @(#) Copyright (c) 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 deals with the updating of STATIC_DIRDEPS_CACHE.
+# Some targets are so huge that computing dirdeps takes a significant
+# amount of time. For such targets a STATIC_DIRDEPS_CACHE can make
+# sense.
+#
+# If the target is represented by targets/pseudo/production
+# it's normal DIRDEPS would be in
+# targets/pseudo/production/Makefile.depend
+# and STATIC_DIRDEPS_CACHE would be
+# targets/pseudo/production/Makefile.dirdeps.cache
+# which is simply initialized by copying dirdeps.cache.production
+# from $OBJTOP
+#
+# When dirdeps-targets.mk is initializing DIRDEPS it will look for
+# Makefile.dirdeps.cache and unless told not to
+# (MK_STATIC_DIRDEPS_CACHE=no) will use it as DIRDEPS_CACHE.
+#
+# If MK_STATIC_DIRDEPS_CACHE_UPDATE is "yes", then this makefile
+# comes into play.
+#
+# We usually get included from local.dirdeps.mk
+# as well as Makefile.depend of RELDIR with a static Makefile.dirdeps.cache
+#
+# If we see that STATIC_DIRDEPS_CACHE is in use, we need to hook a
+# cache-update target into the build to regenerate dirdeps.cache
+# in parallel with the rest of the build.
+# If MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE is "yes" we update
+# STATIC_DIRDEPS_CACHE as soon as the update is ready,
+# otherwise it will be done at the end of the build.
+#
+# If STATIC_DIRDEPS_CACHE is not in use, but a DIRDEPS_CACHE is,
+# then we need do nothing except export STATIC_DIRDEPS_CACHE and
+# DYNAMIC_DIRDEPS_CACHE for use when we are include during the visit
+# to the ultimate target (targets/pseudo/production).
+#
+# Regardless of which happens, when included at .MAKE.LEVEL > 0
+# for a target other than cache-update we simply copy
+# DYNAMIC_DIRDEPS_CACHE to STATIC_DIRDEPS_CACHE with some optional
+# filtering.
+#
+# If we are included for the target cache-update we take care of
+# running dirdeps.mk again to generate the DYNAMIC_DIRDEPS_CACHE.
+#
+
+.if !target(_${.PARSEFILE}_)
+_${.PARSEFILE}_: .NOTMAIN
+
+STATIC_CACHE_SED += \
+ -e '/Autogenerated/s,-.*,- edit with care!,' \
+ -e '/cache-update/d'
+
+STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT ?= \
+ { echo Saving ${DYNAMIC_DIRDEPS_CACHE} as ${STATIC_DIRDEPS_CACHE}; \
+ sed ${STATIC_CACHE_SED} ${DYNAMIC_DIRDEPS_CACHE} > ${STATIC_DIRDEPS_CACHE}; }
+.endif
+
+.if ${MK_DIRDEPS_CACHE:Uno} == "yes"
+.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes"
+.if ${_debug_reldir:U0} || ${DEBUG_DIRDEPS:U:Mcache*} != ""
+_debug_cache = 1
+.else
+_debug_cache = 0
+.endif
+
+.if ${.MAKE.LEVEL} == 0 && !make(cache-update)
+
+.if ${_debug_cache}
+.info ${MK_STATIC_DIRDEPS_CACHE_UPDATE MK_STATIC_DIRDEPS_CACHE MK_DIRDEPS_CACHE DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
+.endif
+
+.if ${MK_STATIC_DIRDEPS_CACHE} == "yes" && defined(STATIC_DIRDEPS_CACHE) && exists(${STATIC_DIRDEPS_CACHE})
+.if !make(dirdeps)
+# We are using static cache and this is the only look we will get.
+# We want to generate an updated cache while we build
+# so need to hook cache-update to dirdeps now.
+# Note: we are running as a sibling to dirdeps-cached,
+# attempting to do this in that context is problematic.
+
+# One of these should exist - to actually kick off the cache generation
+.for d in ${STATIC_DIRDEPS_CACHE:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H:H}/cache-update
+.if exists($d)
+cache_update_dirdep ?= $d.${TARGET_SPEC}
+.endif
+.endfor
+.if !target(${cache_update_dirdep})
+dirdeps: ${cache_update_dirdep}
+${cache_update_dirdep}: _DIRDEP_USE
+DYNAMIC_DIRDEPS_CACHE := ${OBJTOP}/dirdeps.cache.${STATIC_DIRDEPS_CACHE:H:T}-update
+.export DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE
+.endif
+.endif # make(dirdeps)
+.endif # MK_*
+
+.endif # .MAKE.LEVEL 0
+
+.if ${.MAKE.LEVEL} > 0 && ${.CURDIR:T} == "cache-update"
+# we are the background update shim
+
+.if ${_debug_cache}
+.info level ${.MAKE.LEVEL}: ${MK_DIRDEPS_CACHE DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
+.endif
+
+all: cache-build
+cache-build: .META
+ @set -x; MAKELEVEL=0 \
+ ${.MAKE} -C ${SRCTOP} -f ${RELDIR}/Makefile cache-update \
+ -DWITHOUT_STATIC_DIRDEPS_CACHE_UPDATE
+
+.endif # cache-update
+
+.elif ${.MAKE.LEVEL} == 0 && make(cache-update) && !target(cache-update)
+# we were invoked above
+# we just leverage dirdeps.mk
+BUILD_DIRDEPS_TARGETS := ${STATIC_DIRDEPS_CACHE:H:T}
+DIRDEPS := ${STATIC_DIRDEPS_CACHE:H:S,^${SRCTOP}/,,}.${TARGET_SPEC}
+DIRDEPS_CACHE := ${DYNAMIC_DIRDEPS_CACHE}
+
+.if ${DEBUG_DIRDEPS:U:Mcache*} != ""
+.info level 0: ${MK_DIRDEPS_CACHE DIRDEPS_CACHE DIRDEPS:L:@v@$v=${$v}@}
+.endif
+
+# so cache-built below can check on us
+x!= echo; echo ${.MAKE.PID} > ${DIRDEPS_CACHE}.new.pid
+
+cache-update: ${DIRDEPS_CACHE}
+ @rm -f ${DIRDEPS_CACHE}.new.pid
+.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "yes"
+ ${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
+.endif
+
+all:
+
+.include <dirdeps.mk>
+
+.endif # MK_STATIC_DIRDEPS_CACHE_UPDATE
+.endif # MK_DIRDEPS_CACHE
+
+.if ${.MAKE.LEVEL} > 0 && ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes" && \
+ ${STATIC_DIRDEPS_CACHE:Uno:H} == "${SRCTOP}/${RELDIR}"
+.if !defined(DYNAMIC_DIRDEPS_CACHE)
+all:
+.else
+# This is the easy bit, time to save the cache
+
+all: cache-update
+
+# ensure the cache update is completed
+cache-built:
+ @test -s ${DYNAMIC_DIRDEPS_CACHE}.new || exit 0; \
+ pid=`cat ${DYNAMIC_DIRDEPS_CACHE}.new.pid 2> /dev/null`; \
+ test $${pid:-0} -gt 1 || exit 0; \
+ echo "Waiting for $$pid to finish ${DYNAMIC_DIRDEPS_CACHE} ..."; \
+ while 'kill' -0 $$pid; do sleep 30; done > /dev/null 2>&1
+
+cache-update: cache-built
+.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "no"
+ @test ! -s ${DYNAMIC_DIRDEPS_CACHE} || \
+ ${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
+.endif
+
+.endif
+.endif