1# RCSid: 2# $Id: dirdeps-targets.mk,v 1.24 2020/12/11 18:15:43 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 44# include . to allow any directory to work as a target 45DIRDEPS_TARGETS_DIRS ?= targets targets/pseudo 46# these prefixes can modify how we behave 47# they need to be stripped when looking for target dirs 48DIRDEPS_TARGETS_PREFIX_LIST ?= pkg- build- 49 50# some .TARGETS need filtering 51DIRDEPS_TARGETS_FILTER += Nall 52 53# matching target dirs if any 54tdirs := ${.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:}@} 55 56.if !empty(DEBUG_DIRDEPS_TARGETS) 57.info tdirs=${tdirs} 58.endif 59 60.if !empty(tdirs) 61# some things we know we want to ignore 62DIRDEPS_TARGETS_SKIP_LIST += \ 63 *~ \ 64 *.bak \ 65 *.inc \ 66 *.old \ 67 *.options \ 68 *.orig \ 69 *.rej \ 70 71# the list of MACHINEs we consider 72DIRDEPS_TARGETS_MACHINE_LIST += \ 73 ${ALL_MACHINE_LIST:U} \ 74 ${PSEUDO_MACHINE_LIST:Ucommon host host32} \ 75 ${TARGET_MACHINE_LIST} 76 77DIRDEPS_TARGETS_MACHINE_LIST := ${DIRDEPS_TARGETS_MACHINE_LIST:O:u} 78 79# raw Makefile.depend* list 80tdeps != 'cd' ${SRCTOP} && 'ls' -1 ${tdirs:O:u:@d@$d/${.MAKE.DEPENDFILE_PREFIX}*@:S,^./,,} 2> /dev/null; echo 81.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != "" 82.info tdeps=${tdeps} 83.endif 84# remove things we know we don't want 85tdeps := ${tdeps:${DIRDEPS_TARGETS_SKIP_LIST:${M_ListToSkip}}} 86.if ${DEBUG_DIRDEPS_TARGETS:U:Mdep*} != "" 87.info tdeps=${tdeps} 88.endif 89 90# plain entries (no qualifiers) these apply to any TARGET_SPEC 91ptdeps := ${tdeps:M*${.MAKE.DEPENDFILE_PREFIX}:S,/${.MAKE.DEPENDFILE_PREFIX},,} 92 93# MACHINE qualified entries 94mqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m}@:S,/${.MAKE.DEPENDFILE_PREFIX},,} 95 96tqtdeps = 97.if ${TARGET_SPEC_VARS:[#]} > 1 98# TARGET_SPEC qualified entries 99.if !empty(TARGET_SPEC_LIST) 100# we have a list of valid TARGET_SPECS; use it 101tqtdeps := ${TARGET_SPEC_LIST:U:O:u:@t@${tdeps:M*.$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,} 102.else 103# do we have a list of valid tuple members for at least 104# the last tupple element? if so match on that 105TARGET_SPEC_LAST_LIST ?= ${${TARGET_SPEC_VARS:[-1]}_LIST} 106.if !empty(TARGET_SPEC_LAST_LIST) 107tqtdeps := ${TARGET_SPEC_LAST_LIST:U:O:u:@t@${tdeps:M*,$t}@:S,/${.MAKE.DEPENDFILE_PREFIX},,} 108.else 109# this is sub-optimal match MACHINE, 110tqtdeps := ${DIRDEPS_TARGETS_MACHINE_LIST:@m@${tdeps:M*.$m,*}@:S,/${.MAKE.DEPENDFILE_PREFIX},,} 111.endif 112.endif 113.endif 114 115# now work out what we want in DIRDEPS 116.if empty(REQUESTED_MACHINE) 117# we want them all just as found 118DIRDEPS = ${ptdeps} ${mqtdeps} ${tqtdeps} 119.else 120# we only want those that match REQUESTED_MACHINE/REQUESTED_TARGET_SPEC 121# or REQUESTED_TARGET_SPEC (TARGET_SPEC) 122DIRDEPS = \ 123 ${ptdeps:@d@$d.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC:U${REQUESTED_MACHINE}}}@} \ 124 ${mqtdeps:M*.${REQUESTED_MACHINE}} \ 125 ${tqtdeps:M*.${REQUESTED_TARGET_SPEC:U${TARGET_SPEC}}} 126.endif 127# clean up 128DIRDEPS := ${DIRDEPS:O:u} 129 130.if !empty(DEBUG_DIRDEPS_TARGETS) 131.for x in tdeps ptdeps mqtdeps tqtdeps DIRDEPS 132.info $x=${$x} 133.endfor 134.endif 135.endif 136# if we got DIRDEPS get to work 137.if !empty(DIRDEPS) 138DIRDEPS.dirs := ${DIRDEPS:S,^,${SRCTOP}/,:@d@${exists($d):?$d:${d:R}}@} 139# some targets want to tweak options we might want to process now 140.for m in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.options,} 141.-include <$m> 142.endfor 143.if defined(MK_STATIC_DIRDEPS_CACHE) 144# some targets are very expensive to compute dirdeps for 145# so we may have a static cache 146.for c in ${DIRDEPS.dirs:S,$,/Makefile.dirdeps.cache,} 147.if exists($c) 148STATIC_DIRDEPS_CACHE ?= $c 149.if ${MK_STATIC_DIRDEPS_CACHE} == "yes" 150DIRDEPS_CACHE ?= $c 151MK_DIRDEPS_CACHE = yes 152.endif 153.endif 154.endfor 155.if defined(STATIC_DIRDEPS_CACHE) 156.export STATIC_DIRDEPS_CACHE 157.endif 158.endif 159 160# allow a top-level makefile to do other stuff 161# before including dirdeps.mk 162.if ${MK_DIRDEPS_TARGETS_INCLUDE_DIRDEPS:Uyes} == "yes" 163.include <dirdeps.mk> 164.endif 165 166DIRDEPS_TARGETS_SKIP += all clean* destroy* 167 168.for t in ${.TARGETS:${DIRDEPS_TARGETS_SKIP:${M_ListToSkip}}} 169$t: dirdeps 170.endfor 171.endif 172.endif 173