1 |
# $Id: dirdeps.mk,v 1.89 2017/05/17 17:41:47 sjg Exp $ |
2 |
|
3 |
# Copyright (c) 2010-2013, Juniper Networks, Inc. |
4 |
# All rights reserved. |
5 |
# |
6 |
# Redistribution and use in source and binary forms, with or without |
7 |
# modification, are permitted provided that the following conditions |
8 |
# are met: |
9 |
# 1. Redistributions of source code must retain the above copyright |
10 |
# notice, this list of conditions and the following disclaimer. |
11 |
# 2. Redistributions in binary form must reproduce the above copyright |
12 |
# notice, this list of conditions and the following disclaimer in the |
13 |
# documentation and/or other materials provided with the distribution. |
14 |
# |
15 |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
16 |
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
17 |
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
18 |
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
19 |
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
20 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
21 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 |
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 |
|
27 |
# Much of the complexity here is for supporting cross-building. |
28 |
# If a tree does not support that, simply using plain Makefile.depend |
29 |
# should provide sufficient clue. |
30 |
# Otherwise the recommendation is to use Makefile.depend.${MACHINE} |
31 |
# as expected below. |
32 |
|
33 |
# Note: this file gets multiply included. |
34 |
# This is what we do with DIRDEPS |
35 |
|
36 |
# DIRDEPS: |
37 |
# This is a list of directories - relative to SRCTOP, it is |
38 |
# normally only of interest to .MAKE.LEVEL 0. |
39 |
# In some cases the entry may be qualified with a .<machine> |
40 |
# or .<target_spec> suffix (see TARGET_SPEC_VARS below), |
41 |
# for example to force building something for the pseudo |
42 |
# machines "host" or "common" regardless of current ${MACHINE}. |
43 |
# |
44 |
# All unqualified entries end up being qualified with .${TARGET_SPEC} |
45 |
# and partially qualified (if TARGET_SPEC_VARS has multiple |
46 |
# entries) are also expanded to a full .<target_spec>. |
47 |
# The _DIRDEP_USE target uses the suffix to set TARGET_SPEC |
48 |
# correctly when visiting each entry. |
49 |
# |
50 |
# The fully qualified directory entries are used to construct a |
51 |
# dependency graph that will drive the build later. |
52 |
# |
53 |
# Also, for each fully qualified directory target, we will search |
54 |
# using ${.MAKE.DEPENDFILE_PREFERENCE} to find additional |
55 |
# dependencies. We use Makefile.depend (default value for |
56 |
# .MAKE.DEPENDFILE_PREFIX) to refer to these makefiles to |
57 |
# distinguish them from others. |
58 |
# |
59 |
# Before each Makefile.depend file is read, we set |
60 |
# DEP_RELDIR to be the RELDIR (path relative to SRCTOP) for |
61 |
# its directory, and DEP_MACHINE etc according to the .<target_spec> |
62 |
# represented by the suffix of the corresponding target. |
63 |
# |
64 |
# Since each Makefile.depend file includes dirdeps.mk, this |
65 |
# processing is recursive and results in .MAKE.LEVEL 0 learning the |
66 |
# dependencies of the tree wrt the initial directory (_DEP_RELDIR). |
67 |
# |
68 |
# BUILD_AT_LEVEL0 |
69 |
# Indicates whether .MAKE.LEVEL 0 builds anything: |
70 |
# if "no" sub-makes are used to build everything, |
71 |
# if "yes" sub-makes are only used to build for other machines. |
72 |
# It is best to use "no", but this can require fixing some |
73 |
# makefiles to not do anything at .MAKE.LEVEL 0. |
74 |
# |
75 |
# TARGET_SPEC_VARS |
76 |
# The default value is just MACHINE, and for most environments |
77 |
# this is sufficient. The _DIRDEP_USE target actually sets |
78 |
# both MACHINE and TARGET_SPEC to the suffix of the current |
79 |
# target so that in the general case TARGET_SPEC can be ignored. |
80 |
# |
81 |
# If more than MACHINE is needed then sys.mk needs to decompose |
82 |
# TARGET_SPEC and set the relevant variables accordingly. |
83 |
# It is important that MACHINE be included in and actually be |
84 |
# the first member of TARGET_SPEC_VARS. This allows other |
85 |
# variables to be considered optional, and some of the treatment |
86 |
# below relies on MACHINE being the first entry. |
87 |
# Note: TARGET_SPEC cannot contain any '.'s so the target |
88 |
# triple used by compiler folk won't work (directly anyway). |
89 |
# |
90 |
# For example: |
91 |
# |
92 |
# # Always list MACHINE first, |
93 |
# # other variables might be optional. |
94 |
# TARGET_SPEC_VARS = MACHINE TARGET_OS |
95 |
# .if ${TARGET_SPEC:Uno:M*,*} != "" |
96 |
# _tspec := ${TARGET_SPEC:S/,/ /g} |
97 |
# MACHINE := ${_tspec:[1]} |
98 |
# TARGET_OS := ${_tspec:[2]} |
99 |
# # etc. |
100 |
# # We need to stop that TARGET_SPEC affecting any submakes |
101 |
# # and deal with MACHINE=${TARGET_SPEC} in the environment. |
102 |
# TARGET_SPEC = |
103 |
# # export but do not track |
104 |
# .export-env TARGET_SPEC |
105 |
# .export ${TARGET_SPEC_VARS} |
106 |
# .for v in ${TARGET_SPEC_VARS:O:u} |
107 |
# .if empty($v) |
108 |
# .undef $v |
109 |
# .endif |
110 |
# .endfor |
111 |
# .endif |
112 |
# # make sure we know what TARGET_SPEC is |
113 |
# # as we may need it to find Makefile.depend* |
114 |
# TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,} |
115 |
# |
116 |
# The following variables can influence the initial DIRDEPS |
117 |
# computation with regard to the TARGET_SPECs that will be |
118 |
# built. |
119 |
# Most should also be considered by init.mk |
120 |
# |
121 |
# ONLY_TARGET_SPEC_LIST |
122 |
# Defines a list of TARGET_SPECs for which the current |
123 |
# directory can be built. |
124 |
# If ALL_MACHINES is defined, we build for all the |
125 |
# TARGET_SPECs listed. |
126 |
# |
127 |
# ONLY_MACHINE_LIST |
128 |
# As for ONLY_TARGET_SPEC_LIST but only specifies |
129 |
# MACHINEs. |
130 |
# |
131 |
# NOT_TARGET_SPEC_LIST |
132 |
# A list of TARGET_SPECs for which the current |
133 |
# directory should not be built. |
134 |
# |
135 |
# NOT_MACHINE_LIST |
136 |
# A list of MACHINEs the current directory should not be |
137 |
# built for. |
138 |
# |
139 |
|
140 |
.if !target(bootstrap) && (make(bootstrap) || \ |
141 |
make(bootstrap-this) || \ |
142 |
make(bootstrap-recurse) || \ |
143 |
make(bootstrap-empty)) |
144 |
# disable most of below |
145 |
.MAKE.LEVEL = 1 |
146 |
.endif |
147 |
|
148 |
# touch this at your peril |
149 |
_DIRDEP_USE_LEVEL?= 0 |
150 |
.if ${.MAKE.LEVEL} == ${_DIRDEP_USE_LEVEL} |
151 |
# only the first instance is interested in all this |
152 |
|
153 |
.if !target(_DIRDEP_USE) |
154 |
|
155 |
# do some setup we only need once |
156 |
_CURDIR ?= ${.CURDIR} |
157 |
_OBJDIR ?= ${.OBJDIR} |
158 |
|
159 |
now_utc = ${%s:L:gmtime} |
160 |
.if !defined(start_utc) |
161 |
start_utc := ${now_utc} |
162 |
.endif |
163 |
|
164 |
.if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != "" |
165 |
# This little trick let's us do |
166 |
# |
167 |
# mk -f dirdeps.mk some/dir.${TARGET_SPEC} |
168 |
# |
169 |
all: |
170 |
${.TARGETS:Nall}: all |
171 |
DIRDEPS := ${.TARGETS:M*[/.]*} |
172 |
# so that -DNO_DIRDEPS works |
173 |
DEP_RELDIR := ${DIRDEPS:[1]:R} |
174 |
# this will become DEP_MACHINE below |
175 |
TARGET_MACHINE := ${DIRDEPS:[1]:E:C/,.*//} |
176 |
.if ${TARGET_MACHINE:N*/*} == "" |
177 |
TARGET_MACHINE := ${MACHINE} |
178 |
.endif |
179 |
# disable DIRDEPS_CACHE as it does not like this trick |
180 |
MK_DIRDEPS_CACHE = no |
181 |
.endif |
182 |
|
183 |
# make sure we get the behavior we expect |
184 |
.MAKE.SAVE_DOLLARS = no |
185 |
|
186 |
# make sure these are empty to start with |
187 |
_DEP_TARGET_SPEC = |
188 |
|
189 |
# If TARGET_SPEC_VARS is other than just MACHINE |
190 |
# it should be set by sys.mk or similar by now. |
191 |
# TARGET_SPEC must not contain any '.'s. |
192 |
TARGET_SPEC_VARS ?= MACHINE |
193 |
# this is what we started with |
194 |
TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,} |
195 |
# this is what we mostly use below |
196 |
DEP_TARGET_SPEC = ${TARGET_SPEC_VARS:S,^,DEP_,:@v@${$v:U}@:ts,} |
197 |
# make sure we have defaults |
198 |
.for v in ${TARGET_SPEC_VARS} |
199 |
DEP_$v ?= ${$v} |
200 |
.endfor |
201 |
|
202 |
.if ${TARGET_SPEC_VARS:[#]} > 1 |
203 |
# Ok, this gets more complex (putting it mildly). |
204 |
# In order to stay sane, we need to ensure that all the build_dirs |
205 |
# we compute below are fully qualified wrt DEP_TARGET_SPEC. |
206 |
# The makefiles may only partially specify (eg. MACHINE only), |
207 |
# so we need to construct a set of modifiers to fill in the gaps. |
208 |
.if ${MAKE_VERSION} >= 20170130 |
209 |
_tspec_x := ${TARGET_SPEC_VARS:range} |
210 |
.elif ${TARGET_SPEC_VARS:[#]} > 10 |
211 |
# seriously? better have jot(1) or equivalent to produce suitable sequence |
212 |
_tspec_x := ${${JOT:Ujot} ${TARGET_SPEC_VARS:[#]}:L:sh} |
213 |
.else |
214 |
# we can provide the sequence ourselves |
215 |
_tspec_x := ${1 2 3 4 5 6 7 8 9 10:L:[1..${TARGET_SPEC_VARS:[#]}]} |
216 |
.endif |
217 |
# this handles unqualified entries |
218 |
M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC}; |
219 |
# there needs to be at least one item missing for these to make sense |
220 |
.for i in ${_tspec_x:[2..-1]} |
221 |
_tspec_m$i := ${TARGET_SPEC_VARS:[2..$i]:@w@[^,]+@:ts,} |
222 |
_tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,} |
223 |
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i}; |
224 |
.endfor |
225 |
.else |
226 |
# A harmless? default. |
227 |
M_dep_qual_fixes = U |
228 |
.endif |
229 |
|
230 |
.if !defined(.MAKE.DEPENDFILE_PREFERENCE) |
231 |
# .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater? |
232 |
# you really want this set by sys.mk or similar |
233 |
.MAKE.DEPENDFILE_PREFERENCE = ${_CURDIR}/${.MAKE.DEPENDFILE:T} |
234 |
.if ${.MAKE.DEPENDFILE:E} == "${TARGET_SPEC}" |
235 |
.if ${TARGET_SPEC} != ${MACHINE} |
236 |
.MAKE.DEPENDFILE_PREFERENCE += ${_CURDIR}/${.MAKE.DEPENDFILE:T:R}.$${MACHINE} |
237 |
.endif |
238 |
.MAKE.DEPENDFILE_PREFERENCE += ${_CURDIR}/${.MAKE.DEPENDFILE:T:R} |
239 |
.endif |
240 |
.endif |
241 |
|
242 |
_default_dependfile := ${.MAKE.DEPENDFILE_PREFERENCE:[1]:T} |
243 |
_machine_dependfiles := ${.MAKE.DEPENDFILE_PREFERENCE:T:M*${MACHINE}*} |
244 |
|
245 |
# for machine specific dependfiles we require ${MACHINE} to be at the end |
246 |
# also for the sake of sanity we require a common prefix |
247 |
.if !defined(.MAKE.DEPENDFILE_PREFIX) |
248 |
# knowing .MAKE.DEPENDFILE_PREFIX helps |
249 |
.if !empty(_machine_dependfiles) |
250 |
.MAKE.DEPENDFILE_PREFIX := ${_machine_dependfiles:[1]:T:R} |
251 |
.else |
252 |
.MAKE.DEPENDFILE_PREFIX := ${_default_dependfile:T} |
253 |
.endif |
254 |
.endif |
255 |
|
256 |
|
257 |
# this is how we identify non-machine specific dependfiles |
258 |
N_notmachine := ${.MAKE.DEPENDFILE_PREFERENCE:E:N*${MACHINE}*:${M_ListToSkip}} |
259 |
|
260 |
.endif # !target(_DIRDEP_USE) |
261 |
|
262 |
# First off, we want to know what ${MACHINE} to build for. |
263 |
# This can be complicated if we are using a mixture of ${MACHINE} specific |
264 |
# and non-specific Makefile.depend* |
265 |
|
266 |
# if we were included recursively _DEP_TARGET_SPEC should be valid. |
267 |
.if empty(_DEP_TARGET_SPEC) |
268 |
# we may or may not have included a dependfile yet |
269 |
.if defined(.INCLUDEDFROMFILE) |
270 |
_last_dependfile := ${.INCLUDEDFROMFILE:M${.MAKE.DEPENDFILE_PREFIX}*} |
271 |
.else |
272 |
_last_dependfile := ${.MAKE.MAKEFILES:M*/${.MAKE.DEPENDFILE_PREFIX}*:[-1]} |
273 |
.endif |
274 |
.if ${_debug_reldir:U0} |
275 |
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _last_dependfile='${_last_dependfile}' |
276 |
.endif |
277 |
|
278 |
.if empty(_last_dependfile) || ${_last_dependfile:E:${N_notmachine}} == "" |
279 |
# this is all we have to work with |
280 |
DEP_MACHINE = ${TARGET_MACHINE:U${MACHINE}} |
281 |
_DEP_TARGET_SPEC := ${DEP_TARGET_SPEC} |
282 |
.else |
283 |
_DEP_TARGET_SPEC = ${_last_dependfile:${M_dep_qual_fixes:ts:}:E} |
284 |
.endif |
285 |
.if !empty(_last_dependfile) |
286 |
# record that we've read dependfile for this |
287 |
_dirdeps_checked.${_CURDIR}.${TARGET_SPEC}: |
288 |
.endif |
289 |
.endif |
290 |
|
291 |
# by now _DEP_TARGET_SPEC should be set, parse it. |
292 |
.if ${TARGET_SPEC_VARS:[#]} > 1 |
293 |
# we need to parse DEP_MACHINE may or may not contain more info |
294 |
_tspec := ${_DEP_TARGET_SPEC:S/,/ /g} |
295 |
.for i in ${_tspec_x} |
296 |
DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]} |
297 |
.endfor |
298 |
.for v in ${TARGET_SPEC_VARS:O:u} |
299 |
.if empty(DEP_$v) |
300 |
.undef DEP_$v |
301 |
.endif |
302 |
.endfor |
303 |
.else |
304 |
DEP_MACHINE := ${_DEP_TARGET_SPEC} |
305 |
.endif |
306 |
|
307 |
# reset each time through |
308 |
_build_all_dirs = |
309 |
|
310 |
# the first time we are included the _DIRDEP_USE target will not be defined |
311 |
# we can use this as a clue to do initialization and other one time things. |
312 |
.if !target(_DIRDEP_USE) |
313 |
# make sure this target exists |
314 |
dirdeps: beforedirdeps .WAIT |
315 |
beforedirdeps: |
316 |
|
317 |
# We normally expect to be included by Makefile.depend.* |
318 |
# which sets the DEP_* macros below. |
319 |
DEP_RELDIR ?= ${RELDIR} |
320 |
|
321 |
# this can cause lots of output! |
322 |
# set to a set of glob expressions that might match RELDIR |
323 |
DEBUG_DIRDEPS ?= no |
324 |
|
325 |
# remember the initial value of DEP_RELDIR - we test for it below. |
326 |
_DEP_RELDIR := ${DEP_RELDIR} |
327 |
|
328 |
.endif |
329 |
|
330 |
# DIRDEPS_CACHE can be very handy for debugging. |
331 |
# Also if repeatedly building the same target, |
332 |
# we can avoid the overhead of re-computing the tree dependencies. |
333 |
MK_DIRDEPS_CACHE ?= no |
334 |
BUILD_DIRDEPS_CACHE ?= no |
335 |
BUILD_DIRDEPS ?= yes |
336 |
|
337 |
.if ${MK_DIRDEPS_CACHE} == "yes" |
338 |
# this is where we will cache all our work |
339 |
DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${.TARGETS:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.} |
340 |
.endif |
341 |
|
342 |
# pickup customizations |
343 |
# as below you can use !target(_DIRDEP_USE) to protect things |
344 |
# which should only be done once. |
345 |
.-include <local.dirdeps.mk> |
346 |
|
347 |
.if !target(_DIRDEP_USE) |
348 |
# things we skip for host tools |
349 |
SKIP_HOSTDIR ?= |
350 |
|
351 |
NSkipHostDir = ${SKIP_HOSTDIR:N*.host*:S,$,.host*,:N.host*:S,^,${SRCTOP}/,:${M_ListToSkip}} |
352 |
|
353 |
# things we always skip |
354 |
# SKIP_DIRDEPS allows for adding entries on command line. |
355 |
SKIP_DIR += .host *.WAIT ${SKIP_DIRDEPS} |
356 |
SKIP_DIR.host += ${SKIP_HOSTDIR} |
357 |
|
358 |
DEP_SKIP_DIR = ${SKIP_DIR} \ |
359 |
${SKIP_DIR.${DEP_TARGET_SPEC}:U} \ |
360 |
${TARGET_SPEC_VARS:@v@${SKIP_DIR.${DEP_$v}:U}@} \ |
361 |
${SKIP_DIRDEPS.${DEP_TARGET_SPEC}:U} \ |
362 |
${TARGET_SPEC_VARS:@v@${SKIP_DIRDEPS.${DEP_$v}:U}@} |
363 |
|
364 |
|
365 |
NSkipDir = ${DEP_SKIP_DIR:${M_ListToSkip}} |
366 |
|
367 |
.if defined(NODIRDEPS) || defined(WITHOUT_DIRDEPS) |
368 |
NO_DIRDEPS = |
369 |
.elif defined(WITHOUT_DIRDEPS_BELOW) |
370 |
NO_DIRDEPS_BELOW = |
371 |
.endif |
372 |
|
373 |
.if defined(NO_DIRDEPS) |
374 |
# confine ourselves to the original dir and below. |
375 |
DIRDEPS_FILTER += M${_DEP_RELDIR}* |
376 |
.elif defined(NO_DIRDEPS_BELOW) |
377 |
DIRDEPS_FILTER += M${_DEP_RELDIR} |
378 |
.endif |
379 |
|
380 |
# this is what we run below |
381 |
DIRDEP_MAKE?= ${.MAKE} |
382 |
|
383 |
# we suppress SUBDIR when visiting the leaves |
384 |
# we assume sys.mk will set MACHINE_ARCH |
385 |
# you can add extras to DIRDEP_USE_ENV |
386 |
# if there is no makefile in the target directory, we skip it. |
387 |
_DIRDEP_USE: .USE .MAKE |
388 |
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \ |
389 |
test -s ${.TARGET:R}/$$m || continue; \ |
390 |
echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \ |
391 |
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \ |
392 |
TARGET_SPEC=${.TARGET:E} \ |
393 |
MACHINE=${.TARGET:E} \ |
394 |
${DIRDEP_MAKE} -C ${.TARGET:R} || exit 1; \ |
395 |
break; \ |
396 |
done |
397 |
|
398 |
.ifdef ALL_MACHINES |
399 |
# this is how you limit it to only the machines we have been built for |
400 |
# previously. |
401 |
.if empty(ONLY_TARGET_SPEC_LIST) && empty(ONLY_MACHINE_LIST) |
402 |
.if !empty(ALL_MACHINE_LIST) |
403 |
# ALL_MACHINE_LIST is the list of all legal machines - ignore anything else |
404 |
_machine_list != cd ${_CURDIR} && 'ls' -1 ${ALL_MACHINE_LIST:O:u:@m@${.MAKE.DEPENDFILE:T:R}.$m@} 2> /dev/null; echo |
405 |
.else |
406 |
_machine_list != 'ls' -1 ${_CURDIR}/${.MAKE.DEPENDFILE_PREFIX}.* 2> /dev/null; echo |
407 |
.endif |
408 |
_only_machines := ${_machine_list:${NIgnoreFiles:UN*.bak}:E:O:u} |
409 |
.else |
410 |
_only_machines := ${ONLY_TARGET_SPEC_LIST:U} ${ONLY_MACHINE_LIST:U} |
411 |
.endif |
412 |
|
413 |
.if empty(_only_machines) |
414 |
# we must be boot-strapping |
415 |
_only_machines := ${TARGET_MACHINE:U${ALL_MACHINE_LIST:U${DEP_MACHINE}}} |
416 |
.endif |
417 |
|
418 |
.else # ! ALL_MACHINES |
419 |
# if ONLY_TARGET_SPEC_LIST or ONLY_MACHINE_LIST is set, we are limited to that. |
420 |
# Note that ONLY_TARGET_SPEC_LIST should be fully qualified. |
421 |
# if TARGET_MACHINE is set - it is really the same as ONLY_MACHINE_LIST |
422 |
# otherwise DEP_MACHINE is it - so DEP_MACHINE will match. |
423 |
_only_machines := ${ONLY_TARGET_SPEC_LIST:U:M${DEP_MACHINE},*} |
424 |
.if empty(_only_machines) |
425 |
_only_machines := ${ONLY_MACHINE_LIST:U${TARGET_MACHINE:U${DEP_MACHINE}}:M${DEP_MACHINE}} |
426 |
.endif |
427 |
.endif |
428 |
|
429 |
.if !empty(NOT_MACHINE_LIST) |
430 |
_only_machines := ${_only_machines:${NOT_MACHINE_LIST:${M_ListToSkip}}} |
431 |
.endif |
432 |
.if !empty(NOT_TARGET_SPEC_LIST) |
433 |
# we must first qualify |
434 |
_dm := ${DEP_MACHINE} |
435 |
_only_machines := ${_only_machines:M*,*} ${_only_machines:N*,*:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:${M_dep_qual_fixes:ts:}:O:u:S,^.,,} |
436 |
DEP_MACHINE := ${_dm} |
437 |
_only_machines := ${_only_machines:${NOT_TARGET_SPEC_LIST:${M_ListToSkip}}} |
438 |
.endif |
439 |
# clean up |
440 |
_only_machines := ${_only_machines:O:u} |
441 |
|
442 |
# make sure we have a starting place? |
443 |
DIRDEPS ?= ${RELDIR} |
444 |
.endif # target |
445 |
|
446 |
.if !defined(NO_DIRDEPS) && !defined(NO_DIRDEPS_BELOW) |
447 |
.if ${MK_DIRDEPS_CACHE} == "yes" |
448 |
|
449 |
# just ensure this exists |
450 |
build-dirdeps: |
451 |
|
452 |
M_oneperline = @x@\\${.newline} $$x@ |
453 |
|
454 |
.if ${BUILD_DIRDEPS_CACHE} == "no" |
455 |
.if !target(dirdeps-cached) |
456 |
# we do this via sub-make |
457 |
BUILD_DIRDEPS = no |
458 |
|
459 |
# ignore anything but these |
460 |
.MAKE.META.IGNORE_FILTER = M*/${.MAKE.DEPENDFILE_PREFIX}* |
461 |
|
462 |
dirdeps: dirdeps-cached |
463 |
dirdeps-cached: ${DIRDEPS_CACHE} .MAKE |
464 |
@echo "${TRACER}Using ${DIRDEPS_CACHE}" |
465 |
@MAKELEVEL=${.MAKE.LEVEL} ${.MAKE} -C ${_CURDIR} -f ${DIRDEPS_CACHE} \ |
466 |
dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no |
467 |
|
468 |
# these should generally do |
469 |
BUILD_DIRDEPS_MAKEFILE ?= ${MAKEFILE} |
470 |
BUILD_DIRDEPS_TARGETS ?= ${.TARGETS} |
471 |
|
472 |
# we need the .meta file to ensure we update if |
473 |
# any of the Makefile.depend* changed. |
474 |
# We do not want to compare the command line though. |
475 |
${DIRDEPS_CACHE}: .META .NOMETA_CMP |
476 |
+@{ echo '# Autogenerated - do NOT edit!'; echo; \ |
477 |
echo 'BUILD_DIRDEPS=no'; echo; \ |
478 |
echo '.include <dirdeps.mk>'; \ |
479 |
} > ${.TARGET}.new |
480 |
+@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \ |
481 |
DIRDEPS="${DIRDEPS}" \ |
482 |
TARGET_SPEC=${TARGET_SPEC} \ |
483 |
MAKEFLAGS= ${.MAKE} -C ${_CURDIR} -f ${BUILD_DIRDEPS_MAKEFILE} \ |
484 |
${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \ |
485 |
.MAKE.DEPENDFILE=.none \ |
486 |
${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \ |
487 |
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \ |
488 |
mv ${.TARGET}.new ${.TARGET} |
489 |
|
490 |
.endif |
491 |
.elif !target(_count_dirdeps) |
492 |
# we want to capture the dirdeps count in the cache |
493 |
.END: _count_dirdeps |
494 |
_count_dirdeps: .NOMETA |
495 |
@echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]}' >&3 |
496 |
|
497 |
.endif |
498 |
.elif !make(dirdeps) && !target(_count_dirdeps) |
499 |
beforedirdeps: _count_dirdeps |
500 |
_count_dirdeps: .NOMETA |
501 |
@echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} seconds=`expr ${now_utc} - ${start_utc}`" |
502 |
|
503 |
.endif |
504 |
.endif |
505 |
|
506 |
.if ${BUILD_DIRDEPS} == "yes" |
507 |
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != "" |
508 |
_debug_reldir = 1 |
509 |
.else |
510 |
_debug_reldir = 0 |
511 |
.endif |
512 |
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} != "" |
513 |
_debug_search = 1 |
514 |
.else |
515 |
_debug_search = 0 |
516 |
.endif |
517 |
|
518 |
# the rest is done repeatedly for every Makefile.depend we read. |
519 |
# if we are anything but the original dir we care only about the |
520 |
# machine type we were included for.. |
521 |
|
522 |
.if ${DEP_RELDIR} == "." |
523 |
_this_dir := ${SRCTOP} |
524 |
.else |
525 |
_this_dir := ${SRCTOP}/${DEP_RELDIR} |
526 |
.endif |
527 |
|
528 |
# on rare occasions, there can be a need for extra help |
529 |
_dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc |
530 |
.-include <${_dep_hack}> |
531 |
|
532 |
.if ${DEP_RELDIR} != ${_DEP_RELDIR} || ${DEP_TARGET_SPEC} != ${TARGET_SPEC} |
533 |
# this should be all |
534 |
_machines := ${DEP_MACHINE} |
535 |
.else |
536 |
# this is the machine list we actually use below |
537 |
_machines := ${_only_machines} |
538 |
|
539 |
.if defined(HOSTPROG) || ${DEP_MACHINE} == "host" |
540 |
# we need to build this guy's dependencies for host as well. |
541 |
_machines += host |
542 |
.endif |
543 |
|
544 |
_machines := ${_machines:O:u} |
545 |
.endif |
546 |
|
547 |
.if ${TARGET_SPEC_VARS:[#]} > 1 |
548 |
# we need to tweak _machines |
549 |
_dm := ${DEP_MACHINE} |
550 |
# apply the same filtering that we do when qualifying DIRDEPS. |
551 |
# M_dep_qual_fixes expects .${MACHINE}* so add (and remove) '.' |
552 |
# Again we expect that any already qualified machines are fully qualified. |
553 |
_machines := ${_machines:M*,*} ${_machines:N*,*:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:${M_dep_qual_fixes:ts:}:O:u:S,^.,,} |
554 |
DEP_MACHINE := ${_dm} |
555 |
_machines := ${_machines:O:u} |
556 |
.endif |
557 |
|
558 |
# reset each time through |
559 |
_build_dirs = |
560 |
|
561 |
.if ${DEP_RELDIR} == ${_DEP_RELDIR} |
562 |
# pickup other machines for this dir if necessary |
563 |
.if ${BUILD_AT_LEVEL0:Uyes} == "no" |
564 |
_build_dirs += ${_machines:@m@${_CURDIR}.$m@} |
565 |
.else |
566 |
_build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@} |
567 |
.if ${DEP_TARGET_SPEC} == ${TARGET_SPEC} |
568 |
# pickup local dependencies now |
569 |
.if ${MAKE_VERSION} < 20160220 |
570 |
.-include <.depend> |
571 |
.else |
572 |
.dinclude <.depend> |
573 |
.endif |
574 |
.endif |
575 |
.endif |
576 |
.endif |
577 |
|
578 |
.if ${_debug_reldir} |
579 |
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}' |
580 |
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}' |
581 |
.endif |
582 |
|
583 |
.if !empty(DIRDEPS) |
584 |
# these we reset each time through as they can depend on DEP_MACHINE |
585 |
DEP_DIRDEPS_FILTER = \ |
586 |
${DIRDEPS_FILTER.${DEP_TARGET_SPEC}:U} \ |
587 |
${TARGET_SPEC_VARS:@v@${DIRDEPS_FILTER.${DEP_$v}:U}@} \ |
588 |
${DIRDEPS_FILTER:U} |
589 |
.if empty(DEP_DIRDEPS_FILTER) |
590 |
# something harmless |
591 |
DEP_DIRDEPS_FILTER = U |
592 |
.endif |
593 |
|
594 |
# this is what we start with |
595 |
__depdirs := ${DIRDEPS:${NSkipDir}:${DEP_DIRDEPS_FILTER:ts:}:C,//+,/,g:O:u:@d@${SRCTOP}/$d@} |
596 |
|
597 |
# some entries may be qualified with .<machine> |
598 |
# the :M*/*/*.* just tries to limit the dirs we check to likely ones. |
599 |
# the ${d:E:M*/*} ensures we don't consider junos/usr.sbin/mgd |
600 |
__qual_depdirs := ${__depdirs:M*/*/*.*:@d@${exists($d):?:${"${d:E:M*/*}":?:${exists(${d:R}):?$d:}}}@} |
601 |
__unqual_depdirs := ${__depdirs:${__qual_depdirs:Uno:${M_ListToSkip}}} |
602 |
|
603 |
.if ${DEP_RELDIR} == ${_DEP_RELDIR} |
604 |
# if it was called out - we likely need it. |
605 |
__hostdpadd := ${DPADD:U.:M${HOST_OBJTOP}/*:S,${HOST_OBJTOP}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host,:N.*:@d@${SRCTOP}/$d@} |
606 |
__qual_depdirs += ${__hostdpadd} |
607 |
.endif |
608 |
|
609 |
.if ${_debug_reldir} |
610 |
.info depdirs=${__depdirs} |
611 |
.info qualified=${__qual_depdirs} |
612 |
.info unqualified=${__unqual_depdirs} |
613 |
.endif |
614 |
|
615 |
# _build_dirs is what we will feed to _DIRDEP_USE |
616 |
_build_dirs += \ |
617 |
${__qual_depdirs:M*.host:${NSkipHostDir}:N.host} \ |
618 |
${__qual_depdirs:N*.host} \ |
619 |
${_machines:Mhost*:@m@${__unqual_depdirs:@d@$d.$m@}@:${NSkipHostDir}:N.host} \ |
620 |
${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@} |
621 |
|
622 |
# qualify everything now |
623 |
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u} |
624 |
|
625 |
.endif # empty DIRDEPS |
626 |
|
627 |
_build_all_dirs += ${_build_dirs} |
628 |
_build_all_dirs := ${_build_all_dirs:O:u} |
629 |
|
630 |
# Normally if doing make -V something, |
631 |
# we do not want to waste time chasing DIRDEPS |
632 |
# but if we want to count the number of Makefile.depend* read, we do. |
633 |
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == "" |
634 |
.if !empty(_build_all_dirs) |
635 |
.if ${BUILD_DIRDEPS_CACHE} == "yes" |
636 |
x!= { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \ |
637 |
echo 'dirdeps: ${_build_all_dirs:${M_oneperline}}'; echo; } >&3; echo |
638 |
x!= { ${_build_all_dirs:@x@${target($x):?:echo '$x: _DIRDEP_USE';}@} echo; } >&3; echo |
639 |
.if !empty(DEP_EXPORT_VARS) |
640 |
# Discouraged, but there are always exceptions. |
641 |
# Handle it here rather than explain how. |
642 |
x!= { echo; ${DEP_EXPORT_VARS:@v@echo '$v=${$v}';@} echo '.export ${DEP_EXPORT_VARS}'; echo; } >&3; echo |
643 |
.endif |
644 |
.else |
645 |
# this makes it all happen |
646 |
dirdeps: ${_build_all_dirs} |
647 |
.endif |
648 |
${_build_all_dirs}: _DIRDEP_USE |
649 |
|
650 |
.if ${_debug_reldir} |
651 |
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs} |
652 |
.endif |
653 |
|
654 |
.if !empty(DEP_EXPORT_VARS) |
655 |
.export ${DEP_EXPORT_VARS} |
656 |
DEP_EXPORT_VARS= |
657 |
.endif |
658 |
|
659 |
# this builds the dependency graph |
660 |
.for m in ${_machines} |
661 |
# it would be nice to do :N${.TARGET} |
662 |
.if !empty(__qual_depdirs) |
663 |
.for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m} |
664 |
.if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != "" |
665 |
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q} |
666 |
.endif |
667 |
.if ${BUILD_DIRDEPS_CACHE} == "yes" |
668 |
x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$q:${M_oneperline}}'; echo; } >&3; echo |
669 |
.else |
670 |
${_this_dir}.$m: ${_build_dirs:M*.$q} |
671 |
.endif |
672 |
.endfor |
673 |
.endif |
674 |
.if ${_debug_reldir} |
675 |
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m} |
676 |
.endif |
677 |
.if ${BUILD_DIRDEPS_CACHE} == "yes" |
678 |
x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m:${M_oneperline}}'; echo; } >&3; echo |
679 |
.else |
680 |
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} |
681 |
.endif |
682 |
.endfor |
683 |
|
684 |
.endif |
685 |
|
686 |
# Now find more dependencies - and recurse. |
687 |
.for d in ${_build_all_dirs} |
688 |
.if !target(_dirdeps_checked.$d) |
689 |
# once only |
690 |
_dirdeps_checked.$d: |
691 |
.if ${_debug_search} |
692 |
.info checking $d |
693 |
.endif |
694 |
# Note: _build_all_dirs is fully qualifed so d:R is always the directory |
695 |
.if exists(${d:R}) |
696 |
# we pass _DEP_TARGET_SPEC to tell the next step what we want |
697 |
_DEP_TARGET_SPEC := ${d:E} |
698 |
# some makefiles may still look at this |
699 |
_DEP_MACHINE := ${d:E:C/,.*//} |
700 |
# set these too in case Makefile.depend* uses them |
701 |
.if ${TARGET_SPEC_VARS:[#]} > 1 |
702 |
_dtspec := ${_DEP_TARGET_SPEC:S/,/ /g} |
703 |
.for i in ${_tspec_x} |
704 |
DEP_${TARGET_SPEC_VARS:[$i]} := ${_dtspec:[$i]} |
705 |
.endfor |
706 |
.else |
707 |
DEP_MACHINE := ${_DEP_MACHINE} |
708 |
.endif |
709 |
# Warning: there is an assumption here that MACHINE is always |
710 |
# the first entry in TARGET_SPEC_VARS. |
711 |
# If TARGET_SPEC and MACHINE are insufficient, you have a problem. |
712 |
_m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:S;${MACHINE};${d:E:C/,.*//};:@m@${exists(${d:R}/$m):?${d:R}/$m:}@:[1]} |
713 |
.if !empty(_m) |
714 |
# M_dep_qual_fixes isn't geared to Makefile.depend |
715 |
_qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}} |
716 |
.if ${_debug_search} |
717 |
.info Looking for ${_qm} |
718 |
.endif |
719 |
# set this "just in case" |
720 |
# we can skip :tA since we computed the path above |
721 |
DEP_RELDIR := ${_m:H:S,${SRCTOP}/,,} |
722 |
# and reset this |
723 |
DIRDEPS = |
724 |
.if ${_debug_reldir} && ${_qm} != ${_m} |
725 |
.info loading ${_m} for ${d:E} |
726 |
.endif |
727 |
.include <${_m}> |
728 |
.endif |
729 |
.endif |
730 |
.endif |
731 |
.endfor |
732 |
|
733 |
.endif # -V |
734 |
.endif # BUILD_DIRDEPS |
735 |
|
736 |
.elif ${.MAKE.LEVEL} > 42 |
737 |
.error You should have stopped recursing by now. |
738 |
.else |
739 |
# we are building something |
740 |
DEP_RELDIR := ${RELDIR} |
741 |
_DEP_RELDIR := ${RELDIR} |
742 |
# pickup local dependencies |
743 |
.if ${MAKE_VERSION} < 20160220 |
744 |
.-include <.depend> |
745 |
.else |
746 |
.dinclude <.depend> |
747 |
.endif |
748 |
.endif |
749 |
|
750 |
# bootstrapping new dependencies made easy? |
751 |
.if !target(bootstrap) && (make(bootstrap) || \ |
752 |
make(bootstrap-this) || \ |
753 |
make(bootstrap-recurse) || \ |
754 |
make(bootstrap-empty)) |
755 |
|
756 |
# if we are bootstrapping create the default |
757 |
_want = ${.CURDIR}/${.MAKE.DEPENDFILE_DEFAULT:T} |
758 |
|
759 |
.if exists(${_want}) |
760 |
# stop here |
761 |
${.TARGETS:Mboot*}: |
762 |
.elif !make(bootstrap-empty) |
763 |
# find a Makefile.depend to use as _src |
764 |
_src != cd ${.CURDIR} && for m in ${.MAKE.DEPENDFILE_PREFERENCE:T:S,${MACHINE},*,}; do test -s $$m || continue; echo $$m; break; done; echo |
765 |
.if empty(_src) |
766 |
.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T}${.newline}Use: bootstrap-empty |
767 |
.endif |
768 |
|
769 |
_src?= ${.MAKE.DEPENDFILE} |
770 |
|
771 |
.MAKE.DEPENDFILE_BOOTSTRAP_SED+= -e 's/${_src:E:C/,.*//}/${MACHINE}/g' |
772 |
|
773 |
# just create Makefile.depend* for this dir |
774 |
bootstrap-this: .NOTMAIN |
775 |
@echo Bootstrapping ${RELDIR}/${_want:T} from ${_src:T}; \ |
776 |
echo You need to build ${RELDIR} to correctly populate it. |
777 |
.if ${_src:T} != ${.MAKE.DEPENDFILE_PREFIX:T} |
778 |
(cd ${.CURDIR} && sed ${.MAKE.DEPENDFILE_BOOTSTRAP_SED} ${_src} > ${_want:T}) |
779 |
.else |
780 |
cp ${.CURDIR}/${_src:T} ${_want} |
781 |
.endif |
782 |
|
783 |
# create Makefile.depend* for this dir and its dependencies |
784 |
bootstrap: bootstrap-recurse |
785 |
bootstrap-recurse: bootstrap-this |
786 |
|
787 |
_mf := ${.PARSEFILE} |
788 |
bootstrap-recurse: .NOTMAIN .MAKE |
789 |
@cd ${SRCTOP} && \ |
790 |
for d in `cd ${RELDIR} && ${.MAKE} -B -f ${"${.MAKEFLAGS:M-n}":?${_src}:${.MAKE.DEPENDFILE:T}} -V DIRDEPS`; do \ |
791 |
test -d $$d || d=$${d%.*}; \ |
792 |
test -d $$d || continue; \ |
793 |
echo "Checking $$d for bootstrap ..."; \ |
794 |
(cd $$d && ${.MAKE} -f ${_mf} bootstrap-recurse); \ |
795 |
done |
796 |
|
797 |
.endif |
798 |
|
799 |
# create an empty Makefile.depend* to get the ball rolling. |
800 |
bootstrap-empty: .NOTMAIN .NOMETA |
801 |
@echo Creating empty ${RELDIR}/${_want:T}; \ |
802 |
echo You need to build ${RELDIR} to correctly populate it. |
803 |
@{ echo DIRDEPS=; echo ".include <dirdeps.mk>"; } > ${_want} |
804 |
|
805 |
.endif |