aboutsummaryrefslogtreecommitdiff
path: root/mk/dirdeps-cache-update.mk
blob: eb992e936eb8fb3bac083143963978012ebaa47d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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