xref: /freebsd/contrib/bmake/mk/dirdeps-cache-update.mk (revision 96474d2a3fa895fb9636183403fc8ca7ccf60216)
1# $Id: dirdeps-cache-update.mk,v 1.21 2020/08/19 17:51:53 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)
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
102.if !target(${cache_update_dirdep})
103dirdeps: ${cache_update_dirdep}
104${cache_update_dirdep}: _DIRDEP_USE
105DYNAMIC_DIRDEPS_CACHE := ${OBJTOP}/dirdeps.cache.${STATIC_DIRDEPS_CACHE:H:T}-update
106.export DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE
107.endif
108.endif	# make(dirdeps)
109.endif	# MK_*
110
111.endif	# .MAKE.LEVEL 0
112
113.if ${.MAKE.LEVEL} > 0 && ${.CURDIR:T} == "cache-update"
114# we are the background update shim
115
116.if ${_debug_cache}
117.info level ${.MAKE.LEVEL}: ${MK_DIRDEPS_CACHE DYNAMIC_DIRDEPS_CACHE STATIC_DIRDEPS_CACHE:L:@v@$v=${$v}@}
118.endif
119
120all: cache-build
121cache-build: .META
122	@set -x; MAKELEVEL=0 \
123	${.MAKE} -C ${SRCTOP} -f ${RELDIR}/Makefile cache-update \
124	-DWITHOUT_STATIC_DIRDEPS_CACHE_UPDATE
125
126.endif	# cache-update
127
128.elif ${.MAKE.LEVEL} == 0 && make(cache-update) && !target(cache-update)
129# we were invoked above
130# we just leverage dirdeps.mk
131BUILD_DIRDEPS_TARGETS := ${STATIC_DIRDEPS_CACHE:H:T}
132DIRDEPS := ${STATIC_DIRDEPS_CACHE:H:S,^${SRCTOP}/,,}.${TARGET_SPEC}
133DIRDEPS_CACHE := ${DYNAMIC_DIRDEPS_CACHE}
134
135.if ${DEBUG_DIRDEPS:U:Mcache*} != ""
136.info level 0: ${MK_DIRDEPS_CACHE DIRDEPS_CACHE DIRDEPS:L:@v@$v=${$v}@}
137.endif
138
139# so cache-built below can check on us
140x!= echo; echo ${.MAKE.PID} > ${DIRDEPS_CACHE}.new.pid
141
142cache-update: ${DIRDEPS_CACHE}
143	@rm -f ${DIRDEPS_CACHE}.new.pid
144.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "yes"
145	${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
146.endif
147
148all:
149
150.include <dirdeps.mk>
151
152.endif	# MK_STATIC_DIRDEPS_CACHE_UPDATE
153.endif	# MK_DIRDEPS_CACHE
154
155.if ${.MAKE.LEVEL} > 0 && ${MK_STATIC_DIRDEPS_CACHE_UPDATE:Uno} == "yes" && \
156	${STATIC_DIRDEPS_CACHE:Uno:H} == "${SRCTOP}/${RELDIR}"
157.if !defined(DYNAMIC_DIRDEPS_CACHE)
158all:
159.else
160# This is the easy bit, time to save the cache
161
162all: cache-update
163
164# ensure the cache update is completed
165cache-built:
166	@test -s ${DYNAMIC_DIRDEPS_CACHE}.new || exit 0; \
167	pid=`cat ${DYNAMIC_DIRDEPS_CACHE}.new.pid 2> /dev/null`; \
168	test $${pid:-0} -gt 1 || exit 0; \
169	echo "Waiting for $$pid to finish ${DYNAMIC_DIRDEPS_CACHE} ..."; \
170	while 'kill' -0 $$pid; do sleep 30; done > /dev/null 2>&1
171
172cache-update: cache-built
173.if ${MK_STATIC_DIRDEPS_CACHE_UPDATE_IMMEDIATE:Uno} == "no"
174	@test ! -s ${DYNAMIC_DIRDEPS_CACHE} || \
175	${STATIC_DIRDEPS_CACHE_UPDATE_SCRIPT}
176.endif
177
178.endif
179.endif
180