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