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