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