diff options
Diffstat (limited to 'contrib/bmake/mk/dirdeps.mk')
-rw-r--r-- | contrib/bmake/mk/dirdeps.mk | 161 |
1 files changed, 145 insertions, 16 deletions
diff --git a/contrib/bmake/mk/dirdeps.mk b/contrib/bmake/mk/dirdeps.mk index 8c342be..fd03c82 100644 --- a/contrib/bmake/mk/dirdeps.mk +++ b/contrib/bmake/mk/dirdeps.mk @@ -1,4 +1,4 @@ -# $Id: dirdeps.mk,v 1.35 2014/05/03 06:27:56 sjg Exp $ +# $Id: dirdeps.mk,v 1.49 2015/03/11 21:39:28 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -111,7 +111,9 @@ # TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,} # -.if ${.MAKE.LEVEL} == 0 +# touch this at your peril +_DIRDEP_USE_LEVEL?= 0 +.if ${.MAKE.LEVEL} == ${_DIRDEP_USE_LEVEL} # only the first instance is interested in all this # First off, we want to know what ${MACHINE} to build for. @@ -121,6 +123,12 @@ .if !target(_DIRDEP_USE) # do some setup we only need once _CURDIR ?= ${.CURDIR} +_OBJDIR ?= ${.OBJDIR} + +now_utc = ${%s:L:gmtime} +.if !defined(start_utc) +start_utc := ${now_utc} +.endif # make sure these are empty to start with _DEP_TARGET_SPEC = @@ -201,7 +209,7 @@ _last_dependfile := ${.INCLUDEDFROMFILE:M${.MAKE.DEPENDFILE_PREFIX}*} .else _last_dependfile := ${.MAKE.MAKEFILES:M*/${.MAKE.DEPENDFILE_PREFIX}*:[-1]} .endif -.if !empty(_debug_reldir) +.if ${_debug_reldir:U0} .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _last_dependfile='${_last_dependfile}' .endif @@ -260,7 +268,7 @@ _DEP_RELDIR := ${DEP_RELDIR} # things we skip for host tools SKIP_HOSTDIR ?= -NSkipHostDir = ${SKIP_HOSTDIR:N*.host:S,$,.host,:N.host:${M_ListToSkip}} +NSkipHostDir = ${SKIP_HOSTDIR:N*.host*:S,$,.host*,:N.host*:S,^,${SRCTOP}/,:${M_ListToSkip}} # things we always skip # SKIP_DIRDEPS allows for adding entries on command line. @@ -332,8 +340,78 @@ _only_machines := ${_only_machines:${NOT_MACHINE_LIST:${M_ListToSkip}}} DIRDEPS ?= ${RELDIR} .endif # target -_debug_reldir := ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} -_debug_search := ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.depend:L:M$x}@} +# if repeatedly building the same target, +# we can avoid the overhead of re-computing the tree dependencies. +MK_DIRDEPS_CACHE ?= no +BUILD_DIRDEPS_CACHE ?= no +BUILD_DIRDEPS ?= yes + +.if !defined(NO_DIRDEPS) +.if ${MK_DIRDEPS_CACHE} == "yes" +# this is where we will cache all our work +DIRDEPS_CACHE?= ${_OBJDIR}/dirdeps.cache${.TARGETS:Nall:O:u:ts-:S,^,.,:N.} + +# just ensure this exists +build-dirdeps: + +M_oneperline = @x@\\${.newline} $$x@ + +.if ${BUILD_DIRDEPS_CACHE} == "no" +.if !target(dirdeps-cached) +# we do this via sub-make +BUILD_DIRDEPS = no + +dirdeps: dirdeps-cached +dirdeps-cached: ${DIRDEPS_CACHE} .MAKE + @echo "${TRACER}Using ${DIRDEPS_CACHE}" + @MAKELEVEL=${.MAKE.LEVEL} ${.MAKE} -C ${_CURDIR} -f ${DIRDEPS_CACHE} \ + dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no + +# these should generally do +BUILD_DIRDEPS_MAKEFILE ?= ${MAKEFILE} +BUILD_DIRDEPS_TARGETS ?= ${.TARGETS} + +# we need the .meta file to ensure we update if +# any of the Makefile.depend* changed. +# We do not want to compare the command line though. +${DIRDEPS_CACHE}: .META .NOMETA_CMP + +@{ echo '# Autogenerated - do NOT edit!'; echo; \ + echo 'BUILD_DIRDEPS=no'; echo; \ + echo '.include <dirdeps.mk>'; \ + } > ${.TARGET}.new + +@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \ + DIRDEPS="${DIRDEPS}" \ + MAKEFLAGS= ${.MAKE} -C ${_CURDIR} -f ${BUILD_DIRDEPS_MAKEFILE} \ + ${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \ + 3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \ + mv ${.TARGET}.new ${.TARGET} + +.endif +.elif !target(_count_dirdeps) +# we want to capture the dirdeps count in the cache +.END: _count_dirdeps +_count_dirdeps: .NOMETA + @echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]}' >&3 + +.endif +.endif +.elif !target(_count_dirdeps) +beforedirdeps: _count_dirdeps +_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}`" + +.endif +.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. # if we are anything but the original dir we care only about the @@ -368,7 +446,8 @@ _machines := ${_machines:O:u} # we need to tweak _machines _dm := ${DEP_MACHINE} # apply the same filtering that we do when qualifying DIRDEPS. -_machines := ${_machines:@DEP_MACHINE@${DEP_TARGET_SPEC}@:${M_dep_qual_fixes:ts:}:O:u} +# M_dep_qual_fixes expects .${MACHINE}* so add (and remove) '.' +_machines := ${_machines:@DEP_MACHINE@${DEP_TARGET_SPEC}@:S,^,.,:${M_dep_qual_fixes:ts:}:O:u:S,^.,,} DEP_MACHINE := ${_dm} .endif @@ -388,7 +467,7 @@ _build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@} .endif .endif -.if !empty(_debug_reldir) +.if ${_debug_reldir} .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: DIRDEPS='${DIRDEPS}' .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: _machines='${_machines}' .endif @@ -419,7 +498,7 @@ __hostdpadd := ${DPADD:U.:M${HOST_OBJTOP}/*:S,${HOST_OBJTOP}/,,:H:${NSkipDir}:${ __qual_depdirs += ${__hostdpadd} .endif -.if !empty(_debug_reldir) +.if ${_debug_reldir} .info depdirs=${__depdirs} .info qualified=${__qual_depdirs} .info unqualified=${__unqual_depdirs} @@ -429,7 +508,8 @@ __qual_depdirs += ${__hostdpadd} _build_dirs += \ ${__qual_depdirs:M*.host:${NSkipHostDir}:N.host} \ ${__qual_depdirs:N*.host} \ - ${_machines:@m@${__unqual_depdirs:@d@$d.$m@}@} + ${_machines:Mhost*:@m@${__unqual_depdirs:@d@$d.$m@}@:${NSkipHostDir}:N.host} \ + ${_machines:Nhost*:@m@${__unqual_depdirs:@d@$d.$m@}@} # qualify everything now _build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u} @@ -441,11 +521,17 @@ _build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u} # but if we want to count the number of Makefile.depend* read, we do. .if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == "" .if !empty(_build_dirs) +.if ${BUILD_DIRDEPS_CACHE} == "yes" +x!= { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \ + echo 'dirdeps: ${_build_dirs:${M_oneperline}}'; echo; } >&3; echo +x!= { ${_build_dirs:@x@${target($x):?:echo '$x: _DIRDEP_USE';}@} echo; } >&3; echo +.else # this makes it all happen dirdeps: ${_build_dirs} +.endif ${_build_dirs}: _DIRDEP_USE -.if !empty(_debug_reldir) +.if ${_debug_reldir} .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs} .endif @@ -454,16 +540,24 @@ ${_build_dirs}: _DIRDEP_USE # it would be nice to do :N${.TARGET} .if !empty(__qual_depdirs) .for q in ${__qual_depdirs:${M_dep_qual_fixes:ts:}:E:O:u:N$m} -.if !empty(_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} .endif +.if ${BUILD_DIRDEPS_CACHE} == "yes" +x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$q:${M_oneperline}}'; echo; } >&3; echo +.else ${_this_dir}.$m: ${_build_dirs:M*.$q} +.endif .endfor .endif -.if !empty(_debug_reldir) +.if ${_debug_reldir} .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m} .endif +.if ${BUILD_DIRDEPS_CACHE} == "yes" +x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m:${M_oneperline}}'; echo; } >&3; echo +.else ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} +.endif .endfor .endif @@ -473,7 +567,7 @@ ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m} .if ${_DIRDEP_CHECKED:M$d} == "" # once only _DIRDEP_CHECKED += $d -.if !empty(_debug_search) +.if ${_debug_search} .info checking $d .endif # Note: _build_dirs is fully qualifed so d:R is always the directory @@ -485,14 +579,14 @@ _m := ${.MAKE.DEPENDFILE_PREFERENCE:T:S;${TARGET_SPEC}$;${d:E};:S;${MACHINE};${d .if !empty(_m) # M_dep_qual_fixes isn't geared to Makefile.depend _qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}} -.if !empty(_debug_search) +.if ${_debug_search} .info Looking for ${_qm} .endif # we pass _DEP_TARGET_SPEC to tell the next step what we want _DEP_TARGET_SPEC := ${d:E} # some makefiles may still look at this _DEP_MACHINE := ${d:E:C/,.*//} -.if !empty(_debug_reldir) && ${_qm} != ${_m} +.if ${_debug_reldir} && ${_qm} != ${_m} .info loading ${_m} for ${d:E} .endif .include <${_m}> @@ -502,6 +596,7 @@ _DEP_MACHINE := ${d:E:C/,.*//} .endfor .endif # -V +.endif # BUILD_DIRDEPS .elif ${.MAKE.LEVEL} > 42 .error You should have stopped recursing by now. @@ -511,3 +606,37 @@ _DEP_RELDIR := ${DEP_RELDIR} .-include <.depend> .endif +# bootstrapping new dependencies made easy? +.if make(bootstrap*) && !target(bootstrap) + +.if exists(${.CURDIR}/${.MAKE.DEPENDFILE:T}) +# stop here +${.TARGETS:Mboot*}: +.else +# find a Makefile.depend to use as _src +_src != cd ${.CURDIR} && for m in ${.MAKE.DEPENDFILE_PREFERENCE:T:S,${MACHINE},*,}; do test -s $$m || continue; echo $$m; break; done; echo +.if empty(_src) +.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T} +.endif + +_src?= ${.MAKE.DEPENDFILE:T} + +bootstrap-this: .NOTMAIN + @echo Bootstrapping ${RELDIR}/${.MAKE.DEPENDFILE:T} from ${_src:T} + (cd ${.CURDIR} && sed 's,${_src:E},${MACHINE},g' ${_src} > ${.MAKE.DEPENDFILE:T}) + +bootstrap: bootstrap-recurse +bootstrap-recurse: bootstrap-this + +_mf := ${.PARSEFILE} +bootstrap-recurse: .NOTMAIN .MAKE + @cd ${SRCTOP} && \ + for d in `cd ${RELDIR} && ${.MAKE} -B -f ${"${.MAKEFLAGS:M-n}":?${_src}:${.MAKE.DEPENDFILE:T}} -V DIRDEPS`; do \ + test -d $$d || d=$${d%.*}; \ + test -d $$d || continue; \ + echo "Checking $$d for bootstrap ..."; \ + (cd $$d && ${.MAKE} -f ${_mf} bootstrap-recurse); \ + done + +.endif +.endif |