diff options
author | Simon J. Gerraty <sjg@FreeBSD.org> | 2015-04-20 03:45:54 +0000 |
---|---|---|
committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2015-04-20 03:45:54 +0000 |
commit | 023e89e5efa694577b481488bb5ea251d3ec1966 (patch) | |
tree | b6c6c2921ca62b71b7bec9a475156de3f868a10f /mk | |
parent | 769742d3aff97a7f08b820ddad980fd0afacfb3a (diff) |
Notes
Diffstat (limited to 'mk')
-rw-r--r-- | mk/ChangeLog | 108 | ||||
-rw-r--r-- | mk/FILES | 4 | ||||
-rw-r--r-- | mk/auto.dep.mk | 4 | ||||
-rw-r--r-- | mk/auto.obj.mk | 9 | ||||
-rw-r--r-- | mk/autodep.mk | 7 | ||||
-rw-r--r-- | mk/cython.mk | 96 | ||||
-rw-r--r-- | mk/dep.mk | 14 | ||||
-rw-r--r-- | mk/dirdeps.mk | 161 | ||||
-rw-r--r-- | mk/gendirdeps.mk | 13 | ||||
-rw-r--r-- | mk/install-mk | 4 | ||||
-rw-r--r-- | mk/links.mk | 13 | ||||
-rw-r--r-- | mk/manifest.mk | 66 | ||||
-rw-r--r-- | mk/meta.autodep.mk | 5 | ||||
-rw-r--r-- | mk/meta.stage.mk | 39 | ||||
-rw-r--r-- | mk/meta.sys.mk | 20 | ||||
-rwxr-xr-x | mk/meta2deps.py | 220 | ||||
-rwxr-xr-x | mk/meta2deps.sh | 30 | ||||
-rw-r--r-- | mk/mk-files.txt | 20 | ||||
-rwxr-xr-x | mk/mkopt.sh | 94 | ||||
-rw-r--r-- | mk/own.mk | 4 | ||||
-rw-r--r-- | mk/sys.dependfile.mk | 8 | ||||
-rw-r--r-- | mk/whats.mk | 63 |
22 files changed, 842 insertions, 160 deletions
diff --git a/mk/ChangeLog b/mk/ChangeLog index 80671ef13f00..597d81458827 100644 --- a/mk/ChangeLog +++ b/mk/ChangeLog @@ -1,3 +1,111 @@ +2015-04-16 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20150411 + bump version + + * own.mk: put AUTO_OBJ in OPTIONS_DEFAULT_NO rather than YES. + it is here mainly for documentation purposes, since + if using auto.obj.mk it is better done via sys.mk + +2015-04-01 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20150401 + + * meta2deps.sh: support @list + + * meta2deps.py: updates from Juniper + o add EXCLUDES + o skip bogus input files. + o treat 'M' and 'L' as both an 'R' and a 'W' + +2015-03-03 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20150303 + + * dirdeps.mk: if MK_DIRDEPS_CACHE is yes, use dirdeps-cache + which is built via sub-make so we have a .meta file to tell if + it is out-of-date. + The dirdeps-cache contains the same dependency rules that we + normaly construct on the fly. + This adds a few seconds overhead when the cache is out of date, + but for a large target, the savings can be significant (10-20min). + +2014-11-18 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20141118 + + * meta.stage.mk: add stale_staged + + * dirdeps.mk (_DIRDEP_USE_LEVEL): allow this to be tweaked + only useful under very rare conditions such as + FreeBSD's make universe. + + * auto.obj.mk: Allow MK_AUTO_OBJ to set MKOBJDIRS=auto + +2014-11-11 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20141111 + + * mkopt.sh: use consistent semantics for _mk_opt and _mk_opts + +2014-11-09 Simon J. Gerraty <sjg@bad.crufty.net> + + * FILES: include mkopt.sh which allows handling options in shell + scripts in a manner compatible with options.mk + +2014-10-12 Simon J. Gerraty <sjg@bad.crufty.net> + + * meta.stage.mk: ensure only _STAGED_DIRS under objroot are used + for GENDIRDEPS_FILTER to avoid surprises. + +2014-10-10 Simon J. Gerraty <sjg@bad.crufty.net> + + * dirdeps.mk (NSkipHostDir): this needs SRCTOP prepended since by + the time it is applied to __depdirs they have. + + * dirdeps.mk fix filtering of _machines since M_dep_qual_fixes + expects patterns like *.${MACHINE} + + * cython.mk (pyprefix?): use pyprefix to find python bits + since prefix might be something else (where we install our + stuff) + +2014-09-11 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20140911 + + * dirdeps.mk: add bootstrap target to simplify adding support for + new MACHINE. + +2014-09-01 Simon J. Gerraty <sjg@bad.crufty.net> + + * gendirdeps.mk: Add handling of GENDIRDEPS_FILTER_DIR_VARS and + GENDIRDEPS_FILTER_VARS to make it easier to produce sharable + Makefile.depend files. + +2014-08-28 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20140828 + + * cython.mk: capture logic for building python extension modules + with Cython. + +2014-08-08 Simon J. Gerraty <sjg@bad.crufty.net> + + * meta.stage.mk (_STAGE_AS_BASENAME_USE): Add StageAs variant + +2014-08-02 Simon J. Gerraty <sjg@bad.crufty.net> + + * install-mk (MK_VERSION): 20140801 + + * dep.mk: use explicit MKDEP_MK rather than overload MKDEP to + identify the autodep.mk variant. + + * sys.dependfile.mk: delete .MAKE.DEPENDFILE if its + initial value does not match .MAKE.DEPENDFILE_PREFIX + + * meta.autodep.mk: if _bootstrap_dirdeps add RELDIR to DIRDEPS + 2014-05-22 Simon J. Gerraty <sjg@bad.crufty.net> * install-mk (MK_VERSION): 20140522 @@ -5,6 +5,7 @@ auto.obj.mk autoconf.mk autodep.mk auto.dep.mk +cython.mk dep.mk doc.mk dpadd.mk @@ -20,7 +21,9 @@ libnames.mk libs.mk links.mk man.mk +manifest.mk mk-files.txt +mkopt.sh nls.mk obj.mk options.mk @@ -49,6 +52,7 @@ sys/SunOS.mk sys/UnixWare.mk target-flags.mk warnings.mk +whats.mk yacc.mk dirdeps.mk gendirdeps.mk diff --git a/mk/auto.dep.mk b/mk/auto.dep.mk index bb2d4c195a77..33137248d450 100644 --- a/mk/auto.dep.mk +++ b/mk/auto.dep.mk @@ -1,6 +1,6 @@ # # RCSid: -# $Id: auto.dep.mk,v 1.2 2010/04/19 17:37:19 sjg Exp $ +# $Id: auto.dep.mk,v 1.3 2014/08/04 05:19:10 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty # @@ -18,7 +18,7 @@ # This module provides automagic dependency generation along the # lines suggested in the GNU make.info -# set MKDEP=auto.dep and dep.mk will include us +# set MKDEP_MK=auto.dep.mk and dep.mk will include us # This version differs from autodep.mk, in that # we use ${.TARGET:T}.d rather than ${.TARGET:T:R}.d diff --git a/mk/auto.obj.mk b/mk/auto.obj.mk index adccd4b87c8c..e25a721cdf69 100644 --- a/mk/auto.obj.mk +++ b/mk/auto.obj.mk @@ -1,4 +1,4 @@ -# $Id: auto.obj.mk,v 1.8 2011/08/08 17:35:20 sjg Exp $ +# $Id: auto.obj.mk,v 1.10 2015/04/16 16:59:00 sjg Exp $ # # @(#) Copyright (c) 2004, Simon J. Gerraty # @@ -34,10 +34,14 @@ Mkdirs= Mkdirs() { \ # if MKOBJDIRS is set to auto (and NOOBJ isn't defined) do some magic... # This will automatically create objdirs as needed. # Skip it if we are just doing 'clean'. +.if ${MK_AUTO_OBJ:Uno} == "yes" +MKOBJDIRS= auto +.endif .if !defined(NOOBJ) && !defined(NO_OBJ) && ${MKOBJDIRS:Uno} == auto # Use __objdir here so it is easier to tweak without impacting # the logic. __objdir?= ${MAKEOBJDIR} +__objdir:= ${__objdir:tA} .if ${.OBJDIR} != ${__objdir} # We need to chdir, make the directory if needed .if !exists(${__objdir}/) && \ @@ -46,11 +50,12 @@ __objdir?= ${MAKEOBJDIR} __objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \ ${ECHO_TRACE} "[Creating objdir ${__objdir}...]" >&2; \ ${Mkdirs}; Mkdirs ${__objdir} +__objdir:= ${__objdir:tA} .endif # This causes make to use the specified directory as .OBJDIR .OBJDIR: ${__objdir} .if ${.OBJDIR} != ${__objdir} && ${__objdir_made:Uno:M${__objdir}/*} != "" -.error could not use ${__objdir} +.error could not use ${__objdir}: .OBJDIR=${.OBJDIR} .endif .endif .endif diff --git a/mk/autodep.mk b/mk/autodep.mk index 818c474e843f..84dea816fa35 100644 --- a/mk/autodep.mk +++ b/mk/autodep.mk @@ -1,6 +1,6 @@ # # RCSid: -# $Id: autodep.mk,v 1.33 2014/04/05 22:56:54 sjg Exp $ +# $Id: autodep.mk,v 1.34 2014/08/04 05:12:27 sjg Exp $ # # @(#) Copyright (c) 1999-2010, Simon J. Gerraty # @@ -19,14 +19,9 @@ # The depend target is mainly for backwards compatibility, # dependencies are normally updated as part of compilation. -# set MKDEP=autodep and dep.mk will include us .if !target(__${.PARSEFILE}__) __${.PARSEFILE}__: -# different versions of bsd.dep.mk use these -MKDEP=autodep -MKDEPCMD=autodep - DEPENDFILE?= .depend .for d in ${DEPENDFILE:N.depend} # bmake only groks .depend diff --git a/mk/cython.mk b/mk/cython.mk new file mode 100644 index 000000000000..7d9b8cd6a5b5 --- /dev/null +++ b/mk/cython.mk @@ -0,0 +1,96 @@ +# RCSid: +# $Id: cython.mk,v 1.6 2014/10/15 06:23:51 sjg Exp $ +# +# @(#) Copyright (c) 2014, Simon J. Gerraty +# +# This file is provided in the hope that it will +# be of use. There is absolutely NO WARRANTY. +# Permission to copy, redistribute or otherwise +# use this file is hereby granted provided that +# the above copyright notice and this notice are +# left intact. +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net +# + +# this is what we build +CYTHON_MODULE = ${CYTHON_MODULE_NAME}${CYTHON_PYVERSION}.so + +CYTHON_MODULE_NAME?= it +CYTHON_SRCS?= ${CYTHON_MODULE_NAME}.pyx + +# this is where we save generated src +CYTHON_SAVEGENDIR?= ${.CURDIR}/gen + +# pyprefix is where python bits are +# which may not be where we want to put ours (prefix) +.if exists(/usr/pkg/include) +pyprefix?= /usr/pkg +.endif +pyprefix?= /usr/local + +PYTHON_VERSION?= 2.7 +PYTHON_H?= ${pyprefix}/include/python${PYTHON_VERSION}/Python.h +PYVERSION:= ${PYTHON_VERSION:C,\..*,,} + +# set this empty if you don't want to handle multiple versions +.if !defined(CYTHON_PYVERSION) +CYTHON_PYVERSION:= ${PYVERSION} +.endif + +CFLAGS+= -I${PYTHON_H:H} + +CYTHON_GENSRCS= ${CYTHON_SRCS:R:S,$,${CYTHON_PYVERSION}.c,} +SRCS+= ${CYTHON_GENSRCS} + +.SUFFIXES: .pyx .c .So + +CYTHON?= ${pyprefix}/bin/cython + +# if we don't have cython we can use pre-generated srcs +.if ${type ${CYTHON} 2> /dev/null || echo:L:sh:M/*} == "" +.PATH: ${CYTHON_SAVEGENDIR} +.else + +.if !empty(CYTHON_PYVERSION) +.for c in ${CYTHON_SRCS} +${c:R}${CYTHON_PYVERSION}.${c:E}: $c + ln -sf ${.ALLSRC:M*pyx} ${.TARGET} +.endfor +.endif + +.pyx.c: + ${CYTHON} ${CYTHON_FLAGS} -${PYVERSION} -o ${.TARGET} ${.IMPSRC} + + +save-gen: ${CYTHON_GENSRCS} + mkdir -p ${CYTHON_SAVEGENDIR} + cp -p ${.ALLSRC} ${CYTHON_SAVEGENDIR} + +.endif + +COMPILE.c?= ${CC} -c ${CFLAGS} + +.c.So: + ${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET} + +${CYTHON_MODULE}: ${SRCS:S,.c,.So,} + ${CC} ${CC_SHARED:U-shared} -o ${.TARGET} ${.ALLSRC:M*.So} ${LDADD} + +# conf.host_target() is limited to uname -m rather than uname -p +_HOST_MACHINE!= uname -m +.if ${HOST_TARGET:M*${_HOST_MACHINE}} == "" +PY_HOST_TARGET:= ${HOST_TARGET:S,${_HOST_ARCH:U${uname -p:L:sh}}$,${_HOST_MACHINE},} +.endif + +MODULE_BINDIR?= ${.CURDIR:H}/${PY_HOST_TARGET:U${HOST_TARGET}} + +build-cython-module: ${CYTHON_MODULE} + +install-cython-module: ${CYTHON_MODULE} + test -d ${DESTDIR}${MODULE_BINDIR} || \ + ${INSTALL} -d ${DESTDIR}${MODULE_BINDIR} + ${INSTALL} -m 755 ${.ALLSRC} ${DESTDIR}${MODULE_BINDIR} + +CLEANFILES+= *.So ${CYTHON_MODULE} diff --git a/mk/dep.mk b/mk/dep.mk index b75450097277..b07191a09cbf 100644 --- a/mk/dep.mk +++ b/mk/dep.mk @@ -1,4 +1,4 @@ -# $Id: dep.mk,v 1.16 2012/11/11 22:37:02 sjg Exp $ +# $Id: dep.mk,v 1.17 2014/08/04 05:12:27 sjg Exp $ .if !target(__${.PARSEFILE}__) __${.PARSEFILE}__: @@ -34,21 +34,15 @@ MKDEP ?= ${MKDEP_CMD} .NOPATH: .depend -.if ${MKDEP} == "auto.dep" && make(depend) +.if ${MKDEP_MK:Uno} == "auto.dep.mk" && make(depend) # auto.dep.mk does not "do" depend MK_AUTODEP= no .endif .if ${MK_AUTODEP} == yes -.if ${MKDEP:T:S,auto,,} != ${MKDEP:T} -.include <${MKDEP}.mk> +MKDEP_MK ?= autodep.mk +.include <${MKDEP_MK}> .else -.include <autodep.mk> -.endif -.else -.if ${MKDEP:T:S,auto,,} != ${MKDEP:T} -MKDEP = ${MKDEP_CMD} -.endif MKDEP_ENV_VARS += CC CXX .for v in ${MKDEP_ENV_VARS:O:u} .if !empty($v) diff --git a/mk/dirdeps.mk b/mk/dirdeps.mk index 8c342be86fc2..fd03c827578e 100644 --- a/mk/dirdeps.mk +++ b/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 diff --git a/mk/gendirdeps.mk b/mk/gendirdeps.mk index b313298b3fef..28e1f21652ad 100644 --- a/mk/gendirdeps.mk +++ b/mk/gendirdeps.mk @@ -1,4 +1,4 @@ -# $Id: gendirdeps.mk,v 1.25 2014/03/14 21:28:37 sjg Exp $ +# $Id: gendirdeps.mk,v 1.26 2014/09/05 04:40:52 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -93,6 +93,17 @@ _skip_gendirdeps = egrep -v '^(${SKIP_GENDIRDEPS:O:u:ts|})' | _skip_gendirdeps = .endif +# Below we will turn _{VAR} into ${VAR} which keeps this simple +# GENDIRDEPS_FILTER_DIR_VARS is a list of dirs to be substiuted for. +# GENDIRDEPS_FILTER_VARS is more general. +# In each case order matters. +.if !empty(GENDIRDEPS_FILTER_DIR_VARS) +GENDIRDEPS_FILTER += ${GENDIRDEPS_FILTER_DIR_VARS:@v@S,${$v},_{${v}},@} +.endif +.if !empty(GENDIRDEPS_FILTER_VARS) +GENDIRDEPS_FILTER += ${GENDIRDEPS_FILTER_VARS:@v@S,/${$v}/,/_{${v}}/,@:NS,//,*:u} +.endif + # this (*should* be set in meta.sys.mk) # is the script that extracts what we want. META2DEPS ?= ${.PARSEDIR}/meta2deps.sh diff --git a/mk/install-mk b/mk/install-mk index 7e4ee8bba5e7..047fcfda9280 100644 --- a/mk/install-mk +++ b/mk/install-mk @@ -55,7 +55,7 @@ # Simon J. Gerraty <sjg@crufty.net> # RCSid: -# $Id: install-mk,v 1.100 2014/05/23 01:30:36 sjg Exp $ +# $Id: install-mk,v 1.109 2015/04/16 16:59:00 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -70,7 +70,7 @@ # sjg@crufty.net # -MK_VERSION=20140522 +MK_VERSION=20150411 OWNER= GROUP= MODE=444 diff --git a/mk/links.mk b/mk/links.mk index 4ec8a01c415c..aac3914fdd00 100644 --- a/mk/links.mk +++ b/mk/links.mk @@ -1,4 +1,4 @@ -# $Id: links.mk,v 1.5 2005/07/11 18:01:05 sjg Exp $ +# $Id: links.mk,v 1.6 2014/09/29 17:14:40 sjg Exp $ # # @(#) Copyright (c) 2005, Simon J. Gerraty # @@ -22,9 +22,14 @@ SYMLINKS?= __SYMLINK_SCRIPT= \ ${ECHO} "$$t -> $$l"; \ - mkdir -p `dirname $$t`; \ - rm -f $$t; \ - ${LN} -s $$l $$t + case `'ls' -l $$t 2> /dev/null` in \ + *"> $$l") ;; \ + *) \ + mkdir -p `dirname $$t`; \ + rm -f $$t; \ + ${LN} -s $$l $$t;; \ + esac + __LINK_SCRIPT= \ ${ECHO} "$$t -> $$l"; \ diff --git a/mk/manifest.mk b/mk/manifest.mk new file mode 100644 index 000000000000..797038d19391 --- /dev/null +++ b/mk/manifest.mk @@ -0,0 +1,66 @@ +# $Id: manifest.mk,v 1.2 2014/10/31 18:06:17 sjg Exp $ +# +# @(#) Copyright (c) 2014, Simon J. Gerraty +# +# This file is provided in the hope that it will +# be of use. There is absolutely NO WARRANTY. +# Permission to copy, redistribute or otherwise +# use this file is hereby granted provided that +# the above copyright notice and this notice are +# left intact. +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net +# + +# generate mtree style manifest supported by makefs in FreeBSD + +# input looks like +# MANIFEST= my.mtree +# for each MANIFEST we have a list of dirs +# ${MANIFEST}.DIRS += bin sbin usr/bin ... +# for each dir we have a ${MANIFEST}.SRCS.$dir +# that provides the absolute path to the contents +# ${MANIFEST}.SRCS.bin += ${OBJTOP}/bin/sh/sh +# ${MANIFEST}.SYMLINKS is a list of src target pairs +# for each file/dir there are a number of attributes +# UID GID MODE FLAGS +# which can be set per dir, per file or we use defaults +# eg. +# MODE.sbin = 550 +# MODE.usr/sbin = 550 +# MODE.dirs = 555 +# means that sbin and usr/sbin get 550 all other dirs get 555 +# MODE.usr/bin/passwd = 4555 +# MODE.usr/bin.files = 555 +# MODE.usr/sbin.files = 500 +# means passwd gets 4555 other files in usr/bin get 555 and +# files in usr/sbin get 500 +# STORE defaults to basename of src and target directory +# but we can use +# ${MANIFEST}.SRCS.sbin += ${OBJTOP}/bin/sh-static/sh-static +# STORE.sbin/sh-static = sbin/sh +# +# the above is a little overkill but means we can easily adapt to +# different formats + +UID.dirs ?= 0 +GID.dirs ?= 0 +MODE.dirs ?= 775 +FLAGS.dirs ?= + +UID.files ?= 0 +GID.files ?= 0 +MODE.files ?= 555 + +# a is attribute name d is dirname +M_DIR_ATTR = L:@a@$${$$a.$$d:U$${$$a.dirs}}@ +# as above and s is set to the name we store f as +M_FILE_ATTR = L:@a@$${$$a.$$s:U$${$$a.$$d.files:U$${$$a.files}}}@ + +# this produces the body of the manifest +# there should typically be a header prefixed +_GEN_MTREE_MANIFEST_USE: .USE + @(${${.TARGET}.DIRS:O:u:@d@echo '$d type=dir uid=${UID:${M_DIR_ATTR}} gid=${GID:${M_DIR_ATTR}} mode=${MODE:${M_DIR_ATTR}} ${FLAGS:${M_DIR_ATTR}}';@} \ + ${${.TARGET}.DIRS:O:u:@d@${${.TARGET}.SRCS.$d:O:u:@f@echo '${s::=${STORE.$d/${f:T}:U$d/${f:T}}}$s contents="$f" type=file uid=${UID:${M_FILE_ATTR}} gid=${GID:${M_FILE_ATTR}} mode=${MODE:${M_FILE_ATTR}} ${FLAGS:${M_FILE_ATTR}}';@}@} \ + set ${${.TARGET}.SYMLINKS}; while test $$# -ge 2; do echo "$$2 type=link link=$$1"; shift 2; done) > ${.TARGET} diff --git a/mk/meta.autodep.mk b/mk/meta.autodep.mk index a961bffb4646..64bc30bd4757 100644 --- a/mk/meta.autodep.mk +++ b/mk/meta.autodep.mk @@ -1,4 +1,4 @@ -# $Id: meta.autodep.mk,v 1.35 2014/05/09 00:05:46 sjg Exp $ +# $Id: meta.autodep.mk,v 1.36 2014/08/02 23:10:29 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -254,6 +254,9 @@ ${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk ${META2DEPS} $${.MAKE.MET .endif .if ${_bootstrap_dirdeps} == "yes" +.if ${BUILD_AT_LEVEL0:Uno} == "no" +DIRDEPS+= ${RELDIR}.${TARGET_SPEC:U${MACHINE}} +.endif # make sure this is included at least once .include <dirdeps.mk> .else diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk index 2f02700fdc19..cd951136fb72 100644 --- a/mk/meta.stage.mk +++ b/mk/meta.stage.mk @@ -1,4 +1,4 @@ -# $Id: meta.stage.mk,v 1.30 2013/04/19 16:32:57 sjg Exp $ +# $Id: meta.stage.mk,v 1.34 2014/11/20 22:40:08 sjg Exp $ # # @(#) Copyright (c) 2011, Simon J. Gerraty # @@ -35,7 +35,13 @@ _stage_file_basename = $${f\#\#*/} _stage_target_dirname = $${t%/*} .endif +_OBJROOT ?= ${OBJROOT:U${OBJTOP:H}} +.if ${_OBJROOT:M*/} != "" +_objroot ?= ${_OBJROOT:tA}/ +.else _objroot ?= ${_OBJROOT:tA} +.endif + # make sure this is global _STAGED_DIRS ?= .export _STAGED_DIRS @@ -46,7 +52,7 @@ STAGE_DIR_FILTER = tA:@d@$${_STAGED_DIRS::+=$$d}$$d@ # convert _STAGED_DIRS into suitable filters GENDIRDEPS_FILTER += Nnot-empty-is-important \ ${_STAGED_DIRS:O:u:M${OBJTOP}*:S,${OBJTOP}/,N,} \ - ${_STAGED_DIRS:O:u:N${OBJTOP}*:S,${_objroot},,:C,^([^/]+)/(.*),N\2.\1,:S,${HOST_TARGET},.host,} + ${_STAGED_DIRS:O:u:M${_objroot}*:N${OBJTOP}*:S,${_objroot},,:C,^([^/]+)/(.*),N\2.\1,:S,${HOST_TARGET},.host,} LN_CP_SCRIPT = LnCp() { \ rm -f $$2 2> /dev/null; \ @@ -113,10 +119,14 @@ STAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \ _STAGE_BASENAME_USE: .USE ${.TARGET:T} @${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} +_STAGE_AS_BASENAME_USE: .USE ${.TARGET:T} + @${STAGE_AS_SCRIPT}; StageAs ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} ${STAGE_AS_${.TARGET:T}:U${.TARGET:T}} + .if !empty(STAGE_INCSDIR) STAGE_TARGETS += stage_incs STAGE_INCS ?= ${.ALLSRC:N.dirdep} +stage_includes: stage_incs stage_incs: .dirdep @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR:${STAGE_DIR_FILTER}} ${STAGE_INCS} @touch $@ @@ -129,12 +139,14 @@ STAGE_LIBS ?= ${.ALLSRC:N.dirdep} stage_libs: .dirdep @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS} +.if !defined(NO_SHLIB_LINKS) .if !empty(SHLIB_LINKS) @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} \ ${SHLIB_LINKS:@t@${STAGE_LIBS:T:M$t.*} $t@} .elif !empty(SHLIB_LINK) && !empty(SHLIB_NAME) @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${SHLIB_NAME} ${SHLIB_LINK} ${SYMLINKS:T} .endif +.endif @touch $@ .endif @@ -212,7 +224,7 @@ stage_as.$s: .dirdep .endfor .endif -CLEANFILES += ${STAGE_TARGETS} +CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes # stage_*links usually needs to follow any others. .for t in ${STAGE_TARGETS:N*links:O:u} @@ -240,5 +252,26 @@ INSTALL := ${STAGE_INSTALL} beforeinstall: .dirdep .endif .endif +.NOPATH: ${STAGE_FILES} + +.if !empty(STAGE_TARGETS) +MK_STALE_STAGED?= no +.if ${MK_STALE_STAGED} == "yes" +all: stale_staged +# get a list of paths that we have just staged +# get a list of paths that we have previously staged to those same dirs +# anything in the 2nd list but not the first is stale - remove it. +stale_staged: staging .NOMETA + @egrep '^[WL] .*${STAGE_OBJTOP}' /dev/null ${.MAKE.META.FILES:M*stage_*} | \ + sed "/\.dirdep/d;s,.* '*\(${STAGE_OBJTOP}/[^ '][^ ']*\).*,\1," | \ + sort > ${.TARGET}.staged1 + @grep -l '${_dirdep}' /dev/null ${_STAGED_DIRS:M${STAGE_OBJTOP}*:O:u:@d@$d/*.dirdep@} | \ + sed 's,\.dirdep,,' | sort > ${.TARGET}.staged2 + @comm -13 ${.TARGET}.staged1 ${.TARGET}.staged2 > ${.TARGET}.stale + @test ! -s ${.TARGET}.stale || { \ + echo "Removing stale staged files..."; \ + sed 's,.*,& &.dirdep,' ${.TARGET}.stale | xargs rm -f; } .endif +.endif +.endif diff --git a/mk/meta.sys.mk b/mk/meta.sys.mk index 1707a6670bb5..bcafd5593212 100644 --- a/mk/meta.sys.mk +++ b/mk/meta.sys.mk @@ -1,4 +1,4 @@ -# $Id: meta.sys.mk,v 1.16 2012/07/03 05:26:00 sjg Exp $ +# $Id: meta.sys.mk,v 1.20 2014/08/04 05:12:27 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -106,7 +106,13 @@ _metaError: .NOMETA .NOTMAIN # Are we, after all, in meta mode? .if ${.MAKE.MODE:Mmeta*} != "" -MKDEP = meta.autodep +MKDEP_MK = meta.autodep.mk + +# if we think we are updating dependencies, +# then filemon had better be present +.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no" && !exists(/dev/filemon) +.error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded. +.endif .if ${.MAKE.LEVEL} == 0 # make sure dirdeps target exists and do it first @@ -121,19 +127,11 @@ dirdeps: # tell dirdeps.mk what we want BUILD_AT_LEVEL0 = no .endif - -.if ${.MAKE.DEPENDFILE:E} == ${MACHINE} +.if ${.TARGETS:Nall} == "" # it works best if we do everything via sub-makes BUILD_AT_LEVEL0 ?= no .endif -BUILD_AT_LEVEL0 ?= yes -.endif -# if we think we are updating dependencies, -# then filemon had better be present -.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no" && !exists(/dev/filemon) -.error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded. .endif - .endif .endif diff --git a/mk/meta2deps.py b/mk/meta2deps.py index 8e349e702e5b..ed183f0b944c 100755 --- a/mk/meta2deps.py +++ b/mk/meta2deps.py @@ -37,7 +37,7 @@ We only pay attention to a subset of the information in the """ RCSid: - $Id: meta2deps.py,v 1.17 2014/04/05 22:56:54 sjg Exp $ + $Id: meta2deps.py,v 1.18 2015/04/03 18:23:25 sjg Exp $ Copyright (c) 2011-2013, Juniper Networks, Inc. All rights reserved. @@ -112,7 +112,8 @@ def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr): rpath = resolve(path, cwd, last_dir, debug, debug_out) if rpath: path = rpath - if (path.find('./') > 0 or + if (path.find('/') < 0 or + path.find('./') > 0 or path.endswith('/..') or os.path.islink(path)): return os.path.realpath(path) @@ -142,7 +143,7 @@ class MetaFile: host_target = None srctops = [] objroots = [] - + excludes = [] seen = {} obj_deps = [] src_deps = [] @@ -179,6 +180,10 @@ class MetaFile: This can allow 'bmake' to learn all the dirs within the tree that depend on 'foo.h' + EXCLUDES + A list of paths to ignore. + ccache(1) can otherwise be trouble. + debug desired debug level debug_out open file to send debug output to (sys.stderr) @@ -236,11 +241,14 @@ class MetaFile: # we want the longest match self.srctops.sort(reverse=True) self.objroots.sort(reverse=True) - + + self.excludes = getv(conf, 'EXCLUDES', []) + if self.debug: print("host_target=", self.host_target, file=self.debug_out) print("srctops=", self.srctops, file=self.debug_out) print("objroots=", self.objroots, file=self.debug_out) + print("excludes=", self.excludes, file=self.debug_out) self.dirdep_re = re.compile(r'([^/]+)/(.+)') @@ -257,6 +265,7 @@ class MetaFile: self.dpdeps = None # we cannot do it? self.cwd = os.getcwd() # make sure this is initialized + self.last_dir = self.cwd if name: self.try_parse() @@ -360,18 +369,18 @@ class MetaFile: V 3 C "pid" "cwd" E "pid" "path" - F "pid" "child" + F "pid" "child" R "pid" "path" W "pid" "path" X "pid" "status" - D "pid" "path" - L "pid" "src" "target" - M "pid" "old" "new" - S "pid" "path" - # Bye bye - - We go to some effort to avoid processing a dependency more than once. - Of the above record types only C,E,F,L,R,V and W are of interest. + D "pid" "path" + L "pid" "src" "target" + M "pid" "old" "new" + S "pid" "path" + # Bye bye + + We go to some effort to avoid processing a dependency more than once. + Of the above record types only C,E,F,L,R,V and W are of interest. """ version = 0 # unknown @@ -379,7 +388,7 @@ class MetaFile: self.name = name; if file: f = file - cwd = last_dir = self.cwd + cwd = self.last_dir = self.cwd else: f = open(self.name, 'r') skip = True @@ -412,7 +421,7 @@ class MetaFile: interesting += 'W' """ elif w[0] == 'CWD': - self.cwd = cwd = last_dir = w[1] + self.cwd = cwd = self.last_dir = w[1] self.seenit(cwd) # ignore this if self.debug: print("%s: CWD=%s" % (self.name, cwd), file=self.debug_out) @@ -422,9 +431,9 @@ class MetaFile: if pid != last_pid: if last_pid: pid_cwd[last_pid] = cwd - pid_last_dir[last_pid] = last_dir + pid_last_dir[last_pid] = self.last_dir cwd = getv(pid_cwd, pid, self.cwd) - last_dir = getv(pid_last_dir, pid, self.cwd) + self.last_dir = getv(pid_last_dir, pid, self.cwd) last_pid = pid # process operations @@ -438,7 +447,7 @@ class MetaFile: cwd = abspath(w[2], cwd, None, self.debug, self.debug_out) if cwd.endswith('/.'): cwd = cwd[0:-2] - last_dir = cwd + self.last_dir = cwd if self.debug > 1: print("cwd=", cwd, file=self.debug_out) continue @@ -449,98 +458,114 @@ class MetaFile: continue # file operations if w[0] in 'ML': - path = w[2].strip("'") - else: - path = w[2] - # we are never interested in .dirdep files as dependencies - if path.endswith('.dirdep'): + # these are special, tread src as read and + # target as write + self.parse_path(w[1].strip("'"), cwd, 'R', w) + self.parse_path(w[2].strip("'"), cwd, 'W', w) continue - # we don't want to resolve the last component if it is - # a symlink - path = resolve(path, cwd, last_dir, self.debug, self.debug_out) - if not path: - continue - dir,base = os.path.split(path) - if dir in self.seen: + elif w[0] in 'ERWS': + path = w[2] + self.parse_path(path, cwd, w[0], w) + + if not file: + f.close() + + def parse_path(self, path, cwd, op=None, w=[]): + """look at a path for the op specified""" + + if not op: + op = w[0] + + # we are never interested in .dirdep files as dependencies + if path.endswith('.dirdep'): + return + for p in self.excludes: + if p and path.startswith(p): if self.debug > 2: - print("seen:", dir, file=self.debug_out) - continue - # we can have a path in an objdir which is a link - # to the src dir, we may need to add dependencies for each - rdir = dir - dir = abspath(dir, cwd, last_dir, self.debug, self.debug_out) - if rdir == dir or rdir.find('./') > 0: - rdir = None - # now put path back together - path = '/'.join([dir,base]) - if self.debug > 1: - print("raw=%s rdir=%s dir=%s path=%s" % (w[2], rdir, dir, path), file=self.debug_out) - if w[0] in 'SRWL': - if w[0] == 'W' and path.endswith('.dirdep'): - continue - if path in [last_dir, cwd, self.cwd, self.curdir]: - if self.debug > 1: - print("skipping:", path, file=self.debug_out) - continue - if os.path.isdir(path): - if w[0] in 'RW': - last_dir = path; - if self.debug > 1: - print("ldir=", last_dir, file=self.debug_out) - continue + print >> self.debug_out, "exclude:", p, path + return + # we don't want to resolve the last component if it is + # a symlink + path = resolve(path, cwd, self.last_dir, self.debug, self.debug_out) + if not path: + return + dir,base = os.path.split(path) + if dir in self.seen: + if self.debug > 2: + print("seen:", dir, file=self.debug_out) + return + # we can have a path in an objdir which is a link + # to the src dir, we may need to add dependencies for each + rdir = dir + dir = abspath(dir, cwd, self.last_dir, self.debug, self.debug_out) + if rdir == dir or rdir.find('./') > 0: + rdir = None + # now put path back together + path = '/'.join([dir,base]) + if self.debug > 1: + print("raw=%s rdir=%s dir=%s path=%s" % (w[2], rdir, dir, path), file=self.debug_out) + if op in 'RWS': + if path in [self.last_dir, cwd, self.cwd, self.curdir]: + if self.debug > 1: + print("skipping:", path, file=self.debug_out) + return + if os.path.isdir(path): + if op in 'RW': + self.last_dir = path; + if self.debug > 1: + print("ldir=", self.last_dir, file=self.debug_out) + return + + if op in 'ERW': + # finally, we get down to it + if dir == self.cwd or dir == self.curdir: + return + srctop = self.find_top(path, self.srctops) + if srctop: + if self.dpdeps: + self.add(self.file_deps, path.replace(srctop,''), 'file') + self.add(self.src_deps, dir.replace(srctop,''), 'src') + self.seenit(w[2]) + self.seenit(dir) + if rdir and not rdir.startswith(srctop): + dir = rdir # for below + rdir = None + else: + return - if w[0] in 'REWML': - # finally, we get down to it - if dir == self.cwd or dir == self.curdir: + objroot = None + for dir in [dir,rdir]: + if not dir: continue - srctop = self.find_top(path, self.srctops) - if srctop: - if self.dpdeps: - self.add(self.file_deps, path.replace(srctop,''), 'file') - self.add(self.src_deps, dir.replace(srctop,''), 'src') - self.seenit(w[2]) - self.seenit(dir) - if rdir and not rdir.startswith(srctop): - dir = rdir # for below - rdir = None - else: - continue - - objroot = None - for dir in [dir,rdir]: - if not dir: - continue - objroot = self.find_top(dir, self.objroots) - if objroot: - break + objroot = self.find_top(dir, self.objroots) if objroot: - ddep = self.find_obj(objroot, dir, path, w[2]) - if ddep: - self.add(self.obj_deps, ddep, 'obj') - else: - # don't waste time looking again - self.seenit(w[2]) - self.seenit(dir) - if not file: - f.close() + break + if objroot: + ddep = self.find_obj(objroot, dir, path, w[2]) + if ddep: + self.add(self.obj_deps, ddep, 'obj') + else: + # don't waste time looking again + self.seenit(w[2]) + self.seenit(dir) def main(argv, klass=MetaFile, xopts='', xoptf=None): """Simple driver for class MetaFile. Usage: - script [options] [key=value ...] "meta" ... + script [options] [key=value ...] "meta" ... Options and key=value pairs contribute to the dictionary passed to MetaFile. -S "SRCTOP" - add "SRCTOP" to the "SRCTOPS" list. + add "SRCTOP" to the "SRCTOPS" list. -C "CURDIR" -O "OBJROOT" - add "OBJROOT" to the "OBJROOTS" list. + add "OBJROOT" to the "OBJROOTS" list. -m "MACHINE" @@ -550,7 +575,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None): -D "DPDEPS" - -d bumps debug level + -d bumps debug level """ import getopt @@ -568,6 +593,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None): conf = { 'SRCTOPS': [], 'OBJROOTS': [], + 'EXCLUDES': [], } try: @@ -589,7 +615,7 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None): debug = 0 output = True - opts, args = getopt.getopt(argv[1:], 'a:dS:C:O:R:m:D:H:qT:' + xopts) + opts, args = getopt.getopt(argv[1:], 'a:dS:C:O:R:m:D:H:qT:X:' + xopts) for o, a in opts: if o == '-a': conf['MACHINE_ARCH'] = a @@ -615,6 +641,9 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None): conf['MACHINE'] = a elif o == '-T': conf['TARGET_SPEC'] = a + elif o == '-X': + if a not in conf['EXCLUDES']: + conf['EXCLUDES'].append(a) elif xoptf: xoptf(o, a, conf) @@ -649,16 +678,21 @@ def main(argv, klass=MetaFile, xopts='', xoptf=None): for k,v in list(conf.items()): print("%s=%s" % (k,v), file=debug_out) + m = None for a in args: if a.endswith('.meta'): + if not os.path.exists(a): + continue m = klass(a, conf) elif a.startswith('@'): # there can actually multiple files per line for line in open(a[1:]): for f in line.strip().split(): + if not os.path.exists(f): + continue m = klass(f, conf) - if output: + if output and m: print(m.dirdeps()) print(m.src_dirdeps('\nsrc:')) diff --git a/mk/meta2deps.sh b/mk/meta2deps.sh index d96ce07c5af4..2a79be17a331 100755 --- a/mk/meta2deps.sh +++ b/mk/meta2deps.sh @@ -77,7 +77,7 @@ # RCSid: -# $Id: meta2deps.sh,v 1.7 2014/04/05 22:56:54 sjg Exp $ +# $Id: meta2deps.sh,v 1.9 2015/04/03 18:23:25 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -139,10 +139,15 @@ add_list() { eval "$name=\"$list\"" } +_excludes_f() { + egrep -v "$EXCLUDES" +} + meta2deps() { DPDEPS= SRCTOPS=$SRCTOP OBJROOTS= + EXCLUDES= while : do case "$1" in @@ -153,6 +158,7 @@ meta2deps() { -H) HOST_TARGET=$2; shift 2;; -S) add_list SRCTOPS $2; shift 2;; -O) add_list OBJROOTS $2; shift 2;; + -X) add_list EXCLUDES '|' $2; shift 2;; -R) RELDIR=$2; shift 2;; -T) TARGET_SPEC=$2; shift 2;; *) break;; @@ -212,8 +218,26 @@ meta2deps() { seenit= seensrc= lpid= - cat /dev/null "$@" | - sed -e 's,^CWD,C C,;/^[CREFL] /!d' -e "s,',,g" | + case "$EXCLUDES" in + "") _excludes=cat;; + *) _excludes=_excludes_f;; + esac + # handle @list files + case "$@" in + *@[!.]*) + for f in "$@" + do + case "$f" in + *.meta) cat $f;; + @*) xargs cat < ${f#@};; + *) cat $f;; + esac + done + ;; + *) cat /dev/null "$@";; + esac 2> /dev/null | + sed -e 's,^CWD,C C,;/^[CREFLM] /!d' -e "s,',,g" | + $_excludes | while read op pid path junk do : op=$op pid=$pid path=$path diff --git a/mk/mk-files.txt b/mk/mk-files.txt index 78826417b859..7eebfd6bcb36 100644 --- a/mk/mk-files.txt +++ b/mk/mk-files.txt @@ -432,13 +432,27 @@ You should never need to edit ``warnings.mk``, it will include ``warnings-sets.mk`` if it exists and you use that to make any local customizations. +rst2htm.mk +---------- + +Logic to simplify generating HTML (and PDF) documents from ReStructuredText. + +cython.mk +--------- + +Logic to build Python C interface modules using Cython_ + +.. _Cython: http://www.cython.org/ + Meta mode ========= The 20110505 and later versions of ``mk-files`` include a number of -makefile contributed by Juniper Networks, Inc. -These allow the latest version of bmake_ to run in `meta mode`_. +makefiles contributed by Juniper Networks, Inc. +These allow the latest version of bmake_ to run in `meta mode`_ +see `dirdeps.mk`_ +.. _`dirdeps.mk`: /help/sjg/dirdeps.htm .. _`meta mode`: bmake-meta-mode.htm Install @@ -463,5 +477,5 @@ where you unpacked the tar file, you can:: .. _mk.tar.gz: http://www.crufty.net/ftp/pub/sjg/mk.tar.gz :Author: sjg@crufty.net -:Revision: $Id: mk-files.txt,v 1.15 2011/06/08 07:06:18 sjg Exp $ +:Revision: $Id: mk-files.txt,v 1.16 2014/09/05 04:41:16 sjg Exp $ :Copyright: Crufty.NET diff --git a/mk/mkopt.sh b/mk/mkopt.sh new file mode 100755 index 000000000000..38b624ef1d24 --- /dev/null +++ b/mk/mkopt.sh @@ -0,0 +1,94 @@ +: +# $Id: mkopt.sh,v 1.8 2014/11/15 07:07:18 sjg Exp $ +# +# @(#) Copyright (c) 2014, Simon J. Gerraty +# +# This file is provided in the hope that it will +# be of use. There is absolutely NO WARRANTY. +# Permission to copy, redistribute or otherwise +# use this file is hereby granted provided that +# the above copyright notice and this notice are +# left intact. +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net +# + +# handle WITH[OUT]_* options in a manner compatible with +# options.mk and bsd.mkopt.mk in recent FreeBSD + +# no need to be included more than once +_MKOPT_SH=: + +# +# _mk_opt OPT default +# +# Set MK_$OPT +# +# The semantics are simple, if MK_$OPT has no value +# WITHOUT_$OPT results in MK_$OPT=no +# otherwise WITH_$OPT results in MK_$OPT=yes. +# Note WITHOUT_$OPT overrides WITH_$OPT. +# +# For backwards compatability reasons we treat WITH_$OPT=no +# the same as WITHOUT_$OPT. +# +_mk_opt() { + _d=$1 + _mo=MK_$2 _wo=WITHOUT_$2 _wi=WITH_$2 + eval "_mov=\$$_mo _wov=\$$_wo _wiv=\$$_wi" + + case "$_wiv" in + no) _wov=no;; + esac + _v=${_mov:-${_wov:+no}} + _v=${_v:-${_wiv:+yes}} + _v=${_v:-$_d} + _opt_list="$_opt_list $_mo" + case "$_v" in + yes|no) ;; # sane + 0|[NnFf]*) _v=no;; # they mean no + 1|[YyTt]*) _v=yes;; # they mean yes + *) _v=$_d;; # ignore bogus value + esac + eval "$_mo=$_v" +} + +# +# _mk_opts default opt ... [default [opt] ...] +# +# see _mk_opts_defaults for example +# +_mk_opts() { + _d=no + for _o in "$@" + do + case "$_o" in + yes|no) _d=$_o; continue;; + esac + _mk_opt $_d $_o + done +} + +_mk_opts_defaults() { + _mk_opts no $__DEFAULT_NO_OPTIONS yes $__DEFAULT_YES_OPTIONS +} + +case "/$0" in +*/mkopt*) + _list=no + while : + do + case "$1" in + *=*) eval "$1"; shift;; + --no|no) _list="$_list no"; shift;; + --yes|yes) _list="$_list yes"; shift;; + -DWITH*) eval "${1#-D}=1"; shift;; + [A-Z]*) _list="$_list $1"; shift;; + *) break;; + esac + done + _mk_opts $_list + ;; +esac + diff --git a/mk/own.mk b/mk/own.mk index e29ff9e6d6c7..f090bbe8e537 100644 --- a/mk/own.mk +++ b/mk/own.mk @@ -1,4 +1,4 @@ -# $Id: own.mk,v 1.27 2013/07/18 05:46:24 sjg Exp $ +# $Id: own.mk,v 1.28 2015/04/16 16:59:00 sjg Exp $ .if !target(__${.PARSEFILE}__) __${.PARSEFILE}__: @@ -89,6 +89,7 @@ OPTIONS_DEFAULT_NO+= DPADD_MK # process options OPTIONS_DEFAULT_NO+= \ + AUTO_OBJ \ INSTALL_AS_USER \ GPROF \ LIBTOOL \ @@ -98,7 +99,6 @@ OPTIONS_DEFAULT_NO+= \ OPTIONS_DEFAULT_YES+= \ ARCHIVE \ AUTODEP \ - AUTO_OBJ \ CRYPTO \ DOC \ DPADD_MK \ diff --git a/mk/sys.dependfile.mk b/mk/sys.dependfile.mk index 42cec61fce13..e915082e778c 100644 --- a/mk/sys.dependfile.mk +++ b/mk/sys.dependfile.mk @@ -1,4 +1,4 @@ -# $Id: sys.dependfile.mk,v 1.5 2013/03/08 00:59:21 sjg Exp $ +# $Id: sys.dependfile.mk,v 1.6 2014/08/02 18:02:06 sjg Exp $ # # @(#) Copyright (c) 2012, Simon J. Gerraty # @@ -25,6 +25,12 @@ # All depend file names should start with this .MAKE.DEPENDFILE_PREFIX ?= Makefile.depend +.if !empty(.MAKE.DEPENDFILE) && \ + ${.MAKE.DEPENDFILE:M${.MAKE.DEPENDFILE_PREFIX}*} == "" +# let us do our thing below... +.undef .MAKE.DEPENDFILE +.endif + # The order of preference: we will use the first one of these we find. # It usually makes sense to order from most specific to least. .MAKE.DEPENDFILE_PREFERENCE ?= \ diff --git a/mk/whats.mk b/mk/whats.mk new file mode 100644 index 000000000000..d17c3ef290ea --- /dev/null +++ b/mk/whats.mk @@ -0,0 +1,63 @@ +# $Id: whats.mk,v 1.1 2014/08/30 22:40:47 sjg Exp $ +# +# @(#) Copyright (c) 2014, Simon J. Gerraty +# +# This file is provided in the hope that it will +# be of use. There is absolutely NO WARRANTY. +# Permission to copy, redistribute or otherwise +# use this file is hereby granted provided that +# the above copyright notice and this notice are +# left intact. +# +# Please send copies of changes and bug-fixes to: +# sjg@crufty.net +# + +.if ${MK_WHATSTRING:Uno} != "no" +what_build_exts?= o +# it can be useful to embed a what(1) string in binaries +# so that the build location can be seen from a core file. +.if defined(PROG) && ${.MAKE.MAKEFILES:M*prog.mk} != "" +what_thing?= ${PROGNAME:U${PROG}} +what_build_thing?= ${PROG} +.elif defined(LIB) && ${.MAKE.MAKEFILES:M*lib.mk} != "" +# probably only makes sense for shared libs +# and the plumbing needed varies depending on *lib.mk +what_thing?= lib${LIB} +.if !empty(SOBJS) +_soe:= ${SOBJS:E:[1]} +what_build_exts= ${_soe} +SOBJS+= ${what_uuid}.${_soe} +.endif +.elif defined(KMOD) && ${.MAKE.MAKEFILES:M*kmod.mk} != "" +what_thing?= ${KMOD} +what_build_thing?= ${KMOD}.ko +.endif + +.if !empty(what_thing) +# a unique name that won't conflict with anything +what_uuid = what_${.CURDIR:T:hash} + +.if !empty(what_build_thing) +${what_build_thing}: ${what_build_exts:@e@${what_uuid}.$e@} +.endif +OBJS+= ${what_uuid}.o +CLEANFILES+= ${what_uuid}.c + +# we do not need to capture this +SUPPRESS_DEPEND+= *${what_uuid}.c + +SB?= ${SRCTOP:H} +SB_LOCATION?= ${HOST}:${SB} +what_location:= ${.OBJDIR:S,${SB},${SB_LOCATION},} + +# this works with clang and gcc +_what_t= const char __attribute__ ((section(".data"))) +_what1:= @(\#)${what_thing:tu} built ${%Y%m%d:L:localtime} by ${USER} +_what2:= @(\#)${what_location} + +${what_uuid}.c: + echo '${_what_t} ${what_uuid}1[] = "${_what1}";' > $@ ${.OODATE:MNO_META_CMP} + echo '${_what_t} ${what_uuid}2[] = "${_what2}";' >> $@ +.endif +.endif |