Changeset View
Changeset View
Standalone View
Standalone View
head/share/mk/dirdeps.mk
# $FreeBSD$ | # $FreeBSD$ | ||||
# $Id: dirdeps.mk,v 1.100 2019/11/12 06:47:58 sjg Exp $ | # $Id: dirdeps.mk,v 1.130 2020/11/02 00:34:30 sjg Exp $ | ||||
# Copyright (c) 2010-2013, Juniper Networks, Inc. | # Copyright (c) 2010-2020, Simon J. Gerraty | ||||
# Copyright (c) 2010-2018, Juniper Networks, Inc. | |||||
# All rights reserved. | # All rights reserved. | ||||
# | # | ||||
# Redistribution and use in source and binary forms, with or without | # Redistribution and use in source and binary forms, with or without | ||||
# modification, are permitted provided that the following conditions | # modification, are permitted provided that the following conditions | ||||
# are met: | # are met: | ||||
# 1. Redistributions of source code must retain the above copyright | # 1. Redistributions of source code must retain the above copyright | ||||
# notice, this list of conditions and the following disclaimer. | # notice, this list of conditions and the following disclaimer. | ||||
# 2. Redistributions in binary form must reproduce the above copyright | # 2. Redistributions in binary form must reproduce the above copyright | ||||
Show All 23 Lines | |||||
# DIRDEPS: | # DIRDEPS: | ||||
# This is a list of directories - relative to SRCTOP, it is | # This is a list of directories - relative to SRCTOP, it is | ||||
# normally only of interest to .MAKE.LEVEL 0. | # normally only of interest to .MAKE.LEVEL 0. | ||||
# In some cases the entry may be qualified with a .<machine> | # In some cases the entry may be qualified with a .<machine> | ||||
# or .<target_spec> suffix (see TARGET_SPEC_VARS below), | # or .<target_spec> suffix (see TARGET_SPEC_VARS below), | ||||
# for example to force building something for the pseudo | # for example to force building something for the pseudo | ||||
# machines "host" or "common" regardless of current ${MACHINE}. | # machines "host" or "common" regardless of current ${MACHINE}. | ||||
# | # | ||||
# All unqualified entries end up being qualified with .${TARGET_SPEC} | # All unqualified entries end up being qualified with .${TARGET_SPEC} | ||||
# and partially qualified (if TARGET_SPEC_VARS has multiple | # and partially qualified (if TARGET_SPEC_VARS has multiple | ||||
# entries) are also expanded to a full .<target_spec>. | # entries) are also expanded to a full .<target_spec>. | ||||
# The _DIRDEP_USE target uses the suffix to set TARGET_SPEC | # The _DIRDEP_USE target uses the suffix to set TARGET_SPEC | ||||
# correctly when visiting each entry. | # correctly when visiting each entry. | ||||
# | # | ||||
# The fully qualified directory entries are used to construct a | # The fully qualified directory entries are used to construct a | ||||
# dependency graph that will drive the build later. | # dependency graph that will drive the build later. | ||||
# | # | ||||
# Also, for each fully qualified directory target, we will search | # Also, for each fully qualified directory target, we will search | ||||
# using ${.MAKE.DEPENDFILE_PREFERENCE} to find additional | # using ${.MAKE.DEPENDFILE_PREFERENCE} to find additional | ||||
# dependencies. We use Makefile.depend (default value for | # dependencies. We use Makefile.depend (default value for | ||||
# .MAKE.DEPENDFILE_PREFIX) to refer to these makefiles to | # .MAKE.DEPENDFILE_PREFIX) to refer to these makefiles to | ||||
# distinguish them from others. | # distinguish them from others. | ||||
# | # | ||||
# Before each Makefile.depend file is read, we set | # Before each Makefile.depend file is read, we set | ||||
# DEP_RELDIR to be the RELDIR (path relative to SRCTOP) for | # DEP_RELDIR to be the RELDIR (path relative to SRCTOP) for | ||||
# its directory, and DEP_MACHINE etc according to the .<target_spec> | # its directory, and DEP_MACHINE etc according to the .<target_spec> | ||||
# represented by the suffix of the corresponding target. | # represented by the suffix of the corresponding target. | ||||
# | # | ||||
# Since each Makefile.depend file includes dirdeps.mk, this | # Since each Makefile.depend file includes dirdeps.mk, this | ||||
# processing is recursive and results in .MAKE.LEVEL 0 learning the | # processing is recursive and results in .MAKE.LEVEL 0 learning the | ||||
# dependencies of the tree wrt the initial directory (_DEP_RELDIR). | # dependencies of the tree wrt the initial directory (_DEP_RELDIR). | ||||
# | # | ||||
# BUILD_AT_LEVEL0 | |||||
# Indicates whether .MAKE.LEVEL 0 builds anything: | |||||
# if "no" sub-makes are used to build everything, | |||||
# if "yes" sub-makes are only used to build for other machines. | |||||
# It is best to use "no", but this can require fixing some | |||||
# makefiles to not do anything at .MAKE.LEVEL 0. | |||||
# | |||||
# TARGET_SPEC_VARS | # TARGET_SPEC_VARS | ||||
# The default value is just MACHINE, and for most environments | # The default value is just MACHINE, and for most environments | ||||
# this is sufficient. The _DIRDEP_USE target actually sets | # this is sufficient. The _DIRDEP_USE target actually sets | ||||
# both MACHINE and TARGET_SPEC to the suffix of the current | # both MACHINE and TARGET_SPEC to the suffix of the current | ||||
# target so that in the general case TARGET_SPEC can be ignored. | # target so that in the general case TARGET_SPEC can be ignored. | ||||
# | # | ||||
# If more than MACHINE is needed then sys.mk needs to decompose | # If more than MACHINE is needed then sys.mk needs to decompose | ||||
# TARGET_SPEC and set the relevant variables accordingly. | # TARGET_SPEC and set the relevant variables accordingly. | ||||
Show All 24 Lines | |||||
# .if empty($v) | # .if empty($v) | ||||
# .undef $v | # .undef $v | ||||
# .endif | # .endif | ||||
# .endfor | # .endfor | ||||
# .endif | # .endif | ||||
# # make sure we know what TARGET_SPEC is | # # make sure we know what TARGET_SPEC is | ||||
# # as we may need it to find Makefile.depend* | # # as we may need it to find Makefile.depend* | ||||
# TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,} | # TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,} | ||||
# | # | ||||
# The following variables can influence the initial DIRDEPS | # The following variables can influence the initial DIRDEPS | ||||
# computation with regard to the TARGET_SPECs that will be | # computation with regard to the TARGET_SPECs that will be | ||||
# built. | # built. | ||||
# Most should also be considered by init.mk | # Most should also be considered by init.mk | ||||
# | # | ||||
# ONLY_TARGET_SPEC_LIST | # ONLY_TARGET_SPEC_LIST | ||||
# Defines a list of TARGET_SPECs for which the current | # Defines a list of TARGET_SPECs for which the current | ||||
# directory can be built. | # directory can be built. | ||||
# If ALL_MACHINES is defined, we build for all the | # If ALL_MACHINES is defined, we build for all the | ||||
# TARGET_SPECs listed. | # TARGET_SPECs listed. | ||||
# | # | ||||
# ONLY_MACHINE_LIST | # ONLY_MACHINE_LIST | ||||
# As for ONLY_TARGET_SPEC_LIST but only specifies | # As for ONLY_TARGET_SPEC_LIST but only specifies | ||||
# MACHINEs. | # MACHINEs. | ||||
# | # | ||||
# NOT_TARGET_SPEC_LIST | # NOT_TARGET_SPEC_LIST | ||||
# A list of TARGET_SPECs for which the current | # A list of TARGET_SPECs for which the current | ||||
# directory should not be built. | # directory should not be built. | ||||
# | # | ||||
# NOT_MACHINE_LIST | # NOT_MACHINE_LIST | ||||
# A list of MACHINEs the current directory should not be | # A list of MACHINEs the current directory should not be | ||||
# built for. | # built for. | ||||
# | # | ||||
# _build_xtra_dirs | |||||
# local.dirdeps.mk can add targets to this variable. | |||||
# They will be hooked into the build, but independent of | |||||
# any other DIRDEP. | |||||
# | |||||
# This allows for adding TESTS to the build, such that the build | |||||
# if any test fails, but without the risk of introducing | |||||
# circular dependencies. | |||||
now_utc ?= ${%s:L:gmtime} | |||||
.if !defined(start_utc) | |||||
start_utc := ${now_utc} | |||||
.endif | |||||
.if !target(bootstrap) && (make(bootstrap) || \ | .if !target(bootstrap) && (make(bootstrap) || \ | ||||
make(bootstrap-this) || \ | make(bootstrap-this) || \ | ||||
make(bootstrap-recurse) || \ | make(bootstrap-recurse) || \ | ||||
make(bootstrap-empty)) | make(bootstrap-empty)) | ||||
# disable most of below | # disable most of below | ||||
.MAKE.LEVEL = 1 | .MAKE.LEVEL = 1 | ||||
.endif | .endif | ||||
# touch this at your peril | # touch this at your peril | ||||
_DIRDEP_USE_LEVEL?= 0 | _DIRDEP_USE_LEVEL?= 0 | ||||
.if ${.MAKE.LEVEL} == ${_DIRDEP_USE_LEVEL} | .if ${.MAKE.LEVEL} == ${_DIRDEP_USE_LEVEL} | ||||
# only the first instance is interested in all this | # only the first instance is interested in all this | ||||
.if !target(_DIRDEP_USE) | .if !target(_DIRDEP_USE) | ||||
# do some setup we only need once | # do some setup we only need once | ||||
_CURDIR ?= ${.CURDIR} | _CURDIR ?= ${.CURDIR} | ||||
_OBJDIR ?= ${.OBJDIR} | _OBJDIR ?= ${.OBJDIR} | ||||
now_utc = ${%s:L:gmtime} | |||||
.if !defined(start_utc) | |||||
start_utc := ${now_utc} | |||||
.endif | |||||
.if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != "" | .if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != "" | ||||
# This little trick let's us do | # This little trick let's us do | ||||
# | # | ||||
# mk -f dirdeps.mk some/dir.${TARGET_SPEC} | # mk -f dirdeps.mk some/dir.${TARGET_SPEC} | ||||
# | # | ||||
all: | all: | ||||
${.TARGETS:Nall}: all | ${.TARGETS:Nall}: all | ||||
DIRDEPS := ${.TARGETS:M*[/.]*} | DIRDEPS := ${.TARGETS:M*[/.]*} | ||||
Show All 30 Lines | |||||
.if ${TARGET_SPEC_VARS:[#]} > 1 | .if ${TARGET_SPEC_VARS:[#]} > 1 | ||||
# Ok, this gets more complex (putting it mildly). | # Ok, this gets more complex (putting it mildly). | ||||
# In order to stay sane, we need to ensure that all the build_dirs | # In order to stay sane, we need to ensure that all the build_dirs | ||||
# we compute below are fully qualified wrt DEP_TARGET_SPEC. | # we compute below are fully qualified wrt DEP_TARGET_SPEC. | ||||
# The makefiles may only partially specify (eg. MACHINE only), | # The makefiles may only partially specify (eg. MACHINE only), | ||||
# so we need to construct a set of modifiers to fill in the gaps. | # so we need to construct a set of modifiers to fill in the gaps. | ||||
.if ${MAKE_VERSION} >= 20170130 | .if ${MAKE_VERSION} >= 20170130 | ||||
_tspec_x := ${TARGET_SPEC_VARS:range} | _tspec_x := ${TARGET_SPEC_VARS:range} | ||||
.elif ${TARGET_SPEC_VARS:[#]} > 10 | |||||
# seriously? better have jot(1) or equivalent to produce suitable sequence | |||||
_tspec_x := ${${JOT:Ujot} ${TARGET_SPEC_VARS:[#]}:L:sh} | |||||
.else | .else | ||||
# we can provide the sequence ourselves | # do it the hard way | ||||
_tspec_x := ${1 2 3 4 5 6 7 8 9 10:L:[1..${TARGET_SPEC_VARS:[#]}]} | _tspec_x := ${TARGET_SPEC_VARS:[#]:@x@i=1;while [ $$i -le $x ]; do echo $$i; i=$$((i + 1)); done;@:sh} | ||||
.endif | .endif | ||||
# this handles unqualified entries | # this handles unqualified entries | ||||
M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC}; | M_dep_qual_fixes = C;(/[^/.,]+)$$;\1.$${DEP_TARGET_SPEC}; | ||||
# there needs to be at least one item missing for these to make sense | # there needs to be at least one item missing for these to make sense | ||||
.for i in ${_tspec_x:[2..-1]} | .for i in ${_tspec_x:[2..-1]} | ||||
_tspec_m$i := ${TARGET_SPEC_VARS:[2..$i]:@w@[^,]+@:ts,} | _tspec_m$i := ${TARGET_SPEC_VARS:[2..$i]:@w@[^,]+@:ts,} | ||||
_tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,} | _tspec_a$i := ,${TARGET_SPEC_VARS:[$i..-1]:@v@$$$${DEP_$v}@:ts,} | ||||
M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i}; | M_dep_qual_fixes += C;(\.${_tspec_m$i})$$;\1${_tspec_a$i}; | ||||
.endfor | .endfor | ||||
TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]} | |||||
.else | .else | ||||
# A harmless? default. | # A harmless? default. | ||||
M_dep_qual_fixes = U | M_dep_qual_fixes = U | ||||
.endif | .endif | ||||
.if !defined(.MAKE.DEPENDFILE_PREFERENCE) | .if !defined(.MAKE.DEPENDFILE_PREFERENCE) | ||||
# .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater? | # .MAKE.DEPENDFILE_PREFERENCE makes the logic below neater? | ||||
# you really want this set by sys.mk or similar | # you really want this set by sys.mk or similar | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
.endif | .endif | ||||
.endfor | .endfor | ||||
.else | .else | ||||
DEP_MACHINE := ${_DEP_TARGET_SPEC} | DEP_MACHINE := ${_DEP_TARGET_SPEC} | ||||
.endif | .endif | ||||
# reset each time through | # reset each time through | ||||
_build_all_dirs = | _build_all_dirs = | ||||
_build_xtra_dirs = | |||||
# the first time we are included the _DIRDEP_USE target will not be defined | # the first time we are included the _DIRDEP_USE target will not be defined | ||||
# we can use this as a clue to do initialization and other one time things. | # we can use this as a clue to do initialization and other one time things. | ||||
.if !target(_DIRDEP_USE) | .if !target(_DIRDEP_USE) | ||||
# make sure this target exists | # make sure this target exists | ||||
dirdeps: beforedirdeps .WAIT | dirdeps: beforedirdeps .WAIT | ||||
beforedirdeps: | beforedirdeps: | ||||
Show All 14 Lines | |||||
# Also if repeatedly building the same target, | # Also if repeatedly building the same target, | ||||
# we can avoid the overhead of re-computing the tree dependencies. | # we can avoid the overhead of re-computing the tree dependencies. | ||||
MK_DIRDEPS_CACHE ?= no | MK_DIRDEPS_CACHE ?= no | ||||
BUILD_DIRDEPS_CACHE ?= no | BUILD_DIRDEPS_CACHE ?= no | ||||
BUILD_DIRDEPS ?= yes | BUILD_DIRDEPS ?= yes | ||||
.if ${MK_DIRDEPS_CACHE} == "yes" | .if ${MK_DIRDEPS_CACHE} == "yes" | ||||
# this is where we will cache all our work | # this is where we will cache all our work | ||||
DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${.TARGETS:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.} | DIRDEPS_CACHE ?= ${_OBJDIR:tA}/dirdeps.cache${_TARGETS:U${.TARGETS}:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.} | ||||
.endif | .endif | ||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != "" | |||||
_debug_reldir = 1 | |||||
.else | |||||
_debug_reldir = 0 | |||||
.endif | |||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} != "" | |||||
_debug_search = 1 | |||||
.else | |||||
_debug_search = 0 | |||||
.endif | |||||
# pickup customizations | # pickup customizations | ||||
# as below you can use !target(_DIRDEP_USE) to protect things | # as below you can use !target(_DIRDEP_USE) to protect things | ||||
# which should only be done once. | # which should only be done once. | ||||
.-include <local.dirdeps.mk> | .-include <local.dirdeps.mk> | ||||
.if !target(_DIRDEP_USE) | .if !target(_DIRDEP_USE) | ||||
# things we skip for host tools | # things we skip for host tools | ||||
SKIP_HOSTDIR ?= | SKIP_HOSTDIR ?= | ||||
Show All 26 Lines | |||||
.elif defined(NO_DIRDEPS_BELOW) | .elif defined(NO_DIRDEPS_BELOW) | ||||
DIRDEPS_FILTER += M${_DEP_RELDIR} | DIRDEPS_FILTER += M${_DEP_RELDIR} | ||||
.endif | .endif | ||||
# this is what we run below | # this is what we run below | ||||
DIRDEP_MAKE ?= ${.MAKE} | DIRDEP_MAKE ?= ${.MAKE} | ||||
DIRDEP_DIR ?= ${.TARGET:R} | DIRDEP_DIR ?= ${.TARGET:R} | ||||
# if you want us to report load averages during build | |||||
# DIRDEP_USE_PRELUDE += ${DIRDEP_LOADAVG_REPORT}; | |||||
DIRDEP_LOADAVG_CMD ?= ${UPTIME:Uuptime} | sed 's,.*\(load\),\1,' | |||||
DIRDEP_LOADAVG_LAST = 0 | |||||
# yes the expression here is a bit complicated, | |||||
# the trick is to only eval ${DIRDEP_LOADAVG_LAST::=${now_utc}} | |||||
# when we want to report. | |||||
DIRDEP_LOADAVG_REPORT = \ | |||||
test -z "${"${expr ${now_utc} - ${DIRDEP_LOADAVG_INTEVAL:U60} - ${DIRDEP_LOADAVG_LAST}:L:sh:N-*}":?yes${DIRDEP_LOADAVG_LAST::=${now_utc}}:}" || \ | |||||
echo "${TRACER}`${DIRDEP_LOADAVG_CMD}`" | |||||
# we suppress SUBDIR when visiting the leaves | # we suppress SUBDIR when visiting the leaves | ||||
# we assume sys.mk will set MACHINE_ARCH | # we assume sys.mk will set MACHINE_ARCH | ||||
# you can add extras to DIRDEP_USE_ENV | # you can add extras to DIRDEP_USE_ENV | ||||
# if there is no makefile in the target directory, we skip it. | # if there is no makefile in the target directory, we skip it. | ||||
_DIRDEP_USE: .USE .MAKE | _DIRDEP_USE: .USE .MAKE | ||||
@for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \ | @for m in ${.MAKE.MAKEFILE_PREFERENCE}; do \ | ||||
test -s ${.TARGET:R}/$$m || continue; \ | test -s ${.TARGET:R}/$$m || continue; \ | ||||
echo "${TRACER}Checking ${.TARGET:R} for ${.TARGET:E} ..."; \ | echo "${TRACER}Checking ${.TARGET:S,${SRCTOP}/,,} for ${.TARGET:E} ..."; \ | ||||
${DIRDEP_USE_PRELUDE} \ | ${DIRDEP_USE_PRELUDE} \ | ||||
MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \ | MACHINE_ARCH= NO_SUBDIR=1 ${DIRDEP_USE_ENV} \ | ||||
TARGET_SPEC=${.TARGET:E} \ | TARGET_SPEC=${.TARGET:E} \ | ||||
MACHINE=${.TARGET:E} \ | MACHINE=${.TARGET:E} \ | ||||
${DIRDEP_MAKE} -C ${DIRDEP_DIR} || exit 1; \ | ${DIRDEP_MAKE} -C ${DIRDEP_DIR} || exit 1; \ | ||||
break; \ | break; \ | ||||
done | done | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
.MAKE.META.IGNORE_FILTER = M*/${.MAKE.DEPENDFILE_PREFIX}* | .MAKE.META.IGNORE_FILTER = M*/${.MAKE.DEPENDFILE_PREFIX}* | ||||
dirdeps: dirdeps-cached | dirdeps: dirdeps-cached | ||||
dirdeps-cached: ${DIRDEPS_CACHE} .MAKE | dirdeps-cached: ${DIRDEPS_CACHE} .MAKE | ||||
@echo "${TRACER}Using ${DIRDEPS_CACHE}" | @echo "${TRACER}Using ${DIRDEPS_CACHE}" | ||||
@MAKELEVEL=${.MAKE.LEVEL} ${.MAKE} -C ${_CURDIR} -f ${DIRDEPS_CACHE} \ | @MAKELEVEL=${.MAKE.LEVEL} ${.MAKE} -C ${_CURDIR} -f ${DIRDEPS_CACHE} \ | ||||
dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no | dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no | ||||
# leaf makefiles rarely work for building DIRDEPS_CACHE | |||||
.if ${RELDIR} != "." | |||||
BUILD_DIRDEPS_MAKEFILE ?= -f dirdeps.mk | |||||
.endif | |||||
# these should generally do | # these should generally do | ||||
BUILD_DIRDEPS_MAKEFILE ?= ${MAKEFILE} | BUILD_DIRDEPS_MAKEFILE ?= | ||||
BUILD_DIRDEPS_TARGETS ?= ${.TARGETS} | BUILD_DIRDEPS_TARGETS ?= ${.TARGETS} | ||||
.if ${DIRDEPS_CACHE} != ${STATIC_DIRDEPS_CACHE:Uno} && ${DIRDEPS_CACHE:M${SRCTOP}/*} == "" | |||||
# export this for dirdeps-cache-update.mk | |||||
DYNAMIC_DIRDEPS_CACHE := ${DIRDEPS_CACHE} | |||||
.export DYNAMIC_DIRDEPS_CACHE | |||||
# we need the .meta file to ensure we update if | # we need the .meta file to ensure we update if | ||||
# any of the Makefile.depend* changed. | # any of the Makefile.depend* changed. | ||||
# We do not want to compare the command line though. | # We do not want to compare the command line though. | ||||
${DIRDEPS_CACHE}: .META .NOMETA_CMP | ${DIRDEPS_CACHE}: .META .NOMETA_CMP | ||||
+@{ echo '# Autogenerated - do NOT edit!'; echo; \ | +@{ echo '# Autogenerated - do NOT edit!'; echo; \ | ||||
echo 'BUILD_DIRDEPS=no'; echo; \ | echo 'BUILD_DIRDEPS=no'; echo; \ | ||||
echo '.include <dirdeps.mk>'; echo; \ | echo '.include <dirdeps.mk>'; echo; \ | ||||
} > ${.TARGET}.new | } > ${.TARGET}.new | ||||
+@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \ | +@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \ | ||||
DIRDEPS="${DIRDEPS}" \ | DIRDEPS="${DIRDEPS}" \ | ||||
TARGET_SPEC=${TARGET_SPEC} \ | TARGET_SPEC=${TARGET_SPEC} \ | ||||
MAKEFLAGS= ${.MAKE} -C ${_CURDIR} -f ${BUILD_DIRDEPS_MAKEFILE} \ | MAKEFLAGS= ${DIRDEP_CACHE_MAKE:U${.MAKE}} -C ${_CURDIR} \ | ||||
${BUILD_DIRDEPS_MAKEFILE} \ | |||||
${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \ | ${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \ | ||||
.MAKE.DEPENDFILE=.none \ | .MAKE.DEPENDFILE=.none \ | ||||
${"${DEBUG_DIRDEPS:Nno}":?DEBUG_DIRDEPS='${DEBUG_DIRDEPS}':} \ | |||||
${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \ | ${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \ | ||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \ | ${.MAKEFLAGS:tW:S,-d ,-d,g:tw:M-d*} \ | ||||
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g;s,_{,$${,g' >> ${.TARGET}.new && \ | |||||
mv ${.TARGET}.new ${.TARGET} | mv ${.TARGET}.new ${.TARGET} | ||||
.endif | .endif | ||||
.endif | |||||
.elif !target(_count_dirdeps) | .elif !target(_count_dirdeps) | ||||
# we want to capture the dirdeps count in the cache | # we want to capture the dirdeps count in the cache | ||||
.END: _count_dirdeps | .END: _count_dirdeps | ||||
_count_dirdeps: .NOMETA | _count_dirdeps: .NOMETA | ||||
@echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]}' >&3 | @{ echo; echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} ${DIRDEP_INFO_XTRAS}'; } >&3 | ||||
.endif | .endif | ||||
.elif !make(dirdeps) && !target(_count_dirdeps) | .elif !make(dirdeps) && !target(_count_dirdeps) | ||||
beforedirdeps: _count_dirdeps | beforedirdeps: _count_dirdeps | ||||
_count_dirdeps: .NOMETA | _count_dirdeps: .NOMETA | ||||
@echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} seconds=`expr ${now_utc} - ${start_utc}`" | @echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} ${DIRDEP_INFO_XTRAS} seconds=`expr ${now_utc} - ${start_utc}`" | ||||
.endif | .endif | ||||
.endif | .endif | ||||
.if ${BUILD_DIRDEPS} == "yes" | .if ${BUILD_DIRDEPS} == "yes" | ||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != "" | |||||
_debug_reldir = 1 | |||||
.else | |||||
_debug_reldir = 0 | |||||
.endif | |||||
.if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} != "" | |||||
_debug_search = 1 | |||||
.else | |||||
_debug_search = 0 | |||||
.endif | |||||
# the rest is done repeatedly for every Makefile.depend we read. | # the rest is done repeatedly for every Makefile.depend we read. | ||||
# if we are anything but the original dir we care only about the | # if we are anything but the original dir we care only about the | ||||
# machine type we were included for.. | # machine type we were included for.. | ||||
.if ${DEP_RELDIR} == "." | .if ${DEP_RELDIR} == "." | ||||
_this_dir := ${SRCTOP} | _this_dir := ${SRCTOP} | ||||
.else | .else | ||||
Show All 35 Lines | |||||
_machines := ${_machines:O:u} | _machines := ${_machines:O:u} | ||||
.endif | .endif | ||||
# reset each time through | # reset each time through | ||||
_build_dirs = | _build_dirs = | ||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR} | .if ${DEP_RELDIR} == ${_DEP_RELDIR} | ||||
# pickup other machines for this dir if necessary | # pickup other machines for this dir if necessary | ||||
.if ${BUILD_AT_LEVEL0:Uyes} == "no" | |||||
_build_dirs += ${_machines:@m@${_CURDIR}.$m@} | _build_dirs += ${_machines:@m@${_CURDIR}.$m@} | ||||
.else | |||||
_build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@} | |||||
.if ${DEP_TARGET_SPEC} == ${TARGET_SPEC} | |||||
# pickup local dependencies now | |||||
.if ${MAKE_VERSION} < 20160220 | |||||
.-include <.depend> | |||||
.else | |||||
.dinclude <.depend> | |||||
.endif | .endif | ||||
.endif | |||||
.endif | |||||
.endif | |||||
.if ${_debug_reldir} | .if ${_debug_reldir} | ||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}' | .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}' | ||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}' | .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}' | ||||
.endif | .endif | ||||
.if !empty(DIRDEPS) | .if !empty(DIRDEPS) | ||||
# these we reset each time through as they can depend on DEP_MACHINE | # these we reset each time through as they can depend on DEP_MACHINE | ||||
Show All 18 Lines | |||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR} | .if ${DEP_RELDIR} == ${_DEP_RELDIR} | ||||
# if it was called out - we likely need it. | # if it was called out - we likely need it. | ||||
__hostdpadd := ${DPADD:U.:M${HOST_OBJTOP}/*:S,${HOST_OBJTOP}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host,:N.*:@d@${SRCTOP}/$d@} \ | __hostdpadd := ${DPADD:U.:M${HOST_OBJTOP}/*:S,${HOST_OBJTOP}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host,:N.*:@d@${SRCTOP}/$d@} \ | ||||
${DPADD:U.:M${HOST_OBJTOP32:Uno}/*:S,${HOST_OBJTOP32:Uno}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host32,:N.*:@d@${SRCTOP}/$d@} | ${DPADD:U.:M${HOST_OBJTOP32:Uno}/*:S,${HOST_OBJTOP32:Uno}/,,:H:${NSkipDir}:${DIRDEPS_FILTER:ts:}:S,$,.host32,:N.*:@d@${SRCTOP}/$d@} | ||||
__qual_depdirs += ${__hostdpadd} | __qual_depdirs += ${__hostdpadd} | ||||
.endif | .endif | ||||
.if ${_debug_reldir} | .if ${_debug_reldir} | ||||
.info DEP_DIRDEPS_FILTER=${DEP_DIRDEPS_FILTER:ts:} | |||||
.info depdirs=${__depdirs} | .info depdirs=${__depdirs} | ||||
.info qualified=${__qual_depdirs} | .info qualified=${__qual_depdirs} | ||||
.info unqualified=${__unqual_depdirs} | .info unqualified=${__unqual_depdirs} | ||||
.endif | .endif | ||||
# _build_dirs is what we will feed to _DIRDEP_USE | # _build_dirs is what we will feed to _DIRDEP_USE | ||||
_build_dirs += \ | _build_dirs += \ | ||||
${__qual_depdirs:M*.host:${NSkipHostDir}:N.host} \ | ${__qual_depdirs:M*.host:${NSkipHostDir}:N.host} \ | ||||
${__qual_depdirs:N*.host} \ | ${__qual_depdirs:N*.host} \ | ||||
${_machines:Mhost*:@m@${__unqual_depdirs:@d@$d.$m@}@:${NSkipHostDir}:N.host} \ | ${_machines:Mhost*:@m@${__unqual_depdirs:@d@$d.$m@}@:${NSkipHostDir}:N.host} \ | ||||
${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@} | ${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@} | ||||
# qualify everything now | # qualify everything now | ||||
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u} | _build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u} | ||||
.endif # empty DIRDEPS | .endif # empty DIRDEPS | ||||
_build_all_dirs += ${_build_dirs} | _build_all_dirs += ${_build_dirs} ${_build_xtra_dirs} | ||||
_build_all_dirs := ${_build_all_dirs:O:u} | _build_all_dirs := ${_build_all_dirs:O:u} | ||||
# Normally if doing make -V something, | # Normally if doing make -V something, | ||||
# we do not want to waste time chasing DIRDEPS | # we do not want to waste time chasing DIRDEPS | ||||
# but if we want to count the number of Makefile.depend* read, we do. | # but if we want to count the number of Makefile.depend* read, we do. | ||||
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == "" | .if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == "" | ||||
.if !empty(_build_all_dirs) | .if !empty(_build_all_dirs) | ||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" | .if ${BUILD_DIRDEPS_CACHE} == "yes" | ||||
# guard against _build_all_dirs being too big for a single command line | x!= echo; { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; } >&3 | ||||
# first get list of dirs that need _DIRDEP_USE | # guard against _new_dirdeps being too big for a single command line | ||||
# then export that and _build_all_dirs | |||||
_new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@} | _new_dirdeps := ${_build_all_dirs:@x@${target($x):?:$x}@} | ||||
.export _new_dirdeps _build_all_dirs | .export _build_xtra_dirs _new_dirdeps | ||||
x!= echo; { echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \ | |||||
echo "dirdeps: \\"; \ | |||||
for x in $$_build_all_dirs; do echo " $$x \\"; done; echo; \ | |||||
for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; echo; } >&3 | |||||
.if !empty(DEP_EXPORT_VARS) | .if !empty(DEP_EXPORT_VARS) | ||||
# Discouraged, but there are always exceptions. | # Discouraged, but there are always exceptions. | ||||
# Handle it here rather than explain how. | # Handle it here rather than explain how. | ||||
x!= { echo; ${DEP_EXPORT_VARS:@v@echo '$v=${$v}';@} echo '.export ${DEP_EXPORT_VARS}'; echo; } >&3; echo | x!= echo; { echo; ${DEP_EXPORT_VARS:@v@echo '$v=${$v}';@} echo '.export ${DEP_EXPORT_VARS}'; echo; } >&3 | ||||
.endif | .endif | ||||
.else | .else | ||||
# this makes it all happen | # this makes it all happen | ||||
dirdeps: ${_build_all_dirs} | dirdeps: ${_build_all_dirs} | ||||
.endif | .endif | ||||
${_build_all_dirs}: _DIRDEP_USE | ${_build_all_dirs}: _DIRDEP_USE | ||||
.if ${_debug_reldir} | .if ${_debug_reldir} | ||||
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs} | .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs} | ||||
.endif | .endif | ||||
.if !empty(DEP_EXPORT_VARS) | .if !empty(DEP_EXPORT_VARS) | ||||
.export ${DEP_EXPORT_VARS} | .export ${DEP_EXPORT_VARS} | ||||
DEP_EXPORT_VARS= | DEP_EXPORT_VARS= | ||||
.endif | .endif | ||||
# this builds the dependency graph | # this builds the dependency graph | ||||
.for m in ${_machines} | .for m in ${_machines} | ||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" && !empty(_build_dirs) | |||||
x!= echo; { echo; echo 'DIRDEPS.${_this_dir}.$m = \'; } >&3 | |||||
_cache_deps = | |||||
.endif | |||||
# it would be nice to do :N${.TARGET} | # it would be nice to do :N${.TARGET} | ||||
.if !empty(__qual_depdirs) | .if !empty(__qual_depdirs) | ||||
.for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m} | .for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m} | ||||
.if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != "" | .if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != "" | ||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q} | .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q} | ||||
.endif | .endif | ||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" | .if ${BUILD_DIRDEPS_CACHE} == "yes" | ||||
_cache_deps := ${_build_dirs:M*.$q} | _cache_deps += ${_build_dirs:M*.$q} | ||||
.export _cache_deps | |||||
x!= echo; { echo "${_this_dir}.$m: \\"; \ | |||||
for x in $$_cache_deps; do echo " $$x \\"; done; echo; } >&3 | |||||
.else | .else | ||||
${_this_dir}.$m: ${_build_dirs:M*.$q} | ${_this_dir}.$m: ${_build_dirs:M*.$q} | ||||
.endif | .endif | ||||
.endfor | .endfor | ||||
.endif | .endif | ||||
.if ${_debug_reldir} | .if ${_debug_reldir} | ||||
.info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m} | .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m} | ||||
.endif | .endif | ||||
.if ${BUILD_DIRDEPS_CACHE} == "yes" | .if ${BUILD_DIRDEPS_CACHE} == "yes" | ||||
_cache_deps := ${_build_dirs:M*.$m:N${_this_dir}.$m} | .if !empty(_build_dirs) | ||||
_cache_deps += ${_build_dirs:M*.$m:N${_this_dir}.$m} | |||||
.if !empty(_cache_deps) | |||||
.export _cache_deps | .export _cache_deps | ||||
x!= echo; { echo "${_this_dir}.$m: \\"; \ | x!= echo; for x in $$_cache_deps; do echo " $$x \\"; done >&3 | ||||
for x in $$_cache_deps; do echo " $$x \\"; done; echo; } >&3 | .endif | ||||
x!= echo; { echo; echo '${_this_dir}.$m: $${DIRDEPS.${_this_dir}.$m}'; \ | |||||
echo; echo 'dirdeps: ${_this_dir}.$m \'; \ | |||||
for x in $$_build_xtra_dirs; do echo " $$x \\"; done; \ | |||||
echo; for x in $$_new_dirdeps; do echo "$$x: _DIRDEP_USE"; done; } >&3 | |||||
.endif | |||||
.else | .else | ||||
${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} | ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} | ||||
.endif | .endif | ||||
.endfor | .endfor | ||||
.endif | .endif | ||||
# Now find more dependencies - and recurse. | # Now find more dependencies - and recurse. | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
.error You should have stopped recursing by now. | .error You should have stopped recursing by now. | ||||
.else | .else | ||||
# we are building something | # we are building something | ||||
DEP_RELDIR := ${RELDIR} | DEP_RELDIR := ${RELDIR} | ||||
_DEP_RELDIR := ${RELDIR} | _DEP_RELDIR := ${RELDIR} | ||||
# Since we are/should be included by .MAKE.DEPENDFILE | # Since we are/should be included by .MAKE.DEPENDFILE | ||||
# This is a final opportunity to add/hook global rules. | # This is a final opportunity to add/hook global rules. | ||||
.-include <local.dirdeps-build.mk> | .-include <local.dirdeps-build.mk> | ||||
# skip _reldir_{finish,failed} if not included from Makefile.depend* | |||||
# or not in meta mode | |||||
.if !defined(WITHOUT_META_STATS) && ${.INCLUDEDFROMFILE:U:M${.MAKE.DEPENDFILE_PREFIX}*} != "" && ${.MAKE.MODE:Mmeta} != "" | |||||
meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \ | |||||
created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}} | |||||
.if !target(_reldir_finish) | |||||
.END: _reldir_finish | |||||
_reldir_finish: .NOMETA | |||||
@echo "${TRACER}Finished ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}" | |||||
.endif | |||||
.if !target(_reldir_failed) | |||||
.ERROR: _reldir_failed | |||||
_reldir_failed: .NOMETA | |||||
@echo "${TRACER}Failed ${RELDIR}.${TARGET_SPEC} seconds=$$(( ${now_utc} - ${start_utc} )) ${meta_stats}" | |||||
.endif | |||||
.endif | |||||
# pickup local dependencies | # pickup local dependencies | ||||
.if ${MAKE_VERSION} < 20160220 | .if ${MAKE_VERSION} < 20160220 | ||||
.-include <.depend> | .-include <.depend> | ||||
.else | .else | ||||
.dinclude <.depend> | .dinclude <.depend> | ||||
.endif | .endif | ||||
.endif | .endif | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |