1321964Ssjg# $Id: meta.autodep.mk,v 1.45 2016/06/03 17:22:32 sjg Exp $
2246149Ssjg
3246149Ssjg#
4246149Ssjg#	@(#) Copyright (c) 2010, Simon J. Gerraty
5246149Ssjg#
6246149Ssjg#	This file is provided in the hope that it will
7246149Ssjg#	be of use.  There is absolutely NO WARRANTY.
8246149Ssjg#	Permission to copy, redistribute or otherwise
9246149Ssjg#	use this file is hereby granted provided that 
10246149Ssjg#	the above copyright notice and this notice are
11246149Ssjg#	left intact. 
12246149Ssjg#      
13246149Ssjg#	Please send copies of changes and bug-fixes to:
14246149Ssjg#	sjg@crufty.net
15246149Ssjg#
16246149Ssjg
17246149Ssjg_this ?= ${.PARSEFILE}
18246149Ssjg.if !target(__${_this}__)
19246149Ssjg__${_this}__: .NOTMAIN
20246149Ssjg
21321964Ssjg.-include <local.autodep.mk>
22246149Ssjg
23246149Ssjg.if defined(SRCS)
24246149Ssjg# it would be nice to be able to query .SUFFIXES
25246149SsjgOBJ_EXTENSIONS+= .o .po .lo .So
26246149Ssjg
27246149Ssjg# explicit dependencies help short-circuit .SUFFIX searches
28246149SsjgSRCS_DEP_FILTER+= N*.[hly]
29246149Ssjg.for s in ${SRCS:${SRCS_DEP_FILTER:O:u:ts:}}
30246149Ssjg.for e in ${OBJ_EXTENSIONS:O:u}
31246149Ssjg.if !target(${s:T:R}$e)
32246149Ssjg${s:T:R}$e: $s
33246149Ssjg.endif
34246149Ssjg.endfor
35246149Ssjg.endfor
36246149Ssjg.endif
37246149Ssjg
38246149Ssjg.if make(gendirdeps)
39246149Ssjg# you are supposed to know what you are doing!
40246149SsjgUPDATE_DEPENDFILE = yes
41246149Ssjg.elif !empty(.TARGETS) && !make(all)
42246149Ssjg# do not update the *depend* files 
43246149Ssjg# unless we are building the entire directory or the default target.
44246149Ssjg# NO means don't update .depend - or Makefile.depend*
45246149Ssjg# no means update .depend but not Makefile.depend*
46246149SsjgUPDATE_DEPENDFILE = NO
47246149Ssjg.elif ${.MAKEFLAGS:M-k} != ""
48246149Ssjg# it is a bad idea to update anything
49246149SsjgUPDATE_DEPENDFILE = NO
50246149Ssjg.endif
51246149Ssjg
52246149Ssjg_CURDIR ?= ${.CURDIR}
53292068Ssjg_OBJDIR ?= ${.OBJDIR}
54292068Ssjg_OBJTOP ?= ${OBJTOP}
55292068Ssjg_OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
56246149Ssjg_DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
57246149Ssjg
58321964Ssjg.if ${.MAKE.LEVEL} > 0 || ${BUILD_AT_LEVEL0:Uyes:tl} == "yes"
59321964Ssjg# do not allow auto update if we ever built this dir without filemon
60321964SsjgNO_FILEMON_COOKIE = .nofilemon
61321964SsjgCLEANFILES += ${NO_FILEMON_COOKIE}
62321964Ssjg.if ${.MAKE.MODE:Uno:Mnofilemon} != ""
63321964SsjgUPDATE_DEPENDFILE = NO
64321964Ssjgall: ${NO_FILEMON_COOKIE}
65321964Ssjg${NO_FILEMON_COOKIE}: .NOMETA
66321964Ssjg	@echo UPDATE_DEPENDFILE=NO > ${.TARGET}
67321964Ssjg.elif exists(${NO_FILEMON_COOKIE})
68321964SsjgUPDATE_DEPENDFILE = NO
69321964Ssjg.warning ${RELDIR} built with nofilemon; UPDATE_DEPENDFILE=NO
70321964Ssjg.endif
71321964Ssjg.endif
72321964Ssjg
73246149Ssjg.if ${.MAKE.LEVEL} == 0
74246149Ssjg.if ${BUILD_AT_LEVEL0:Uyes:tl} == "no"
75246149SsjgUPDATE_DEPENDFILE = NO
76246149Ssjg.endif
77246149Ssjg.endif
78246149Ssjg.if !exists(${_DEPENDFILE})
79246149Ssjg_bootstrap_dirdeps = yes
80246149Ssjg.endif
81246149Ssjg_bootstrap_dirdeps ?= no
82246149SsjgUPDATE_DEPENDFILE ?= yes
83246149Ssjg
84246149Ssjg.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
85246149Ssjg.info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
86246149Ssjg.endif
87246149Ssjg
88246149Ssjg.if !empty(XMAKE_META_FILE)
89246149Ssjg.if exists(${.OBJDIR}/${XMAKE_META_FILE})
90246149Ssjg# we cannot get accurate dependencies from an update build
91246149SsjgUPDATE_DEPENDFILE = NO
92246149Ssjg.else
93246149SsjgMETA_XTRAS += ${XMAKE_META_FILE}
94246149Ssjg.endif
95246149Ssjg.endif
96246149Ssjg
97246149Ssjg.if ${_bootstrap_dirdeps} == "yes" || exists(${_DEPENDFILE})
98246149Ssjg# if it isn't supposed to be touched by us the Makefile should have
99246149Ssjg# UPDATE_DEPENDFILE = no
100246149SsjgWANT_UPDATE_DEPENDFILE ?= yes
101246149Ssjg.endif
102246149Ssjg
103246149Ssjg.if ${WANT_UPDATE_DEPENDFILE:Uno:tl} != "no"
104321964Ssjg.if ${.MAKE.MODE:Uno:Mmeta*} == "" || ${.MAKE.MODE:Uno:M*read*} != ""
105246149SsjgUPDATE_DEPENDFILE = no
106246149Ssjg.endif
107246149Ssjg
108246149Ssjg.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
109246149Ssjg.info ${_DEPENDFILE:S,${SRCTOP}/,,} update=${UPDATE_DEPENDFILE}
110246149Ssjg.endif
111246149Ssjg
112246149Ssjg.if ${UPDATE_DEPENDFILE:tl} == "yes"
113246149Ssjg# sometimes we want .meta files generated to aid debugging/error detection
114246149Ssjg# but do not want to consider them for dependencies
115246149Ssjg# for example the result of running configure
116246149Ssjg# just make sure this is not empty
117246149SsjgMETA_FILE_FILTER ?= N.meta
118292068Ssjg# never consider these
119292068SsjgMETA_FILE_FILTER += Ndirdeps.cache*
120246149Ssjg
121246149Ssjg.if !empty(DPADD)
122246149Ssjg# if we have any non-libs in DPADD, 
123246149Ssjg# they probably need to be paid attention to
124246149Ssjg.if !empty(DPLIBS)
125246149SsjgFORCE_DPADD = ${DPADD:${DPLIBS:${M_ListToSkip}}:${DPADD_LAST:${M_ListToSkip}}}
126246149Ssjg.else
127246149Ssjg_nonlibs := ${DPADD:T:Nlib*:N*include}
128246149Ssjg.if !empty(_nonlibs)
129246149SsjgFORCE_DPADD += ${_nonlibs:@x@${DPADD:M*/$x}@}
130246149Ssjg.endif
131246149Ssjg.endif
132246149Ssjg.endif
133246149Ssjg
134246149Ssjg.if !make(gendirdeps)
135246149Ssjg.END:	gendirdeps
136246149Ssjg.endif
137246149Ssjg
138246149Ssjg# if we don't have OBJS, then .depend isn't useful
139246149Ssjg.if !target(.depend) && (!empty(OBJS) || ${.ALLTARGETS:M*.o} != "")
140246149Ssjg# some makefiles and/or targets contain
141246149Ssjg# circular dependencies if you dig too deep 
142246149Ssjg# (as meta mode is apt to do) 
143276305Sngie# so we provide a means of suppressing them.
144246149Ssjg# the input to the loop below is target: dependency
145246149Ssjg# with just one dependency per line.
146246149Ssjg# Also some targets are not really local, or use random names.
147246149Ssjg# Use local.autodep.mk to provide local additions!
148246149SsjgSUPPRESS_DEPEND += \
149246149Ssjg	${SB:S,/,_,g}* \
150246149Ssjg	*:y.tab.c \
151246149Ssjg	*.c:*.c \
152246149Ssjg	*.h:*.h
153246149Ssjg
154246149Ssjg.NOPATH:	.depend
155246149Ssjg# we use ${.MAKE.META.CREATED} to trigger an update but
156246149Ssjg# we process using ${.MAKE.META.FILES}
157246149Ssjg# the double $$ defers initial evaluation
158246149Ssjg# if necessary, we fake .po dependencies, just so the result 
159246149Ssjg# in Makefile.depend* is stable
160276305Sngie# The current objdir may be referred to in various ways
161246149SsjgOBJDIR_REFS += ${.OBJDIR} ${.OBJDIR:tA} ${_OBJDIR} ${RELOBJTOP}/${RELDIR}
162246149Ssjg_depend = .depend
163246149Ssjg# it would be nice to be able to get .SUFFIXES as ${.SUFFIXES}
164246149Ssjg# we actually only care about the .SUFFIXES of files that might be 
165246149Ssjg# generated by tools like yacc.
166246149SsjgDEPEND_SUFFIXES += .c .h .cpp .hpp .cxx .hxx .cc .hh
167246149Ssjg.depend: .NOMETA $${.MAKE.META.CREATED} ${_this}
168246149Ssjg	@echo "Updating $@: ${.OODATE:T:[1..8]}"
169246149Ssjg	@egrep -i '^R .*\.(${DEPEND_SUFFIXES:tl:O:u:S,^.,,:ts|})$$' /dev/null ${.MAKE.META.FILES:T:O:u:${META_FILE_FILTER:ts:}:M*o.meta} | \
170246149Ssjg	sed -e 's, \./, ,${OBJDIR_REFS:O:u:@d@;s, $d/, ,@};/\//d' \
171246149Ssjg		-e 's,^\([^/][^/]*\).meta...[0-9]* ,\1: ,' | \
172246149Ssjg	sort -u | \
173246149Ssjg	while read t d; do \
174246149Ssjg		case "$$d:" in $$t) continue;; esac; \
175246149Ssjg		case "$$t$$d" in ${SUPPRESS_DEPEND:U.:O:u:ts|}) continue;; esac; \
176246149Ssjg		echo $$t $$d; \
177246149Ssjg	done > $@.${.MAKE.PID}
178246149Ssjg	@case "${.MAKE.META.FILES:T:M*.po.*}" in \
179246149Ssjg	*.po.*) mv $@.${.MAKE.PID} $@;; \
180246149Ssjg	*) { cat $@.${.MAKE.PID}; \
181246149Ssjg	sed 's,\.So:,.o:,;s,\.o:,.po:,' $@.${.MAKE.PID}; } | sort -u > $@; \
182246149Ssjg	rm -f $@.${.MAKE.PID};; \
183246149Ssjg	esac
184246149Ssjg.else
185246149Ssjg# make sure this exists
186246149Ssjg.depend:
187246149Ssjg# do _not_ assume that .depend is in any fit state for us to use
188246149SsjgCAT_DEPEND = /dev/null
189246149Ssjg.if ${.MAKE.LEVEL} > 0
190246149Ssjg.export CAT_DEPEND
191246149Ssjg.endif
192246149Ssjg_depend =
193246149Ssjg.endif
194246149Ssjg
195246149Ssjg.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
196246149Ssjg.info ${_DEPENDFILE:S,${SRCTOP}/,,} _depend=${_depend}
197246149Ssjg.endif
198246149Ssjg
199276305Sngie.if ${UPDATE_DEPENDFILE} == "yes"
200246149Ssjggendirdeps:	${_DEPENDFILE}
201276305Sngie.endif
202246149Ssjg
203246149Ssjg.if !target(${_DEPENDFILE})
204246149Ssjg.if ${_bootstrap_dirdeps} == "yes"
205246149Ssjg# We are boot-strapping a new directory
206246149Ssjg# Use DPADD to seed DIRDEPS
207246149Ssjg.if !empty(DPADD)
208246149Ssjg# anything which matches ${_OBJROOT}* but not ${_OBJTOP}*
209246149Ssjg# needs to be qualified in DIRDEPS
210246149Ssjg# The pseudo machine "host" is used for HOST_TARGET
211292068SsjgDIRDEPS += \
212246149Ssjg	${DPADD:M${_OBJTOP}*:H:C,${_OBJTOP}[^/]*/,,:N.:O:u} \
213321964Ssjg	${DPADD:M${_OBJROOT}*:N${_OBJTOP}*:N${STAGE_ROOT:U${_OBJTOP}}/*:H:S,${_OBJROOT},,:C,^([^/]+)/(.*),\2.\1,:S,${HOST_TARGET}$,host,:N.*:O:u}
214246149Ssjg
215246149Ssjg.endif
216246149Ssjg.endif
217246149Ssjg
218246149Ssjg_gendirdeps_mutex =
219246149Ssjg.if defined(NEED_GENDIRDEPS_MUTEX)
220246149Ssjg# If a src dir gets built with multiple object dirs,
221246149Ssjg# we need a mutex.  Obviously, this is best avoided.
222246149Ssjg# Note if .MAKE.DEPENDFILE is common for all ${MACHINE}
223246149Ssjg# you either need to mutex, or ensure only one machine builds at a time!
224246149Ssjg# lockf is an example of a suitable tool
225246149SsjgLOCKF ?= /usr/bin/lockf
226246149Ssjg.if exists(${LOCKF})
227246149SsjgGENDIRDEPS_MUTEXER ?= ${LOCKF} -k
228246149Ssjg.endif
229246149Ssjg.if empty(GENDIRDEPS_MUTEXER)
230246149Ssjg.error NEED_GENDIRDEPS_MUTEX defined, but GENDIRDEPS_MUTEXER not set
231246149Ssjg.else
232246149Ssjg_gendirdeps_mutex = ${GENDIRDEPS_MUTEXER} ${GENDIRDEPS_MUTEX:U${_CURDIR}/Makefile}
233246149Ssjg.endif
234246149Ssjg.endif
235246149Ssjg
236246149Ssjg# If we have META_XTRAS we most likely did not create them
237246149Ssjg# but we need to behave as if we did.
238246149Ssjg# Avoid adding glob patterns to .MAKE.META.CREATED though.
239246149Ssjg.MAKE.META.CREATED += ${META_XTRAS:N*\**:O:u}
240246149Ssjg
241246149Ssjg.if make(gendirdeps)
242246149SsjgMETA_FILES = *.meta
243246149Ssjg.elif ${OPTIMIZE_OBJECT_META_FILES:Uno:tl} == "no"
244246149SsjgMETA_FILES = ${.MAKE.META.FILES:T:N.depend*:O:u}
245246149Ssjg.else
246246149Ssjg# if we have 1000's of .o.meta, .So.meta etc we need only look at one set
247246149Ssjg# it is left as an exercise for the reader to work out what this does
248246149SsjgMETA_FILES = ${.MAKE.META.FILES:T:N.depend*:N*o.meta:O:u} \
249246149Ssjg	${.MAKE.META.FILES:T:M*.${.MAKE.META.FILES:M*o.meta:R:E:O:u:[1]}.meta:O:u}
250246149Ssjg.endif
251246149Ssjg
252246149Ssjg.if ${DEBUG_AUTODEP:Uno:@m@${RELDIR:M$m}@} != ""
253246149Ssjg.info ${_DEPENDFILE:S,${SRCTOP}/,,}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} xtras=${META_XTRAS}
254246149Ssjg.endif
255246149Ssjg
256246149Ssjg.if ${.MAKE.LEVEL} > 0 && !empty(GENDIRDEPS_FILTER)
257246149Ssjg.export GENDIRDEPS_FILTER
258246149Ssjg.endif
259246149Ssjg
260246149Ssjg# we might have .../ in MAKESYSPATH
261246149Ssjg_makesyspath:= ${_PARSEDIR}
262246149Ssjg${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk  ${META2DEPS} $${.MAKE.META.CREATED}
263246149Ssjg	@echo Checking $@: ${.OODATE:T:[1..8]}
264246149Ssjg	@(cd . && \
265246149Ssjg	SKIP_GENDIRDEPS='${SKIP_GENDIRDEPS:O:u}' \
266246149Ssjg	DPADD='${FORCE_DPADD:O:u}' ${_gendirdeps_mutex} \
267246149Ssjg	MAKESYSPATH=${_makesyspath} \
268246149Ssjg	${.MAKE} -f gendirdeps.mk RELDIR=${RELDIR} _DEPENDFILE=${_DEPENDFILE} \
269321964Ssjg	META_FILES='${META_XTRAS:O:u} ${META_FILES:T:O:u:${META_FILE_FILTER:ts:}}')
270246149Ssjg	@test -s $@ && touch $@; :
271246149Ssjg.endif
272246149Ssjg
273246149Ssjg.endif
274246149Ssjg.endif
275246149Ssjg
276246149Ssjg.if ${_bootstrap_dirdeps} == "yes"
277292068Ssjg.if ${BUILD_AT_LEVEL0:Uno} == "no"
278292068SsjgDIRDEPS+= ${RELDIR}.${TARGET_SPEC:U${MACHINE}}
279292068Ssjg.endif
280246149Ssjg# make sure this is included at least once
281246149Ssjg.include <dirdeps.mk>
282246149Ssjg.else
283246149Ssjg${_DEPENDFILE}: .PRECIOUS
284246149Ssjg.endif
285246149Ssjg
286246149SsjgCLEANFILES += *.meta filemon.* *.db
287276305Sngie
288276305Sngie# these make it easy to gather some stats
289276305Sngienow_utc = ${%s:L:gmtime}
290276305Sngiestart_utc := ${now_utc}
291276305Sngie
292276305Sngiemeta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \
293276305Sngie	created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}}
294276305Sngie
295276305Sngie#.END: _reldir_finish
296276305Sngie.if target(gendirdeps)
297276305Sngie_reldir_finish: gendirdeps
298246149Ssjg.endif
299276305Sngie_reldir_finish: .NOMETA
300276305Sngie	@echo "${TIME_STAMP} Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
301276305Sngie
302276305Sngie#.ERROR: _reldir_failed
303276305Sngie_reldir_failed: .NOMETA
304276305Sngie	@echo "${TIME_STAMP} Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}"
305276305Sngie
306276305Sngie.if defined(WITH_META_STATS) && ${.MAKE.LEVEL} > 0
307276305Sngie.END: _reldir_finish
308276305Sngie.ERROR: _reldir_failed
309276305Sngie.endif
310276305Sngie
311276305Sngie.endif
312