xref: /freebsd/share/mk/dirdeps-targets.mk (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
1# $FreeBSD$
2# RCSid:
3#       $Id: dirdeps-targets.mk,v 1.24 2020/12/11 18:15:43 sjg Exp $
4#
5#       @(#) Copyright (c) 2019-2020 Simon J. Gerraty
6#
7#       This file is provided in the hope that it will
8#       be of use.  There is absolutely NO WARRANTY.
9#       Permission to copy, redistribute or otherwise
10#       use this file is hereby granted provided that
11#       the above copyright notice and this notice are
12#       left intact.
13#
14#       Please send copies of changes and bug-fixes to:
15#       sjg@crufty.net
16#
17
18##
19# This makefile is used to set initial DIRDEPS for top-level build
20# targets.
21#
22# The basic idea is that we have a list of directories in
23# DIRDEPS_TARGETS_DIRS which are relative to SRCTOP.
24# When asked to make 'foo' we look for any directory named 'foo'
25# under DIRDEPS_TARGETS_DIRS.
26# We then search those dirs for any Makefile.depend*
27# Finally we select any that match conditions like REQUESTED_MACHINE
28# or TARGET_SPEC and initialize DIRDEPS accordingly.
29#
30# We will check each of the initial DIRDEPS for Makefile.dirdeps.options
31# and include any found.
32# This makes it feasible to tweak options like MK_DIRDEPS_CACHE
33# for a specific target.
34#
35# If MK_STATIC_DIRDEPS_CACHE is defined we will check if the
36# initial DIRDEPS has a static cache (Makefile.dirdeps.cache).
37# This only makes sense for seriously expensive targets.
38#
39
40.if ${.MAKE.LEVEL} == 0
41# pickup customizations
42.-include <local.dirdeps-targets.mk>
43
44# for DIRDEPS_BUILD this is how we prime the pump
45# include . to allow any directory to work as a target
46DIRDEPS_TARGETS_DIRS ?= targets targets/pseudo
47# these prefixes can modify how we behave
48# they need to be stripped when looking for target dirs
49DIRDEPS_TARGETS_PREFIX_LIST ?= pkg- build-
50
51# some .TARGETS need filtering
52DIRDEPS_TARGETS_FILTER += Nall
53
54# matching target dirs if any
55tdirs := ${.TARGETS:${DIRDEPS_TARGETS_FILTER:ts:}:${DIRDEPS_TARGETS_PREFIX_LIST:@p@S,^$p,,@:ts:}:@t@${DIRDEPS_TARGETS_DIRS:@d@$d/$t@}@:@d@${exists(${SRCTOP}/$d):?$d:}@}
56
57.if !empty(DEBUG_DIRDEPS_TARGETS)
58.info tdirs=${tdirs}
59.endif
60
61.if !empty(tdirs)
62# some things we know we want to ignore
63DIRDEPS_TARGETS_SKIP_LIST += \
64	*~ \
65	*.bak \
66	*.inc \
67	*.old \
68	*.options \
69	*.orig \
70	*.rej \
71
72# the list of MACHINEs we consider
73DIRDEPS_TARGETS_MACHINE_LIST += \
74	${ALL_MACHINE_LIST:U} \
75	${PSEUDO_MACHINE_LIST:Ucommon host host32} \
76	${TARGET_MACHINE_LIST}
77
78DIRDEPS_TARGETS_MACHINE_LIST := ${DIRDEPS_TARGETS_MACHINE_LIST:O:u}
79
80# raw Makefile.depend* list
81tdeps != 'cd' ${SRCTOP} && 'ls' -1 ${tdirs:O:u:@d@$d/${.MAKE.DEPENDFILE_PREFIX}*@:S,^./,,} 2> /dev/null; echo
82.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
83.info tdeps=${tdeps}
84.endif
85# remove things we know we don't want
86tdeps := ${tdeps:${DIRDEPS_TARGETS_SKIP_LIST:${M_ListToSkip}}}
87.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != ""
88.info tdeps=${tdeps}
89.endif
90
91# plain entries (no qualifiers) these apply to any TARGET_SPEC
92ptdeps := ${tdeps:M*${.MAKE.DEPENDFILE_PREFIX}:S,/${.MAKE.DEPENDFILE_PREFIX},,}
93
94# MACHINE qualified entries
95mqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
96
97tqtdeps =
98.if ${TARGET_SPEC_VARS:[#]} > 1
99# TARGET_SPEC qualified entries
100.if !empty(TARGET_SPEC_LIST)
101# we have a list of valid TARGET_SPECS; use it
102tqtdeps := ${TARGET_SPEC_LIST:U:O:u:@t@${tdeps:M*.$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
103.else
104# do we have a list of valid tuple members for at least
105# the last tupple element? if so match on that
106TARGET_SPEC_LAST_LIST ?= ${${TARGET_SPEC_VARS:[-1]}_LIST}
107.if !empty(TARGET_SPEC_LAST_LIST)
108tqtdeps := ${TARGET_SPEC_LAST_LIST:U:O:u:@t@${tdeps:M*,$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
109.else
110# this is sub-optimal match MACHINE,
111tqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m,*}@:S,/${.MAKE.DEPENDFILE_PREFIX},,}
112.endif
113.endif
114.endif
115
116# now work out what we want in DIRDEPS
117.if empty(REQUESTED_MACHINE)
118# we want them all just as found
119DIRDEPS = ${ptdeps} ${mqtdeps} ${tqtdeps}
120.else
121# we only want those that match REQUESTED_MACHINE/REQUESTED_TARGET_SPEC
122# or REQUESTED_TARGET_SPEC (TARGET_SPEC)
123DIRDEPS = \
124	${ptdeps:@d@$d.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC:U${REQUESTED_MACHINE}}}@} \
125	${mqtdeps:M*.${REQUESTED_MACHINE}} \
126	${tqtdeps:M*.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC}}}
127.endif
128# clean up
129DIRDEPS := ${DIRDEPS:O:u}
130
131.if !empty(DEBUG_DIRDEPS_TARGETS)
132.for x in tdeps ptdeps mqtdeps tqtdeps DIRDEPS
133.info $x=${$x}
134.endfor
135.endif
136.endif
137# if we got DIRDEPS get to work
138.if !empty(DIRDEPS)
139DIRDEPS.dirs := ${DIRDEPS:S,^,${SRCTOP}/,:@d@${exists($d):?$d:${d:R}}@}
140# some targets want to tweak options we might want to process now
141.for m in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.options,}
142.-include <$m>
143.endfor
144.if defined(MK_STATIC_DIRDEPS_CACHE)
145# some targets are very expensive to compute dirdeps for
146# so we may have a static cache
147.for c in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.cache,}
148.if exists($c)
149STATIC_DIRDEPS_CACHE ?= $c
150.if ${MK_STATIC_DIRDEPS_CACHE} == "yes"
151DIRDEPS_CACHE ?= $c
152MK_DIRDEPS_CACHE = yes
153.endif
154.endif
155.endfor
156.if defined(STATIC_DIRDEPS_CACHE)
157.export STATIC_DIRDEPS_CACHE
158.endif
159.endif
160
161# allow a top-level makefile to do other stuff
162# before including dirdeps.mk
163.if ${MK_DIRDEPS_TARGETS_INCLUDE_DIRDEPS:Uyes} == "yes"
164.include <dirdeps.mk>
165.endif
166
167DIRDEPS_TARGETS_SKIP += all clean* destroy*
168
169.for t in ${.TARGETS:${DIRDEPS_TARGETS_SKIP:${M_ListToSkip}}}
170$t: dirdeps
171.endfor
172.endif
173.endif
174