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