1# $Id: dirdeps-cache-update.mk,v 1.22 2020/09/10 00:14:38 sjg Exp $ 2# 3# @(#) Copyright (c) 2020, 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## 17# 18# This makefile deals with the updating of STATIC_DIRDEPS_CACHE. 19# Some targets are so huge that computing dirdeps takes a significant 20# amount of time. For such targets a STATIC_DIRDEPS_CACHE can make 21# sense. 22# 23# If the target is represented by targets/pseudo/production 24# it's normal DIRDEPS would be in 25# targets/pseudo/production/Makefile.depend 26# and STATIC_DIRDEPS_CACHE would be 27# targets/pseudo/production/Makefile.dirdeps.cache 28# which is simply initialized by copying dirdeps.cache.production 29# from $OBJTOP 30# 31# When dirdeps-targets.mk is initializing DIRDEPS it will look for 32# Makefile.dirdeps.cache and unless told not to 33# (MK_STATIC_DIRDEPS_CACHE=no) will use it as DIRDEPS_CACHE. 34# 35# If MK_STATIC_DIRDEPS_CACHE_UPDATE is "yes", then this makefile 36# comes into play. 37# 38# We usually get included from local.dirdeps.mk 39# as well as Makefile.depend of RELDIR with a static Makefile.dirdeps.cache 40# 41# If we see that STATIC_DIRDEPS_CACHE is in use, we need to hook a 42# cache-update target into the build to regenerate dirdeps.cache 43# in parallel with the rest of the build. 44# If MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE is "yes" we update 45# STATIC_DIRDEPS_CACHE as soon as the update is ready, 46# otherwise it will be done at the end of the build. 47# 48# If STATIC_DIRDEPS_CACHE is not in use, but a DIRDEPS_CACHE is, 49# then we need do nothing except export STATIC_DIRDEPS_CACHE and 50# DYNAMIC_DIRDEPS_CACHE for use when we are include during the visit 51# to the ultimate target (targets/pseudo/production). 52# 53# Regardless of which happens, when included at .MAKE.LEVEL > 0 54# for a target other than cache-update we simply copy 55# DYNAMIC_DIRDEPS_CACHE to STATIC_DIRDEPS_CACHE with some optional 56# filtering. 57# 58# If we are included for the target cache-update we take care of 59# running dirdeps.mk again to generate the DYNAMIC_DIRDEPS_CACHE. 60# 61 62.if !target(_${.PARSEFILE}_) 63_${.PARSEFILE}_: .NOTMAIN 64 65STATIC_CACHE_SED += \ 66 -e '/Autogenerated/s,-.*,- edit with care!,' \ 67 -e '/cache-update/d' 68 69STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT ?= \ 70 { echo Saving ${DYNAMIC_DIRDEPS_CACHE} as ${STATIC_DIRDEPS_CACHE}; \ 71 sed ${STATIC_CACHE_SED} ${DYNAMIC_DIRDEPS_CACHE} > ${STATIC_DIRDEPS_CACHE}; } 72.endif 73 74.if ${MK_DIRDEPS_CACHE:Uno} == "yes" 75.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes" 76.if ${_debug_reldir:U0} || ${DEBUG_DIRDEPS:U:Mcache*} != "" 77_debug_cache = 1 78.else 79_debug_cache = 0 80.endif 81 82.if ${.MAKE.LEVEL} == 0 && !make(cache-update) 83 84.if ${_debug_cache} 85.info ${MK_STATIC_DIRDEPS_CACHE_UPDATE MK_STATIC_DIRDEPS_CACHE MK_DIRDEPS_CACHE DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@} 86.endif 87 88.if ${MK_STATIC_DIRDEPS_CACHE} == "yes" && defined(STATIC_DIRDEPS_CACHE) && exists(${STATIC_DIRDEPS_CACHE}) 89.if !make(dirdeps) && !target(cache_update_dirdep) 90# We are using static cache and this is the only look we will get. 91# We want to generate an updated cache while we build 92# so need to hook cache-update to dirdeps now. 93# Note: we are running as a sibling to dirdeps-cached, 94# attempting to do this in that context is problematic. 95 96# One of these should exist - to actually kick off the cache generation 97.for d in ${STATIC_DIRDEPS_CACHE:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H}/cache-update ${STATIC_DIRDEPS_CACHE:H:H:H}/cache-update 98.if exists($d) 99cache_update_dirdep ?= $d.${TARGET_SPEC} 100.endif 101.endfor 102dirdeps cache_update_dirdep: ${cache_update_dirdep} 103${cache_update_dirdep}: _DIRDEP_USE 104DYNAMIC_DIRDEPS_CACHE := ${OBJTOP}/dirdeps.cache.${STATIC_DIRDEPS_CACHE:H:T}-update 105.export DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE 106.endif # make(dirdeps) 107.endif # MK_* 108 109.endif # .MAKE.LEVEL 0 110 111.if ${.MAKE.LEVEL} > 0 && ${.CURDIR:T} == "cache-update" 112# we are the background update shim 113 114.if ${_debug_cache} 115.info level ${.MAKE.LEVEL}: ${MK_DIRDEPS_CACHE DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@} 116.endif 117 118all: cache-build 119cache-build: .META 120 @set -x; MAKELEVEL=0 \ 121 ${.MAKE} -C ${SRCTOP} -f ${RELDIR}/Makefile cache-update \ 122 -DWITHOUT_STATIC_DIRDEPS_CACHE_UPDATE 123 124.endif # cache-update 125 126.elif ${.MAKE.LEVEL} == 0 && make(cache-update) && !target(cache-update) 127# we were invoked above 128# we just leverage dirdeps.mk 129BUILD_DIRDEPS_TARGETS := ${STATIC_DIRDEPS_CACHE:H:T} 130DIRDEPS := ${STATIC_DIRDEPS_CACHE:H:S,^${SRCTOP}/,,}.${TARGET_SPEC} 131DIRDEPS_CACHE := ${DYNAMIC_DIRDEPS_CACHE} 132 133.if ${DEBUG_DIRDEPS:U:Mcache*} != "" 134.info level 0: ${MK_DIRDEPS_CACHE DIRDEPS_CACHE DIRDEPS:L:@v@$v=${$v}@} 135.endif 136 137# so cache-built below can check on us 138x!= echo; echo ${.MAKE.PID} > ${DIRDEPS_CACHE}.new.pid 139 140cache-update: ${DIRDEPS_CACHE} 141 @rm -f ${DIRDEPS_CACHE}.new.pid 142.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "yes" 143 ${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT} 144.endif 145 146all: 147 148.include <dirdeps.mk> 149 150.endif # MK_STATIC_DIRDEPS_CACHE_UPDATE 151.endif # MK_DIRDEPS_CACHE 152 153.if ${.MAKE.LEVEL} > 0 && ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes" && \ 154 ${STATIC_DIRDEPS_CACHE:Uno:H} == "${SRCTOP}/${RELDIR}" 155.if !defined(DYNAMIC_DIRDEPS_CACHE) 156all: 157.else 158# This is the easy bit, time to save the cache 159 160all: cache-update 161 162# ensure the cache update is completed 163cache-built: 164 @test -s ${DYNAMIC_DIRDEPS_CACHE}.new || exit 0; \ 165 pid=`cat ${DYNAMIC_DIRDEPS_CACHE}.new.pid 2> /dev/null`; \ 166 test $${pid:-0} -gt 1 || exit 0; \ 167 echo "Waiting for $$pid to finish ${DYNAMIC_DIRDEPS_CACHE} ..."; \ 168 while 'kill' -0 $$pid; do sleep 30; done > /dev/null 2>&1 169 170cache-update: cache-built 171.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "no" 172 @test ! -s ${DYNAMIC_DIRDEPS_CACHE} || \ 173 ${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT} 174.endif 175 176.endif 177.endif 178