summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoerg <joerg>2015-05-19 21:36:43 +0000
committerjoerg <joerg>2015-05-19 21:36:43 +0000
commited5a1fe2e3f6e6bbce060caf3e0a78e9c50c2200 (patch)
tree2b7216a215b93c3db4db0c3a78c3ab11b8eaec34
parent2dc2569b2479813cbdd0a0c12025311424516e1f (diff)
downloadpkgsrc-BMAKE.tar.gz
Import bmake-20150505BMAKE
-rw-r--r--devel/bmake/files/ChangeLog555
-rw-r--r--devel/bmake/files/FILES142
-rw-r--r--devel/bmake/files/Makefile221
-rw-r--r--devel/bmake/files/Makefile.config.in20
-rw-r--r--devel/bmake/files/PSD.doc/Makefile6
-rw-r--r--devel/bmake/files/PSD.doc/tutorial.ms21
-rw-r--r--devel/bmake/files/README2
-rw-r--r--devel/bmake/files/arch.c8
-rw-r--r--devel/bmake/files/bmake.1392
-rw-r--r--devel/bmake/files/bmake.cat11579
-rwxr-xr-xdevel/bmake/files/boot-strap296
-rw-r--r--devel/bmake/files/bsd.after-import.mk111
-rw-r--r--devel/bmake/files/buf.c47
-rw-r--r--devel/bmake/files/buf.h3
-rw-r--r--devel/bmake/files/compat.c40
-rw-r--r--devel/bmake/files/cond.c82
-rw-r--r--devel/bmake/files/config.h.in15
-rwxr-xr-xdevel/bmake/files/configure76
-rw-r--r--devel/bmake/files/configure.in44
-rw-r--r--devel/bmake/files/dir.c50
-rw-r--r--devel/bmake/files/dir.h4
-rw-r--r--devel/bmake/files/for.c81
-rw-r--r--devel/bmake/files/hash.c9
-rw-r--r--devel/bmake/files/job.c246
-rw-r--r--devel/bmake/files/job.h4
-rw-r--r--devel/bmake/files/lst.h2
-rw-r--r--devel/bmake/files/lst.lib/lstInt.h2
-rw-r--r--devel/bmake/files/lst.lib/lstMember.c9
-rw-r--r--devel/bmake/files/lst.lib/lstRemove.c6
-rwxr-xr-xdevel/bmake/files/machine.sh6
-rw-r--r--devel/bmake/files/main.c471
-rw-r--r--devel/bmake/files/make-bootstrap.sh.in8
-rw-r--r--devel/bmake/files/make-conf.h8
-rw-r--r--devel/bmake/files/make.1367
-rw-r--r--devel/bmake/files/make.c26
-rw-r--r--devel/bmake/files/make.h42
-rw-r--r--devel/bmake/files/make_malloc.c10
-rw-r--r--devel/bmake/files/makefile.in14
-rw-r--r--devel/bmake/files/meta.c315
-rw-r--r--devel/bmake/files/meta.h5
-rw-r--r--devel/bmake/files/nonints.h25
-rw-r--r--devel/bmake/files/os.sh10
-rw-r--r--devel/bmake/files/parse.c355
-rw-r--r--devel/bmake/files/realpath.c77
-rw-r--r--devel/bmake/files/str.c16
-rw-r--r--devel/bmake/files/suff.c194
-rw-r--r--devel/bmake/files/targ.c12
-rw-r--r--devel/bmake/files/unit-tests/Makefile.in115
-rw-r--r--devel/bmake/files/unit-tests/comment.exp5
-rw-r--r--devel/bmake/files/unit-tests/comment.mk31
-rw-r--r--devel/bmake/files/unit-tests/cond1.exp23
-rw-r--r--devel/bmake/files/unit-tests/cond1.mk109
-rw-r--r--devel/bmake/files/unit-tests/cond2.exp7
-rw-r--r--devel/bmake/files/unit-tests/cond2.mk25
-rw-r--r--devel/bmake/files/unit-tests/doterror.exp9
-rw-r--r--devel/bmake/files/unit-tests/doterror.mk20
-rw-r--r--devel/bmake/files/unit-tests/dotwait.exp30
-rw-r--r--devel/bmake/files/unit-tests/dotwait.mk61
-rw-r--r--devel/bmake/files/unit-tests/error.exp4
-rw-r--r--devel/bmake/files/unit-tests/error.mk10
-rw-r--r--devel/bmake/files/unit-tests/escape.exp104
-rw-r--r--devel/bmake/files/unit-tests/escape.mk246
-rw-r--r--devel/bmake/files/unit-tests/export-all.exp12
-rw-r--r--devel/bmake/files/unit-tests/export-all.mk23
-rw-r--r--devel/bmake/files/unit-tests/export-env.exp9
-rw-r--r--devel/bmake/files/unit-tests/export-env.mk24
-rw-r--r--devel/bmake/files/unit-tests/export.exp6
-rw-r--r--devel/bmake/files/unit-tests/export.mk22
-rw-r--r--devel/bmake/files/unit-tests/forloop.exp19
-rw-r--r--devel/bmake/files/unit-tests/forloop.mk45
-rw-r--r--devel/bmake/files/unit-tests/forsubst.exp2
-rw-r--r--devel/bmake/files/unit-tests/forsubst.mk10
-rw-r--r--devel/bmake/files/unit-tests/hash.exp9
-rw-r--r--devel/bmake/files/unit-tests/hash.mk18
-rw-r--r--devel/bmake/files/unit-tests/impsrc.exp13
-rw-r--r--devel/bmake/files/unit-tests/impsrc.mk43
-rw-r--r--devel/bmake/files/unit-tests/misc.exp1
-rw-r--r--devel/bmake/files/unit-tests/misc.mk16
-rw-r--r--devel/bmake/files/unit-tests/moderrs.exp16
-rw-r--r--devel/bmake/files/unit-tests/moderrs.mk31
-rw-r--r--devel/bmake/files/unit-tests/modmatch.exp17
-rw-r--r--devel/bmake/files/unit-tests/modmatch.mk25
-rw-r--r--devel/bmake/files/unit-tests/modmisc.exp10
-rw-r--r--devel/bmake/files/unit-tests/modmisc.mk38
-rw-r--r--devel/bmake/files/unit-tests/modorder.exp11
-rw-r--r--devel/bmake/files/unit-tests/modorder.mk22
-rw-r--r--devel/bmake/files/unit-tests/modts.exp33
-rw-r--r--devel/bmake/files/unit-tests/modts.mk43
-rw-r--r--devel/bmake/files/unit-tests/modword.exp122
-rw-r--r--devel/bmake/files/unit-tests/modword.mk151
-rw-r--r--devel/bmake/files/unit-tests/order.exp4
-rw-r--r--devel/bmake/files/unit-tests/order.mk20
-rw-r--r--devel/bmake/files/unit-tests/phony-end.exp6
-rw-r--r--devel/bmake/files/unit-tests/phony-end.mk9
-rw-r--r--devel/bmake/files/unit-tests/posix.exp23
-rw-r--r--devel/bmake/files/unit-tests/posix.mk24
-rw-r--r--devel/bmake/files/unit-tests/posix1.exp185
-rw-r--r--devel/bmake/files/unit-tests/posix1.mk184
-rw-r--r--devel/bmake/files/unit-tests/qequals.exp2
-rw-r--r--devel/bmake/files/unit-tests/qequals.mk8
-rw-r--r--devel/bmake/files/unit-tests/suffixes.exp35
-rw-r--r--devel/bmake/files/unit-tests/suffixes.mk89
-rw-r--r--devel/bmake/files/unit-tests/sunshcmd.exp4
-rw-r--r--devel/bmake/files/unit-tests/sunshcmd.mk10
-rw-r--r--devel/bmake/files/unit-tests/sysv.exp7
-rw-r--r--devel/bmake/files/unit-tests/sysv.mk26
-rw-r--r--devel/bmake/files/unit-tests/ternary.exp10
-rw-r--r--devel/bmake/files/unit-tests/ternary.mk8
-rw-r--r--devel/bmake/files/unit-tests/unexport-env.exp2
-rw-r--r--devel/bmake/files/unit-tests/unexport-env.mk14
-rw-r--r--devel/bmake/files/unit-tests/unexport.exp4
-rw-r--r--devel/bmake/files/unit-tests/unexport.mk8
-rw-r--r--devel/bmake/files/unit-tests/varcmd.exp9
-rw-r--r--devel/bmake/files/unit-tests/varcmd.mk49
-rw-r--r--devel/bmake/files/unit-tests/varmisc.exp2
-rw-r--r--devel/bmake/files/unit-tests/varmisc.mk8
-rw-r--r--devel/bmake/files/unit-tests/varshell.exp10
-rw-r--r--devel/bmake/files/unit-tests/varshell.mk19
-rw-r--r--devel/bmake/files/util.c43
-rw-r--r--devel/bmake/files/var.c263
120 files changed, 6033 insertions, 2676 deletions
diff --git a/devel/bmake/files/ChangeLog b/devel/bmake/files/ChangeLog
index b24761aa3d3..f46e95de9a0 100644
--- a/devel/bmake/files/ChangeLog
+++ b/devel/bmake/files/ChangeLog
@@ -1,3 +1,558 @@
+2015-05-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20150505
+ Merge with NetBSD make, pick up
+ o cond.c: be strict about lhs of comparison when evaluating .if
+ but less so when called from variable expansion.
+ o unit-tests/cond2.mk: test various error conditions
+
+2015-05-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * machine.sh (MACHINE): Add Bitrig
+ patch from joerg@netbsd.org
+
+2015-04-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20150418
+ Merge with NetBSD make, pick up
+ o job.c: use memmove() rather than memcpy()
+
+ * unit-tests/varshell.mk: SunOS cannot handle the TERMINATED_BY_SIGNAL
+ case, so skip it.
+
+2015-04-11 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20150411
+ bump version - only mk/ changes.
+
+2015-04-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20150410
+ Merge with NetBSD make, pick up
+ o document different handling of '-' in jobs mode vs compat
+ o fix jobs mode so that '-' only applies to whole job
+ when shell lacks hasErrCtl
+ o meta.c: use separate vars to track lcwd and latestdir (read)
+ per process
+
+2015-04-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20150401
+ Merge with NetBSD make, pick up
+ o meta.c: close meta file in child
+
+ * Makefile: use BINDIR.bmake if set.
+ Same for MANDIR and SHAREDIR
+ Handy for testing release candidates
+ in various environments.
+
+2015-03-26 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * move initialization of savederr to block where it is used
+ to avoid spurious warning from gcc5
+
+2014-11-11 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20141111
+ just a cooler number
+
+2014-11-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20141105
+ Merge with NetBSD make, pick up
+ o revert major overhaul of suffix handling
+ and POSIX compliance - too much breakage
+ and impossible to make backwards compatible.
+ o we still have the new unit test structure which is ok.
+ o meta.c ensure "-- filemon" is at start of line.
+
+2014-09-17 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * configure.in: test that result of getconf PATH_MAX is numeric
+ and discard if not. Apparently needed for Hurd.
+
+2014-08-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20140830
+ Merge with NetBSD make, pick up
+ o major overhaul of suffix handling
+ o improved POSIX compliance
+ o overhauled unit-tests
+
+2014-06-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20140620
+ Merge with NetBSD make, pick up
+ o var.c return varNoError rather than var_Error for ::= modifiers.
+
+2014-05-22 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20140522
+ Merge with NetBSD make, pick up
+ o var.c detect some parse errors.
+
+2014-04-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Fix spelling errors - patch from Pedro Giffuni
+
+2014-02-14 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20140214
+ Merge with NetBSD make, pick up
+ o .INCLUDEFROM*
+ o use Var_Value to get MAKEOBJDIR[PREFIX]
+ o reduced realloc'ign in brk_string.
+ * configure.in: add a check for compiler supporting __func__
+
+2014-01-03 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: ignore mksrc=none
+
+2014-01-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (DEFAULT_SYS_PATH?): use just ${prefix}/share/mk
+
+2014-01-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20140101
+ * configure.in: set bmake_path_max to min(_SC_PATH_MAX,1024)
+ * Makefile.config: defined BMAKE_PATH_MAX to bmake_path_max
+ * make.h: use BMAKE_PATH_MAX if MAXPATHLEN not defined (needed for
+ Hurd)
+ * configure.in: Add AC_PREREQ and check for
+ sysctl; patch from Andrew Shadura andrewsh at debian.org
+
+2013-10-16 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20131010
+ * lose the const from arg to systcl to avoid problems on older BSDs.
+
+2013-10-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20131001
+ Merge with NetBSD make, pick up
+ o main.c: for NATIVE build sysctl to get MACHINE_ARCH from
+ hw.machine_arch if necessary.
+ o meta.c: meta_oodate - need to look at src of Link and target
+ of Move as well.
+ * main.c: check that CTL_HW and HW_MACHINE_ARCH exist.
+ provide __arraycount() if needed.
+
+2013-09-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130904
+ Merge with NetBSD make, pick up
+ o Add VAR_INTERNAL context, so that internal setting of
+ MAKEFILE does not override value set by makefiles.
+
+2013-09-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130902
+ Merge with NetBSD make, pick up
+ o CompatRunCommand: only apply shellErrFlag when errCheck is true
+
+2013-08-28 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130828
+ Merge with NetBSD make, pick up
+ o Fix VAR :sh = syntax from Will Andrews at freebsd.org
+ o Call Job_SetPrefix() from Job_Init() so makefiles have
+ opportunity to set .MAKE.JOB.PREFIX
+
+2013-07-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130730
+ Merge with NetBSD make, pick up
+ o Allow suppression of --- job -- tokens by setting
+ .MAKE.JOB.PREFIX empty.
+
+2013-07-16 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130716
+ Merge with NetBSD make, pick up
+ o number of gmake compatibility tweaks
+ -w for gmake style entering/leaving messages
+ if .MAKE.LEVEL > 0 indicate it in progname "make[1]" etc.
+ handle MAKEFLAGS containing only letters.
+ o when overriding a GLOBAL variable on the command line,
+ delete it from GLOBAL context so -V doesn't show the wrong
+ value.
+
+2013-07-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * configure.in: We don't need MAKE_LEVEL_SAFE anymore.
+
+ * Makefile (MAKE_VERSION): 20130706
+ Merge with NetBSD make, pick up
+ o Shell_Init(): export shellErrFlag if commandShell hasErrCtl is
+ true so that CompatRunCommand() can use it, to ensure
+ consistent behavior with jobs mode.
+ o use MAKE_LEVEL_ENV to define the variable to propagate
+ .MAKE.LEVEL - currently set to MAKELEVEL (same as gmake).
+ o meta.c: use .MAKE.META.IGNORE_PATHS to allow customization of
+ paths to ignore.
+
+2013-06-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130604
+ Merge with NetBSD make, pick up
+ o job.c: JobCreatePipe: do fcntl() after any tweaking of fd's
+ to avoid leaking descriptors.
+
+2013-05-28 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130528
+ Merge with NetBSD make, pick up
+ o var.c: cleanup some left-overs in VarHash()
+
+2013-05-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130520
+ generate manifest from component FILES rather than have to
+ update FILES when mk/FILES changes.
+
+2013-05-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130518
+ Merge with NetBSD make, pick up
+ o suff.c: don't skip all processsing for .PHONY targets
+ else wildcard srcs do not get expanded.
+ o var.c: expand name of variable to delete if necessary.
+
+2013-03-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130330
+ Merge with NetBSD make, pick up
+ o meta.c: refine the handling of .OODATE in commands.
+ Rather than suppress command comparison for the entire script
+ as though .NOMETA_CMP had been used, only suppress it for the
+ one command line.
+ This allows something like ${.OODATE:M.NOMETA_CMP} to be used to
+ suppress comparison of a command without otherwise affecting it.
+ o make.1: document that
+
+2013-03-22 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130321
+ yes, not quite right but its a cooler number.
+ Merge with NetBSD make, pick up
+ o parse.c: fix ParseGmakeExport to be portable
+ and add a unit-test.
+ * meta.c: call meta_init() before makefiles are read and if built
+ with filemon support set .MAKE.PATH_FILEMON to _PATH_FILEMON
+ this let's makefiles test for support.
+ Call meta_mode_init() to process .MAKE.MODE.
+
+2013-03-13 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130305
+ Merge with NetBSD make, pick up
+ o run .STALE: target when a dependency from .depend is missing.
+ o job.c: add Job_RunTarget() for the above and .BEGIN
+
+2013-03-03 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130303
+ Merge with NetBSD make, pick up
+ o main.c: set .MAKE.OS to utsname.sysname
+ o job.c: more checks for read and poll errors
+ o var.c: lose VarChangeCase() saves 4% time
+
+2013-03-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: remove MAKEOBJDIRPREFIX from environment since we
+ want to use MAKEOBJDIR
+
+2013-01-27 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Merge with NetBSD make, pick up
+ o make.1: more info on how shell commands are handled.
+ o job.c,main.c: detect write errors to job pipes.
+
+2013-01-25 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20130123
+ Merge with NetBSD make, pick up
+ o meta.c: if script uses .OODATE and meta_oodate() decides
+ rebuild is needed, .OODATE will be empty - set it to .ALLSRC.
+ o var.c: in debug output indicate which variabale modifiers
+ apply to.
+ o remove Check_Cwd logic the makefiles have been fixed.
+
+2012-12-12 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * makefile.in: add a simple makefile for folk who insist on
+ ./configure; make; make install
+ it just runs boot-strap
+ * include mk/* to accommodate the above
+ * boot-strap: re-work to accommodate the above
+ mksrc defaults to $Mydir/mk
+ allow op={configure,build,install,clean,all}
+ add options to facilitate install
+ * Makefile.config.in: just the bits set by configure
+ * Makefile: bump version to 20121212
+ abandon Makefile.in (NetBSD Makefile)
+ leverage mk/* instead
+ * configure.in: ensure srcdir is absolute
+
+2012-11-11 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20121111
+ fix generation of bmake.cat1
+
+2012-11-09 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20121109
+ Merge with NetBSD make, pick up
+ o make.c: MakeBuildChild: return 0 so search continues if a
+ .ORDER dependency is detected.
+ o unit-tests/order: test the above
+
+2012-11-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20121102
+ Merge with NetBSD make, pick up
+ o cond.c: allow cond_state[] to grow.
+ In meta mode with a very large tree, we can hit the limit
+ while processing dirdeps.
+
+2012-10-25 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in: we need to use ${srcdir} not ${.CURDIR}
+
+2012-10-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20121010
+ o protect syntax that only bmake parses correctly.
+ o remove auto setting of FORCE_MACHINE, use configure's
+ --with-force-machine=whatever if that is desired.
+
+2012-10-08 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in: do not lose history from make.1 when generating bmake.1
+
+2012-10-07 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20121007
+ Merge with NetBSD make, pick up
+ o compat.c: ignore empty commands - same as jobs mode.
+ o make.1: document meta chars that cause use of shell
+
+2012-09-11 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120911
+ * bsd.after-import.mk: include Makefile.inc early and allow it to
+ override PROG
+
+2012-08-31 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120831
+ Merge with NetBSD make, pick up
+ o cast sizeof() to int for comparison
+ o minor make.1 tweak
+
+2012-08-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120830
+ Merge with NetBSD make, pick up
+ o .MAKE.EXPAND_VARIABLES knob can control default behavior of -V
+ o debug flag -dV causes -V to show raw value regardless.
+
+2012-07-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * bsd.after-import.mk (after-import): ensure unit-tests/Makefile
+ gets SRCTOP set.
+
+2012-07-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120704
+ Merge with NetBSD make, pick up
+ o Job_ParseShell should call Shell_Init if it has been
+ previously called.
+ * Makefile.in: set USE_META based on configure result.
+ also .PARSEDIR is safer indicator of bmake.
+
+2012-06-26 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in: bump version to 20120626
+ ensure CPPFLAGS is in CFLAGS
+ * meta.c: avoid nested externs
+ * bsd.after-import.mk: avoid ${.CURDIR}/Makefile as target
+
+2012-06-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120620
+ Merge with NetBSD make, pick up
+ o make_malloc.c: avoid including make_malloc.h again
+
+ * Makefile.in: avoid bmake only syntax or protect with
+ .if defined(.MAKE.LEVEL)
+ * bsd.after-import.mk: replace .-include with .sinclude
+ ensure? SRCTOP gets a value
+ * configure.in: look for filemon.h in /usr/include/dev/filemon first.
+
+2012-06-19 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120612
+ Merge with NetBSD make, pick up
+ o use MAKE_ATTR_* rather than those defined by cdefs.h or compiler
+ for greater portability.
+ o unit-tests/forloop: check that .for works as expected wrt
+ number of times and with "quoted strings".
+
+2012-06-06 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120606
+ Merge with NetBSD make, pick up
+ o compat.c: use kill(2) rather than raise(3).
+ * configure.in: look for sys/dev/filemon
+ * bsd.after-import.mk: add a .-include "Makefile.inc" to Makefile
+ and pass BOOTSTRAP_XTRAS to boot-strap.
+
+2012-06-04 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120604
+ Merge with NetBSD make, pick up
+ o util.c and var.c share same var for tracking if environ
+ has been reallocated.
+ o util.c provide getenv with setenv.
+ * Add MAKE_LEVEL_SAFE as an alternate means of passing MAKE_LEVEL
+ when the shell actively strips .MAKE.* from the environment.
+ We still refer to the variable always as .MAKE.LEVEL
+ * util.c fix bug in findenv() was finding prefix of name.
+ * compat.c: re-raising SIGINT etc after running .INTERRUPT
+ results in more reliable termination of all activity on many
+ platforms.
+
+2012-06-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120602
+ Merge with NetBSD make, pick up
+ o for.c: handle quoted items in .for list
+
+2012-05-30 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120530
+ Merge with NetBSD make, pick up
+ o compat.c: ignore empty command.
+
+2012-05-24 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120524
+ * FILES: add bsd.after-import.mk:
+ A simple means of integrating bmake into a BSD build system.
+
+2012-05-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120520
+ Merge with NetBSD make, pick up
+ o increased limit for nested conditionals.
+
+2012-05-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120518
+ Merge with NetBSD make, pick up
+ o use _exit(2) in signal hanlder
+ o Don't use the [dir] cache when building nodes that might have
+ changed since the last exec.
+ o Avoid nested extern declaration warnings.
+
+2012-04-27 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * meta.c (fgetLine): avoid %z - not portable.
+ * parse.c: Since we moved include of sys/mman.h
+ and def's of MAP_COPY etc. we got dups from a merge.
+
+2012-04-24 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120420
+ Merge with NetBSD make, pick up
+ o restore duplicate supression in .MAKE.MAKEFILES
+ runtime saving can be significant.
+ o Var_Subst() uses Buf_DestroyCompact() to reduce memory
+ consumption up to 20%.
+
+2012-04-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120420
+ Merge with NetBSD make, pick up
+ o remove duplicate supression in .MAKE.MAKEFILES
+ o improved dir cache behavior
+ o gmake'ish export command
+
+2012-03-25 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20120325
+ Merge with NetBSD make, pick up
+ o fix parsing of :[#] in conditionals.
+
+2012-02-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in: replace use of .Nx in bmake.1 with NetBSD
+ since some systems cannot cope with .Nx <version>
+
+2011-11-14 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20111111
+ Merge with NetBSD make, pick up
+ o debug output for .PARSEDIR and .PARSEFILE
+
+2011-10-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20111010
+
+2011-10-09 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * boot-strap: check for an expected file in the dirs we look for.
+ * make-bootstrap.sh: pass on LDSTATIC
+
+2011-10-01 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20111001
+ Merge with NetBSD make, pick up
+ o ensure .PREFIX is set for .PHONY
+ and .TARGET set for .PHONY run via .END
+ o __dead used consistently
+
+2011-09-10 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): 20110909 is a better number ;-)
+
+2011-09-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110905
+ Merge with NetBSD make, pick up
+ o meta_oodate: ignore makeDependfile
+
+2011-08-28 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110828
+ Merge with NetBSD make, pick up
+ o silent=yes in .MAKE.MODE causes meta mode to mark targets
+ as SILENT if a .meta file is created
+
+2011-08-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110818
+ Merge with NetBSD make, pick up
+ o in meta mode, if target flagged .META a missing .meta file
+ means target is out-of-date
+ o fixes for gcc 4.5 warnings
+ o simplify job printing code
+
+2011-08-09 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110808
+ Merge with NetBSD make, pick up
+ o do not touch OP_SPECIAL targets when doing make -t
+
+2011-06-22 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile.in (MAKE_VERSION): bump version to 20110622
+ Merge with NetBSD make, pick up
+ o meta_oodate detect corrupted .meta file and declare oodate.
+ * configure.in: add check for setsid
+
2011-06-07 Simon J. Gerraty <sjg@bad.crufty.net>
* Merge with NetBSD make, pick up
diff --git a/devel/bmake/files/FILES b/devel/bmake/files/FILES
index 24e1359bece..c46e74bd7a4 100644
--- a/devel/bmake/files/FILES
+++ b/devel/bmake/files/FILES
@@ -1,45 +1,34 @@
-FILES
ChangeLog
-bmake.cat1
-boot-strap
-os.sh
-Makefile.in
+FILES
+Makefile
+Makefile.config.in
PSD.doc/Makefile
PSD.doc/tutorial.ms
README
+aclocal.m4
arch.c
+bmake.1
+bmake.cat1
+boot-strap
+bsd.after-import.mk
buf.c
buf.h
compat.c
cond.c
-make-conf.h
-make_malloc.c
-make_malloc.h
config.h.in
configure
-aclocal.m4
configure.in
dir.c
dir.h
+dirname.c
find_lib.sh
for.c
-getenv.c
getopt.c
hash.c
hash.h
install-sh
job.c
job.h
-meta.c
-meta.h
-dirname.c
-realpath.c
-strlcpy.c
-strlist.c
-strlist.h
-stresep.c
-trace.c
-trace.h
lst.h
lst.lib/Makefile
lst.lib/lstAppend.c
@@ -72,48 +61,107 @@ lst.lib/lstReplace.c
lst.lib/lstSucc.c
machine.sh
main.c
+make-bootstrap.sh.in
+make-conf.h
make.1
-bmake.1
make.c
make.h
-make-bootstrap.sh.in
+make_malloc.c
+make_malloc.h
+makefile.in
+meta.c
+meta.h
missing/sys/cdefs.h
mkdeps.sh
nonints.h
+os.sh
parse.c
pathnames.h
ranlib.h
+realpath.c
setenv.c
sigcompat.c
sprite.h
str.c
+stresep.c
+strlcpy.c
+strlist.c
+strlist.h
suff.c
targ.c
+trace.c
+trace.h
+unit-tests/Makefile.in
+unit-tests/comment.exp
+unit-tests/comment.mk
+unit-tests/cond1.exp
+unit-tests/cond1.mk
+unit-tests/cond2.exp
+unit-tests/cond2.mk
+unit-tests/doterror.exp
+unit-tests/doterror.mk
+unit-tests/dotwait.exp
+unit-tests/dotwait.mk
+unit-tests/error.exp
+unit-tests/error.mk
+unit-tests/escape.exp
+unit-tests/escape.mk
+unit-tests/export-all.exp
+unit-tests/export-all.mk
+unit-tests/export-env.exp
+unit-tests/export-env.mk
+unit-tests/export.exp
+unit-tests/export.mk
+unit-tests/forloop.exp
+unit-tests/forloop.mk
+unit-tests/forsubst.exp
+unit-tests/forsubst.mk
+unit-tests/hash.exp
+unit-tests/hash.mk
+unit-tests/impsrc.exp
+unit-tests/impsrc.mk
+unit-tests/misc.exp
+unit-tests/misc.mk
+unit-tests/moderrs.exp
+unit-tests/moderrs.mk
+unit-tests/modmatch.exp
+unit-tests/modmatch.mk
+unit-tests/modmisc.exp
+unit-tests/modmisc.mk
+unit-tests/modorder.exp
+unit-tests/modorder.mk
+unit-tests/modts.exp
+unit-tests/modts.mk
+unit-tests/modword.exp
+unit-tests/modword.mk
+unit-tests/order.exp
+unit-tests/order.mk
+unit-tests/phony-end.exp
+unit-tests/phony-end.mk
+unit-tests/posix.exp
+unit-tests/posix.mk
+unit-tests/posix1.exp
+unit-tests/posix1.mk
+unit-tests/qequals.exp
+unit-tests/qequals.mk
+unit-tests/suffixes.exp
+unit-tests/suffixes.mk
+unit-tests/sunshcmd.exp
+unit-tests/sunshcmd.mk
+unit-tests/sysv.exp
+unit-tests/sysv.mk
+unit-tests/ternary.exp
+unit-tests/ternary.mk
+unit-tests/unexport-env.exp
+unit-tests/unexport-env.mk
+unit-tests/unexport.exp
+unit-tests/unexport.mk
+unit-tests/varcmd.exp
+unit-tests/varcmd.mk
+unit-tests/varmisc.exp
+unit-tests/varmisc.mk
+unit-tests/varshell.exp
+unit-tests/varshell.mk
util.c
var.c
wait.h
-unit-tests/Makefile.in
-unit-tests/comment
-unit-tests/cond1
-unit-tests/doterror
-unit-tests/dotwait
-unit-tests/error
-unit-tests/export
-unit-tests/export-all
-unit-tests/forsubst
-unit-tests/hash
-unit-tests/misc
-unit-tests/moderrs
-unit-tests/modmatch
-unit-tests/modmisc
-unit-tests/modorder
-unit-tests/modts
-unit-tests/modword
-unit-tests/posix
-unit-tests/qequals
-unit-tests/sysv
-unit-tests/ternary
-unit-tests/test.exp
-unit-tests/unexport
-unit-tests/unexport-env
-unit-tests/varcmd
diff --git a/devel/bmake/files/Makefile b/devel/bmake/files/Makefile
new file mode 100644
index 00000000000..d0312fd064d
--- /dev/null
+++ b/devel/bmake/files/Makefile
@@ -0,0 +1,221 @@
+# $Id: Makefile,v 1.1.1.1 2015/05/19 21:36:43 joerg Exp $
+
+# Base version on src date
+MAKE_VERSION= 20150505
+
+PROG= bmake
+
+SRCS= \
+ arch.c \
+ buf.c \
+ compat.c \
+ cond.c \
+ dir.c \
+ for.c \
+ hash.c \
+ job.c \
+ main.c \
+ make.c \
+ make_malloc.c \
+ meta.c \
+ parse.c \
+ str.c \
+ strlist.c \
+ suff.c \
+ targ.c \
+ trace.c \
+ util.c \
+ var.c
+
+# from lst.lib/
+SRCS+= \
+ lstAppend.c \
+ lstAtEnd.c \
+ lstAtFront.c \
+ lstClose.c \
+ lstConcat.c \
+ lstDatum.c \
+ lstDeQueue.c \
+ lstDestroy.c \
+ lstDupl.c \
+ lstEnQueue.c \
+ lstFind.c \
+ lstFindFrom.c \
+ lstFirst.c \
+ lstForEach.c \
+ lstForEachFrom.c \
+ lstInit.c \
+ lstInsert.c \
+ lstIsAtEnd.c \
+ lstIsEmpty.c \
+ lstLast.c \
+ lstMember.c \
+ lstNext.c \
+ lstOpen.c \
+ lstPrev.c \
+ lstRemove.c \
+ lstReplace.c \
+ lstSucc.c
+
+# this file gets generated by configure
+.-include "Makefile.config"
+
+.if !empty(LIBOBJS)
+SRCS+= ${LIBOBJS:T:.o=.c}
+.endif
+
+# just in case
+prefix?= /usr
+srcdir?= ${.CURDIR}
+
+DEFAULT_SYS_PATH?= ${prefix}/share/mk
+
+CPPFLAGS+= -DUSE_META
+CFLAGS+= ${CPPFLAGS}
+CFLAGS+= -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"
+CFLAGS+= -I. -I${srcdir} ${XDEFS} -DMAKE_NATIVE
+CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}}
+COPTS.main.c+= "-DMAKE_VERSION=\"${MAKE_VERSION}\""
+
+# meta mode can be useful even without filemon
+FILEMON_H ?= /usr/include/dev/filemon/filemon.h
+.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
+COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
+.endif
+
+.PATH: ${srcdir}
+.PATH: ${srcdir}/lst.lib
+
+.if make(obj) || make(clean)
+SUBDIR+= unit-tests
+.endif
+
+# start-delete1 for bsd.after-import.mk
+# we skip a lot of this when building as part of FreeBSD etc.
+
+# list of OS's which are derrived from BSD4.4
+BSD44_LIST= NetBSD FreeBSD OpenBSD DragonFly MirBSD Bitrig
+# we are...
+OS!= uname -s
+# are we 4.4BSD ?
+isBSD44:=${BSD44_LIST:M${OS}}
+
+.if ${isBSD44} == ""
+MANTARGET= cat
+INSTALL?=${srcdir}/install-sh
+.if (${MACHINE} == "sun386")
+# even I don't have one of these anymore :-)
+CFLAGS+= -DPORTAR
+.elif (${MACHINE} != "sunos")
+SRCS+= sigcompat.c
+CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART
+.endif
+.else
+MANTARGET?= man
+.endif
+
+# turn this on by default - ignored if we are root
+WITH_INSTALL_AS_USER=
+
+# suppress with -DWITHOUT_*
+OPTIONS_DEFAULT_YES+= \
+ AUTOCONF_MK \
+ INSTALL_MK \
+ PROG_LINK
+
+OPTIONS_DEFAULT_NO+= \
+ PROG_VERSION
+
+# process options now
+.include <own.mk>
+
+.if ${MK_PROG_VERSION} == "yes"
+PROG_NAME= ${PROG}-${MAKE_VERSION}
+.if ${MK_PROG_LINK} == "yes"
+SYMLINKS+= ${PROG}-${MAKE_VERSION} ${BINDIR}/${PROG}
+.endif
+.endif
+
+EXTRACT_MAN=no
+# end-delete1
+
+MAN= ${PROG}.1
+MAN1= ${MAN}
+
+.if (${PROG} != "make")
+CLEANFILES+= my.history
+.if make(${MAN}) || !exists(${srcdir}/${MAN})
+my.history: ${MAKEFILE}
+ @(echo ".Nm"; \
+ echo "is derived from NetBSD"; \
+ echo ".Xr make 1 ."; \
+ echo "It uses autoconf to facilitate portability to other platforms."; \
+ echo ".Pp") > $@
+
+.NOPATH: ${MAN}
+${MAN}: make.1 my.history
+ @echo making $@
+ @sed -e 's/^.Nx/NetBSD/' -e '/^.Nm/s/make/${PROG}/' \
+ -e '/^.Sh HISTORY/rmy.history' \
+ -e '/^.Sh HISTORY/,$$s,^.Nm,make,' ${srcdir}/make.1 > $@
+
+all beforeinstall: ${MAN}
+_mfromdir=.
+.endif
+.endif
+
+MANTARGET?= cat
+MANDEST?= ${MANDIR}/${MANTARGET}1
+
+.if ${MANTARGET} == "cat"
+_mfromdir=${srcdir}
+.endif
+
+.include <prog.mk>
+
+CPPFLAGS+= -DMAKE_NATIVE -DHAVE_CONFIG_H
+COPTS.var.c += -Wno-cast-qual
+COPTS.job.c += -Wno-format-nonliteral
+COPTS.parse.c += -Wno-format-nonliteral
+COPTS.var.c += -Wno-format-nonliteral
+
+# Force these
+SHAREDIR= ${SHAREDIR.bmake:U${prefix}/share}
+BINDIR= ${BINDIR.bmake:U${prefix}/bin}
+MANDIR= ${MANDIR.bmake:U${SHAREDIR}/man}
+
+.if !exists(.depend)
+${OBJS}: config.h
+.endif
+
+# make sure that MAKE_VERSION gets updated.
+main.o: ${SRCS} ${MAKEFILE}
+
+# start-delete2 for bsd.after-import.mk
+.if ${MK_AUTOCONF_MK} == "yes"
+.include <autoconf.mk>
+.endif
+SHARE_MK?=${SHAREDIR}/mk
+MKSRC=${srcdir}/mk
+INSTALL?=${srcdir}/install-sh
+
+.if ${MK_INSTALL_MK} == "yes"
+install: install-mk
+.endif
+
+beforeinstall:
+ test -d ${DESTDIR}${BINDIR} || ${INSTALL} -m 775 -d ${DESTDIR}${BINDIR}
+ test -d ${DESTDIR}${MANDEST} || ${INSTALL} -m 775 -d ${DESTDIR}${MANDEST}
+
+install-mk:
+.if exists(${MKSRC}/install-mk)
+ test -d ${DESTDIR}${SHARE_MK} || ${INSTALL} -m 775 -d ${DESTDIR}${SHARE_MK}
+ sh ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${SHARE_MK}
+.else
+ @echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false
+.endif
+# end-delete2
+
+# A simple unit-test driver to help catch regressions
+accept test:
+ cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
diff --git a/devel/bmake/files/Makefile.config.in b/devel/bmake/files/Makefile.config.in
new file mode 100644
index 00000000000..1f9aefe1dfa
--- /dev/null
+++ b/devel/bmake/files/Makefile.config.in
@@ -0,0 +1,20 @@
+# things set by configure
+
+prefix= @prefix@
+srcdir= @srcdir@
+CC?= @CC@
+MACHINE= @machine@
+MACHINE_ARCH= @machine_arch@
+DEFAULT_SYS_PATH= @default_sys_path@
+
+CPPFLAGS+= @CPPFLAGS@
+CFLAGS+= ${CPPFLAGS} @DEFS@
+LDFLAGS= @LDFLAGS@
+LIBOBJS= @LIBOBJS@
+LDADD= @LIBS@
+USE_META= @use_meta@
+FILEMON_H= @filemon_h@
+BMAKE_PATH_MAX?= @bmake_path_max@
+# used if MAXPATHLEN not defined
+CPPFLAGS+= -DBMAKE_PATH_MAX=${BMAKE_PATH_MAX}
+
diff --git a/devel/bmake/files/PSD.doc/Makefile b/devel/bmake/files/PSD.doc/Makefile
index 347538e6983..58355417ba3 100644
--- a/devel/bmake/files/PSD.doc/Makefile
+++ b/devel/bmake/files/PSD.doc/Makefile
@@ -1,8 +1,10 @@
-# $NetBSD: Makefile,v 1.1.1.3 2009/09/18 20:55:32 joerg Exp $
+# $NetBSD: Makefile,v 1.1.1.4 2015/05/19 21:36:44 joerg Exp $
# @(#)Makefile 8.1 (Berkeley) 8/14/93
-DIR= psd/12.make
+SECTION=reference/ref1
+ARTICLE=make
SRCS= tutorial.ms
MACROS= -ms
+EXTRAHTMLFILES=make1.png make2.png
.include <bsd.doc.mk>
diff --git a/devel/bmake/files/PSD.doc/tutorial.ms b/devel/bmake/files/PSD.doc/tutorial.ms
index 7845b6430a0..ca6c7ff7826 100644
--- a/devel/bmake/files/PSD.doc/tutorial.ms
+++ b/devel/bmake/files/PSD.doc/tutorial.ms
@@ -1,4 +1,4 @@
-.\" $NetBSD: tutorial.ms,v 1.1.1.3 2009/09/18 20:55:33 joerg Exp $
+.\" $NetBSD: tutorial.ms,v 1.1.1.4 2015/05/19 21:36:45 joerg Exp $
.\" Copyright (c) 1988, 1989, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -67,6 +67,16 @@
.\"
.EH 'PSD:12-%''PMake \*- A Tutorial'
.OH 'PMake \*- A Tutorial''PSD:12-%'
+.\" Ix is an indexing macro similar to .IX but I've disabled it for now
+.\" Since that would require 2 passes and I am not in the mood for that.
+.de Ix
+..
+.\" Rd is section (region) define and Rm is region mention? Again disable for
+.\" now.
+.de Rd
+..
+.de Rm
+..
.\" xH is a macro to provide numbered headers that are automatically stuffed
.\" into a table-of-contents, properly indented, etc. If the first argument
.\" is numeric, it is taken as the depth for numbering (as for .NH), else
@@ -114,14 +124,15 @@
.nr g4 \\n(.s
.sp -1
.\" .st cf
-\D's -1u'\D't 5u'
+\D't 5u'
.sp -1
-\h'50u'\D'l 71u 0u'\D'l 50u 50u'\D'l 0u 71u'\D'l -50u 50u'\D'l -71u 0u'\D'l -50u -50u'\D'l 0u -71u'\D'l 50u -50u'
+\h'50u'
.sp -1
\D't 3u'
.sp -1
.sp 7u
-\h'53u'\D'p 14 68u 0u 46u 46u 0u 68u -46u 46u -68u 0u -47u -46u 0u -68u 47u -46u'
+\h'53u'
+\d\D'p -0.19i 0.0i 0.0i -0.13i 0.30i 0.0i 0.0i 0.13i'
.sp -1
.ft R
.ps 6
@@ -131,7 +142,7 @@
\h'85u'\v'0.85n'\h-\w\\*(g9u/2u\&\\*(g9
.sp |\\n(g8u
.sp 166u
-\D't 3u'\D's -1u'
+\D't 3u'
.br
.po
.rt
diff --git a/devel/bmake/files/README b/devel/bmake/files/README
index fb688a33bc6..d09e977e48b 100644
--- a/devel/bmake/files/README
+++ b/devel/bmake/files/README
@@ -18,7 +18,7 @@ interesting changes, so that bmake tracks it very closely.
Building:
-The prefered way to bootstrap bmake is:
+The preferred way to bootstrap bmake is:
./bmake/boot-strap
diff --git a/devel/bmake/files/arch.c b/devel/bmake/files/arch.c
index 80c289a7637..e5321e78f65 100644
--- a/devel/bmake/files/arch.c
+++ b/devel/bmake/files/arch.c
@@ -1,4 +1,4 @@
-/* $NetBSD: arch.c,v 1.1.1.7 2011/06/18 22:17:42 bsiegert Exp $ */
+/* $NetBSD: arch.c,v 1.1.1.8 2015/05/19 21:36:43 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: arch.c,v 1.1.1.7 2011/06/18 22:17:42 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: arch.c,v 1.1.1.8 2015/05/19 21:36:43 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: arch.c,v 1.1.1.7 2011/06/18 22:17:42 bsiegert Exp $");
+__RCSID("$NetBSD: arch.c,v 1.1.1.8 2015/05/19 21:36:43 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -1077,7 +1077,7 @@ Arch_Touch(GNode *gn)
*/
void
#if !defined(RANLIBMAG)
-Arch_TouchLib(GNode *gn __unused)
+Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED)
#else
Arch_TouchLib(GNode *gn)
#endif
diff --git a/devel/bmake/files/bmake.1 b/devel/bmake/files/bmake.1
index 124c04a41ff..85e8493fb77 100644
--- a/devel/bmake/files/bmake.1
+++ b/devel/bmake/files/bmake.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: bmake.1,v 1.1.1.4 2011/06/18 22:17:44 bsiegert Exp $
+.\" $NetBSD: bmake.1,v 1.1.1.5 2015/05/19 21:36:43 joerg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd May 29, 2011
+.Dd April 9, 2015
.Dt MAKE 1
.Os
.Sh NAME
@@ -37,41 +37,19 @@
.Nd maintain program dependencies
.Sh SYNOPSIS
.Nm
-.Op Fl BeikNnqrstWX
-.Bk -words
+.Op Fl BeikNnqrstWwX
.Op Fl C Ar directory
-.Ek
-.Bk -words
.Op Fl D Ar variable
-.Ek
-.Bk -words
.Op Fl d Ar flags
-.Ek
-.Bk -words
.Op Fl f Ar makefile
-.Ek
-.Bk -words
.Op Fl I Ar directory
-.Ek
-.Bk -words
.Op Fl J Ar private
-.Ek
-.Bk -words
.Op Fl j Ar max_jobs
-.Ek
-.Bk -words
.Op Fl m Ar directory
-.Ek
-.Bk -words
.Op Fl T Ar file
-.Ek
-.Bk -words
.Op Fl V Ar variable
-.Ek
.Op Ar variable=value
-.Bk -words
.Op Ar target ...
-.Ek
.Sh DESCRIPTION
.Nm
is a program designed to simplify the maintenance of other programs.
@@ -95,7 +73,7 @@ This manual page is intended as a reference document only.
For a more thorough description of
.Nm
and makefiles, please refer to
-.%T "Make \- A Tutorial" .
+.%T "PMake \- A Tutorial" .
.Pp
.Nm
will prepend the contents of the
@@ -126,7 +104,7 @@ Turn on debugging, and specify which portions of
.Nm
are to print debugging information.
Unless the flags are preceded by
-.Ql -
+.Ql \-
they are added to the
.Va MAKEFLAGS
environment variable and will be processed by any child make processes.
@@ -225,6 +203,10 @@ Print debugging information about makefile parsing.
Print debugging information about suffix-transformation rules.
.It Ar t
Print debugging information about target list maintenance.
+.It Ar V
+Force the
+.Fl V
+option to print raw values of variables.
.It Ar v
Print debugging information about variable assignment.
.It Ar x
@@ -368,6 +350,8 @@ contains a
then the value will be expanded before printing.
.It Fl W
Treat any warnings during makefile parsing as errors.
+.It Fl w
+Print entering and leaving directory messages, pre and post processing.
.It Fl X
Don't export variables passed on the command line to the environment
individually.
@@ -457,17 +441,29 @@ The value
need not necessarily be used to describe existing files.
Expansion is in directory order, not alphabetically as done in the shell.
.Sh SHELL COMMANDS
-Each target may have associated with it a series of shell commands, normally
+Each target may have associated with it one or more lines of shell
+commands, normally
used to create the target.
-Each of the commands in this script
+Each of the lines in this script
.Em must
be preceded by a tab.
-While any target may appear on a dependency line, only one of these
-dependencies may be followed by a creation script, unless the
+(For historical reasons, spaces are not accepted.)
+While targets can appear in many dependency lines if desired, by
+default only one of these rules may be followed by a creation
+script.
+If the
.Ql Ic \&::
-operator is used.
+operator is used, however, all rules may include scripts and the
+scripts are executed in the order found.
.Pp
-If the first characters of the command line are any combination of
+Each line is treated as a separate shell command, unless the end of
+line is escaped with a backslash
+.Pq Ql \e
+in which case that line and the next are combined.
+.\" The escaped newline is retained and passed to the shell, which
+.\" normally ignores it.
+.\" However, the tab at the beginning of the following line is removed.
+If the first characters of the command are any combination of
.Ql Ic @ ,
.Ql Ic + ,
or
@@ -485,7 +481,63 @@ This is similar to the effect of the .MAKE special source,
except that the effect can be limited to a single line of a script.
A
.Ql Ic \-
+in compatibility mode
causes any non-zero exit status of the command line to be ignored.
+.Pp
+When
+.Nm
+is run in jobs mode with
+.Fl j Ar max_jobs ,
+the entire script for the target is fed to a
+single instance of the shell.
+In compatibility (non-jobs) mode, each command is run in a separate process.
+If the command contains any shell meta characters
+.Pq Ql #=|^(){};&<>*?[]:$`\e\en
+it will be passed to the shell; otherwise
+.Nm
+will attempt direct execution.
+If a line starts with
+.Ql Ic \-
+and the shell has ErrCtl enabled then failure of the command line
+will be ignored as in compatibility mode.
+Otherwise
+.Ql Ic \-
+affects the entire job;
+the script will stop at the first command line that fails,
+but the target will not be deemed to have failed.
+.Pp
+Makefiles should be written so that the mode of
+.Nm
+operation does not change their behavior.
+For example, any command which needs to use
+.Dq cd
+or
+.Dq chdir
+without potentially changing the directory for subsequent commands
+should be put in parentheses so it executes in a subshell.
+To force the use of one shell, escape the line breaks so as to make
+the whole script one command.
+For example:
+.Bd -literal -offset indent
+avoid-chdir-side-effects:
+ @echo Building $@ in `pwd`
+ @(cd ${.CURDIR} && ${MAKE} $@)
+ @echo Back in `pwd`
+
+ensure-one-shell-regardless-of-mode:
+ @echo Building $@ in `pwd`; \e
+ (cd ${.CURDIR} && ${MAKE} $@); \e
+ echo Back in `pwd`
+.Ed
+.Pp
+Since
+.Nm
+will
+.Xr chdir 2
+to
+.Ql Va .OBJDIR
+before executing any targets, each child process
+starts with that as its current working directory.
.Sh VARIABLE ASSIGNMENTS
Variables in make are much like variables in the shell, and, by tradition,
consist of all upper-case letters.
@@ -596,13 +648,19 @@ Variables defined in the makefile or in included makefiles.
Variables defined as part of the command line.
.It Local variables
Variables that are defined specific to a certain target.
+.El
+.Pp
+Local variables are all built in and their values vary magically from
+target to target.
+It is not currently possible to define new local variables.
The seven local variables are as follows:
-.Bl -tag -width ".ARCHIVE"
+.Bl -tag -width ".ARCHIVE" -offset indent
.It Va .ALLSRC
The list of all sources for this target; also known as
.Ql Va \&\*[Gt] .
.It Va .ARCHIVE
-The name of the archive file.
+The name of the archive file; also known as
+.Ql Va \&! .
.It Va .IMPSRC
In suffix-transformation rules, the name/path of the source from which the
target is to be transformed (the
@@ -611,7 +669,8 @@ source); also known as
.Ql Va \&\*[Lt] .
It is not defined in explicit rules.
.It Va .MEMBER
-The name of the archive member.
+The name of the archive member; also known as
+.Ql Va % .
.It Va .OODATE
The list of sources for this target that were deemed out-of-date; also
known as
@@ -620,31 +679,41 @@ known as
The file prefix of the target, containing only the file portion, no suffix
or preceding directory components; also known as
.Ql Va * .
+The suffix must be one of the known suffixes declared with
+.Ic .SUFFIXES
+or it will not be recognized.
.It Va .TARGET
The name of the target; also known as
.Ql Va @ .
.El
.Pp
The shorter forms
-.Ql Va @ ,
+.Ql ( Va \*[Gt] ,
+.Ql Va \&! ,
+.Ql Va \*[Lt] ,
+.Ql Va % ,
.Ql Va \&? ,
-.Ql Va \&\*[Lt] ,
-.Ql Va \&\*[Gt] ,
+.Ql Va * ,
and
-.Ql Va *
+.Ql Va @ )
are permitted for backward
-compatibility with historical makefiles and are not recommended.
-The six variables
-.Ql Va "@F" ,
-.Ql Va "@D" ,
-.Ql Va "\*[Lt]F" ,
-.Ql Va "\*[Lt]D" ,
-.Ql Va "*F" ,
+compatibility with historical makefiles and legacy POSIX make and are
+not recommended.
+.Pp
+Variants of these variables with the punctuation followed immediately by
+.Ql D
+or
+.Ql F ,
+e.g.
+.Ql Va $(@D) ,
+are legacy forms equivalent to using the
+.Ql :H
and
-.Ql Va "*D"
-are permitted for compatibility with
+.Ql :T
+modifiers.
+These forms are accepted for compatibility with
.At V
-makefiles and are not recommended.
+makefiles and POSIX but are not recommended.
.Pp
Four of the local variables may be used in sources on dependency lines
because they expand to the proper value for each target on the line.
@@ -654,7 +723,6 @@ These variables are
.Ql Va .ARCHIVE ,
and
.Ql Va .MEMBER .
-.El
.Ss Additional built-in variables
In addition,
.Nm
@@ -678,6 +746,10 @@ was executed.
Refer to the description of
.Ql Ev PWD
for more details.
+.It Va .INCLUDEDFROMDIR
+The directory of the file this Makefile was included from.
+.It Va .INCLUDEDFROMFILE
+The filename of the file this Makefile was included from.
.It Ev MAKE
The name that
.Nm
@@ -697,6 +769,10 @@ and cannot be confused with the special target with the same name.
Names the makefile (default
.Ql Pa .depend )
from which generated dependencies are read.
+.It Va .MAKE.EXPAND_VARIABLES
+A boolean that controls the default behavior of the
+.Fl V
+option.
.It Va .MAKE.EXPORTED
The list of variables exported by
.Nm .
@@ -713,6 +789,9 @@ then output for each target is prefixed with a token
.Ql --- target ---
the first part of which can be controlled via
.Va .MAKE.JOB.PREFIX .
+If
+.Va .MAKE.JOB.PREFIX
+is empty, no token is printed.
.br
For example:
.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
@@ -788,6 +867,9 @@ will not create .meta files in
This can be overridden by setting
.Va bf
to a value which represents True.
+.It Pa env
+For debugging, it can be useful to inlcude the environment
+in the .meta file.
.It Pa verbose
If in "meta" mode, print a clue about the target being built.
This is useful if the build is otherwise running silently.
@@ -799,6 +881,11 @@ This keyword causes them to be ignored for
determining whether a target is out of date in "meta" mode.
See also
.Ic .NOMETA_CMP .
+.It Pa silent= Ar bf
+If
+.Va bf
+is True, when a .meta file is created, mark the target
+.Ic .SILENT .
.El
.It Va .MAKE.META.BAILIWICK
In "meta" mode, provides a list of prefixes which
@@ -818,6 +905,11 @@ In "meta" mode, this variable contains a list of all the meta files
used (updated or not).
This list can be used to process the meta files to extract dependency
information.
+.It Va .MAKE.META.IGNORE_PATHS
+Provides a list of path prefixes that should be ignored;
+because the contents are expected to change over time.
+The default list includes:
+.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp
.It Va .MAKE.META.PREFIX
Defines the message printed for each meta file updated in "meta verbose" mode.
The default value is:
@@ -836,6 +928,13 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
is modified.
+.It Va .MAKE.PATH_FILEMON
+If
+.Nm
+was built with
+.Xr filemon 4
+support, this is set to the path of the device node.
+This allows makefiles to test for this support.
.It Va .MAKE.PID
The process-id of
.Nm .
@@ -918,6 +1017,9 @@ This variable and
are both set only while the
.Ql Pa Makefiles
are being parsed.
+If you want to retain their current values, assign them to a variable
+using assignment with expansion:
+.Pq Ql Cm \&:= .
.It Va .PATH
A variable that represents the list of directories that
.Nm
@@ -1008,6 +1110,13 @@ may
be used.
The wildcard characters may be escaped with a backslash
.Pq Ql \e .
+As a consequence of the way values are split into words, matched,
+and then joined, a construct like
+.Dl ${VAR:M*}
+will normalise the inter-word spacing, removing all leading and
+trailing space, and converting multiple consecutive spaces
+to single spaces.
+.
.It Cm \&:N Ns Ar pattern
This is identical to
.Ql Cm \&:M ,
@@ -1151,7 +1260,7 @@ The
modifier is just like the
.Cm \&:S
modifier except that the old and new strings, instead of being
-simple strings, are a regular expression (see
+simple strings, are an extended regular expression (see
.Xr regex 3 )
string
.Ar pattern
@@ -1181,6 +1290,15 @@ and
are orthogonal; the former specifies whether multiple words are
potentially affected, the latter whether multiple substitutions can
potentially occur within each affected word.
+.Pp
+As for the
+.Cm \&:S
+modifier, the
+.Ar pattern
+and
+.Ar replacement
+are subjected to variable expansion before being parsed as
+regular expressions.
.It Cm \&:T
Replaces each word in the variable with its last component.
.It Cm \&:u
@@ -1249,6 +1367,9 @@ The ODE convention is that
should start and end with a period.
For example.
.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+.Pp
+However a single character variable is often more readable:
+.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
.It Cm \&:U Ns Ar newval
If the variable is undefined
.Ar newval
@@ -1270,6 +1391,8 @@ The path of the node which has the same name as the variable
is the value.
If no such node exists or its path is null, then the
name of the variable is used.
+In order for this modifier to work, the name (node) must at least have
+appeared on the rhs of a dependency.
.Sm off
.It Cm \&:\&! Ar cmd Cm \&!
.Sm on
@@ -1330,7 +1453,7 @@ For the purposes of the
modifier, the words are indexed both forwards using positive integers
(where index 1 represents the first word),
and backwards using negative integers
-(where index -1 represents the last word).
+(where index \-1 represents the last word).
.Pp
The
.Ar range
@@ -1429,6 +1552,11 @@ except for internal variables (those that start with
This is not affected by the
.Fl X
flag, so should be used with caution.
+For compatibility with other
+.Nm
+programs
+.Ql export variable=value
+is also accepted.
.Pp
Appending a variable name to
.Va .MAKE.EXPORTED
@@ -1683,7 +1811,7 @@ or
.Fl t
options were specified.
Normally used to mark recursive
-.Nm Ns 's .
+.Nm Ns s .
.It Ic .META
Create a meta file for the target, even if it is flagged as
.Ic .PHONY ,
@@ -1693,6 +1821,7 @@ or
Usage in conjunction with
.Ic .MAKE
is the most likely case.
+In "meta" mode, the target is out-of-date if the meta file is missing.
.It Ic .NOMETA
Do not create a meta file for the target.
Meta files are also not created for
@@ -1705,6 +1834,20 @@ targets.
Ignore differences in commands when deciding if target is out of date.
This is useful if the command contains a value which always changes.
If the number of commands change, though, the target will still be out of date.
+The same effect applies to any command line that uses the variable
+.Va .OODATE ,
+which can be used for that purpose even when not otherwise needed or desired:
+.Bd -literal -offset indent
+
+skip-compare-for-some:
+ @echo this will be compared
+ @echo this will not ${.OODATE:M.NOMETA_CMP}
+ @echo this will also be compared
+
+.Ed
+The
+.Cm \&:M
+pattern suppresses any expansion of the unwanted variable.
.It Ic .NOPATH
Do not search for the target in the directories specified by
.Ic .PATH .
@@ -1888,6 +2031,12 @@ If the source is the special
.Ic .DOTLAST
target, then the current working
directory is searched last.
+.It Ic .PATH. Ns Va suffix
+Like
+.Ic .PATH
+but applies only to files with a particular suffix.
+The suffix must have been previously declared with
+.Ic .SUFFIXES .
.It Ic .PHONY
Apply the
.Ic .PHONY
@@ -1944,8 +2093,8 @@ character when used outside of any quoting characters.
Example:
.Bd -literal
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
- check="set -e" ignore="set +e" \e
- echo="set -v" quiet="set +v" filter="set +v" \e
+ check="set \-e" ignore="set +e" \e
+ echo="set \-v" quiet="set +v" filter="set +v" \e
echoFlag=v errFlag=e newline="'\en'"
.Ed
.It Ic .SILENT
@@ -1956,6 +2105,10 @@ If no sources are specified, the
.Ic .SILENT
attribute is applied to every
command in the file.
+.It Ic .STALE
+This target gets run when a dependency file contains stale entries, having
+.Va .ALLSRC
+set to the name of that dependency file.
.It Ic .SUFFIXES
Each source specifies a suffix to
.Nm .
@@ -1966,7 +2119,7 @@ Example:
.Bd -literal
\&.SUFFIXES: .o
\&.c.o:
- cc -o ${.TARGET} -c ${.IMPSRC}
+ cc \-o ${.TARGET} \-c ${.IMPSRC}
.Ed
.El
.Sh ENVIRONMENT
@@ -2006,38 +2159,121 @@ system makefile
system makefile directory
.El
.Sh COMPATIBILITY
-The basic make syntax is compatible between different versions of make,
+The basic make syntax is compatible between different versions of make;
however the special variables, variable modifiers and conditionals are not.
-.Pp
-The way that parallel makes are scheduled changed in
-.Nx 4.0
-so that .ORDER and .WAIT apply recursively to the dependant nodes.
-The algorithms used may change again in the future.
+.Ss Older versions
+An incomplete list of changes in older versions of
+.Nm :
.Pp
The way that .for loop variables are substituted changed after
-.Nx 5.0
+NetBSD 5.0
so that they still appear to be variable expansions.
In particular this stops them being treated as syntax, and removes some
obscure problems using them in .if statements.
.Pp
-Unlike other
+The way that parallel makes are scheduled changed in
+NetBSD 4.0
+so that .ORDER and .WAIT apply recursively to the dependent nodes.
+The algorithms used may change again in the future.
+.Ss Other make dialects
+Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not
+support most of the features of
.Nm
-programs, this implementation by default executes all commands for a given
-target using a single shell invocation.
-This is done for both efficiency and to simplify error handling in remote
-command invocations.
-Typically this is transparent to the user, unless the target commands change
-the current working directory using
-.Dq cd
-or
-.Dq chdir .
-To be compatible with Makefiles that do this, one can use
-.Fl B
-to disable this behavior.
+as described in this manual.
+Most notably:
+.Bl -bullet -offset indent
+.It
+The
+.Ic .WAIT
+and
+.Ic .ORDER
+declarations and most functionality pertaining to parallelization.
+(GNU make supports parallelization but lacks these features needed to
+control it effectively.)
+.It
+Directives, including for loops and conditionals and most of the
+forms of include files.
+(GNU make has its own incompatible and less powerful syntax for
+conditionals.)
+.It
+All built-in variables that begin with a dot.
+.It
+Most of the special sources and targets that begin with a dot,
+with the notable exception of
+.Ic .PHONY ,
+.Ic .PRECIOUS ,
+and
+.Ic .SUFFIXES .
+.It
+Variable modifiers, except for the
+.Dl :old=new
+string substitution, which does not portably support globbing with
+.Ql %
+and historically only works on declared suffixes.
+.It
+The
+.Ic $>
+variable even in its short form; most makes support this functionality
+but its name varies.
+.El
+.Pp
+Some features are somewhat more portable, such as assignment with
+.Ic += ,
+.Ic ?= ,
+and
+.Ic != .
+The
+.Ic .PATH
+functionality is based on an older feature
+.Ic VPATH
+found in GNU make and many versions of SVR4 make; however,
+historically its behavior is too ill-defined (and too buggy) to rely
+upon.
+.Pp
+The
+.Ic $@
+and
+.Ic $<
+variables are more or less universally portable, as is the
+.Ic $(MAKE)
+variable.
+Basic use of suffix rules (for files only in the current directory,
+not trying to chain transformations together, etc.) is also reasonably
+portable.
.Sh SEE ALSO
.Xr mkdep 1
.Sh HISTORY
.Nm
-is derived from NetBSD's
+is derived from NetBSD
.Xr make 1 .
It uses autoconf to facilitate portability to other platforms.
+.Pp
+A
+make
+command appeared in
+.At v7 .
+This
+make
+implementation is based on Adam De Boor's pmake program which was written
+for Sprite at Berkeley.
+It was designed to be a parallel distributed make running jobs on different
+machines using a daemon called
+.Dq customs .
+.Pp
+Historically the target/dependency
+.Dq FRC
+has been used to FoRCe rebuilding (since the target/dependency
+does not exist... unless someone creates an
+.Dq FRC
+file).
+.Sh BUGS
+The
+make
+syntax is difficult to parse without actually acting of the data.
+For instance finding the end of a variable use should involve scanning each
+the modifiers using the correct terminator for each field.
+In many places
+make
+just counts {} and () in order to find the end of a variable expansion.
+.Pp
+There is no way of escaping a space character in a filename.
diff --git a/devel/bmake/files/bmake.cat1 b/devel/bmake/files/bmake.cat1
index 8fceef71e5b..5c62c1ba8e4 100644
--- a/devel/bmake/files/bmake.cat1
+++ b/devel/bmake/files/bmake.cat1
@@ -4,7 +4,7 @@ NNAAMMEE
bbmmaakkee -- maintain program dependencies
SSYYNNOOPPSSIISS
- bbmmaakkee [--BBeeiikkNNnnqqrrssttWWXX] [--CC _d_i_r_e_c_t_o_r_y] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s]
+ bbmmaakkee [--BBeeiikkNNnnqqrrssttWWwwXX] [--CC _d_i_r_e_c_t_o_r_y] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s]
[--ff _m_a_k_e_f_i_l_e] [--II _d_i_r_e_c_t_o_r_y] [--JJ _p_r_i_v_a_t_e] [--jj _m_a_x___j_o_b_s]
[--mm _d_i_r_e_c_t_o_r_y] [--TT _f_i_l_e] [--VV _v_a_r_i_a_b_l_e] [_v_a_r_i_a_b_l_e_=_v_a_l_u_e]
[_t_a_r_g_e_t _._._.]
@@ -18,7 +18,7 @@ DDEESSCCRRIIPPTTIIOONN
mkdep(1)).
This manual page is intended as a reference document only. For a more
- thorough description of bbmmaakkee and makefiles, please refer to _M_a_k_e _- _A
+ thorough description of bbmmaakkee and makefiles, please refer to _P_M_a_k_e _- _A
_T_u_t_o_r_i_a_l.
bbmmaakkee will prepend the contents of the _M_A_K_E_F_L_A_G_S environment variable to
@@ -118,6 +118,8 @@ DDEESSCCRRIIPPTTIIOONN
_t Print debugging information about target list mainte-
nance.
+ _V Force the --VV option to print raw values of variables.
+
_v Print debugging information about variable assignment.
_x Run shell commands with --xx so the actual commands are
@@ -216,6 +218,9 @@ DDEESSCCRRIIPPTTIIOONN
--WW Treat any warnings during makefile parsing as errors.
+ --ww Print entering and leaving directory messages, pre and post pro-
+ cessing.
+
--XX Don't export variables passed on the command line to the environ-
ment individually. Variables passed on the command line are
still exported via the _M_A_K_E_F_L_A_G_S environment variable. This
@@ -268,19 +273,54 @@ FFIILLEE DDEEPPEENNDDEENNCCYY SSPPEECCIIFFIICCAATTIIOO
done in the shell.
SSHHEELLLL CCOOMMMMAANNDDSS
- Each target may have associated with it a series of shell commands, nor-
- mally used to create the target. Each of the commands in this script
- _m_u_s_t be preceded by a tab. While any target may appear on a dependency
- line, only one of these dependencies may be followed by a creation
- script, unless the `::::' operator is used.
-
- If the first characters of the command line are any combination of `@@',
- `++', or `--', the command is treated specially. A `@@' causes the command
- not to be echoed before it is executed. A `++' causes the command to be
- executed even when --nn is given. This is similar to the effect of the
- .MAKE special source, except that the effect can be limited to a single
- line of a script. A `--' causes any non-zero exit status of the command
- line to be ignored.
+ Each target may have associated with it one or more lines of shell com-
+ mands, normally used to create the target. Each of the lines in this
+ script _m_u_s_t be preceded by a tab. (For historical reasons, spaces are
+ not accepted.) While targets can appear in many dependency lines if
+ desired, by default only one of these rules may be followed by a creation
+ script. If the `::::' operator is used, however, all rules may include
+ scripts and the scripts are executed in the order found.
+
+ Each line is treated as a separate shell command, unless the end of line
+ is escaped with a backslash (`\') in which case that line and the next
+ are combined. If the first characters of the command are any combination
+ of `@@', `++', or `--', the command is treated specially. A `@@' causes the
+ command not to be echoed before it is executed. A `++' causes the command
+ to be executed even when --nn is given. This is similar to the effect of
+ the .MAKE special source, except that the effect can be limited to a sin-
+ gle line of a script. A `--' in compatibility mode causes any non-zero
+ exit status of the command line to be ignored.
+
+ When bbmmaakkee is run in jobs mode with --jj _m_a_x___j_o_b_s, the entire script for
+ the target is fed to a single instance of the shell. In compatibility
+ (non-jobs) mode, each command is run in a separate process. If the com-
+ mand contains any shell meta characters (`#=|^(){};&<>*?[]:$`\\n') it
+ will be passed to the shell; otherwise bbmmaakkee will attempt direct execu-
+ tion. If a line starts with `--' and the shell has ErrCtl enabled then
+ failure of the command line will be ignored as in compatibility mode.
+ Otherwise `--' affects the entire job; the script will stop at the first
+ command line that fails, but the target will not be deemed to have
+ failed.
+
+ Makefiles should be written so that the mode of bbmmaakkee operation does not
+ change their behavior. For example, any command which needs to use
+ ``cd'' or ``chdir'' without potentially changing the directory for subse-
+ quent commands should be put in parentheses so it executes in a subshell.
+ To force the use of one shell, escape the line breaks so as to make the
+ whole script one command. For example:
+
+ avoid-chdir-side-effects:
+ @echo Building $@ in `pwd`
+ @(cd ${.CURDIR} && ${MAKE} $@)
+ @echo Back in `pwd`
+
+ ensure-one-shell-regardless-of-mode:
+ @echo Building $@ in `pwd`; \
+ (cd ${.CURDIR} && ${MAKE} $@); \
+ echo Back in `pwd`
+
+ Since bbmmaakkee will chdir(2) to `_._O_B_J_D_I_R' before executing any targets, each
+ child process starts with that as its current working directory.
VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
Variables in make are much like variables in the shell, and, by tradi-
@@ -371,40 +411,47 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
Variables defined as part of the command line.
Local variables
- Variables that are defined specific to a certain target. The
- seven local variables are as follows:
+ Variables that are defined specific to a certain target.
+
+ Local variables are all built in and their values vary magically from
+ target to target. It is not currently possible to define new local vari-
+ ables. The seven local variables are as follows:
- _._A_L_L_S_R_C The list of all sources for this target; also known as
- `_>'.
+ _._A_L_L_S_R_C The list of all sources for this target; also known as
+ `_>'.
- _._A_R_C_H_I_V_E The name of the archive file.
+ _._A_R_C_H_I_V_E The name of the archive file; also known as `_!'.
- _._I_M_P_S_R_C In suffix-transformation rules, the name/path of the
- source from which the target is to be transformed (the
- ``implied'' source); also known as `_<'. It is not
- defined in explicit rules.
+ _._I_M_P_S_R_C In suffix-transformation rules, the name/path of the
+ source from which the target is to be transformed (the
+ ``implied'' source); also known as `_<'. It is not
+ defined in explicit rules.
- _._M_E_M_B_E_R The name of the archive member.
+ _._M_E_M_B_E_R The name of the archive member; also known as `_%'.
- _._O_O_D_A_T_E The list of sources for this target that were deemed
- out-of-date; also known as `_?'.
+ _._O_O_D_A_T_E The list of sources for this target that were deemed out-
+ of-date; also known as `_?'.
- _._P_R_E_F_I_X The file prefix of the target, containing only the file
- portion, no suffix or preceding directory components;
- also known as `_*'.
+ _._P_R_E_F_I_X The file prefix of the target, containing only the file
+ portion, no suffix or preceding directory components;
+ also known as `_*'. The suffix must be one of the known
+ suffixes declared with ..SSUUFFFFIIXXEESS or it will not be recog-
+ nized.
- _._T_A_R_G_E_T The name of the target; also known as `_@'.
+ _._T_A_R_G_E_T The name of the target; also known as `_@'.
- The shorter forms `_@', `_?', `_<', `_>', and `_*' are permitted for
- backward compatibility with historical makefiles and are not rec-
- ommended. The six variables `_@_F', `_@_D', `_<_F', `_<_D', `_*_F', and
- `_*_D' are permitted for compatibility with AT&T System V UNIX
- makefiles and are not recommended.
+ The shorter forms (`_>', `_!', `_<', `_%', `_?', `_*', and `_@') are permitted
+ for backward compatibility with historical makefiles and legacy POSIX
+ make and are not recommended.
- Four of the local variables may be used in sources on dependency
- lines because they expand to the proper value for each target on
- the line. These variables are `_._T_A_R_G_E_T', `_._P_R_E_F_I_X', `_._A_R_C_H_I_V_E',
- and `_._M_E_M_B_E_R'.
+ Variants of these variables with the punctuation followed immediately by
+ `D' or `F', e.g. `_$_(_@_D_)', are legacy forms equivalent to using the `:H'
+ and `:T' modifiers. These forms are accepted for compatibility with AT&T
+ System V UNIX makefiles and POSIX but are not recommended.
+
+ Four of the local variables may be used in sources on dependency lines
+ because they expand to the proper value for each target on the line.
+ These variables are `_._T_A_R_G_E_T', `_._P_R_E_F_I_X', `_._A_R_C_H_I_V_E', and `_._M_E_M_B_E_R'.
AAddddiittiioonnaall bbuuiilltt--iinn vvaarriiaabblleess
In addition, bbmmaakkee sets or knows about the following variables:
@@ -419,6 +466,13 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
_._C_U_R_D_I_R A path to the directory where bbmmaakkee was executed. Refer
to the description of `PWD' for more details.
+ _._I_N_C_L_U_D_E_D_F_R_O_M_D_I_R
+ The directory of the file this Makefile was included
+ from.
+
+ _._I_N_C_L_U_D_E_D_F_R_O_M_F_I_L_E
+ The filename of the file this Makefile was included from.
+
MAKE The name that bbmmaakkee was executed with (_a_r_g_v_[_0_]). For
compatibility bbmmaakkee also sets _._M_A_K_E with the same value.
The preferred variable to use is the environment variable
@@ -430,6 +484,10 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
Names the makefile (default `_._d_e_p_e_n_d') from which gener-
ated dependencies are read.
+ _._M_A_K_E_._E_X_P_A_N_D___V_A_R_I_A_B_L_E_S
+ A boolean that controls the default behavior of the --VV
+ option.
+
_._M_A_K_E_._E_X_P_O_R_T_E_D The list of variables exported by bbmmaakkee.
_._M_A_K_E_._J_O_B_S The argument to the --jj option.
@@ -437,7 +495,8 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
_._M_A_K_E_._J_O_B_._P_R_E_F_I_X
If bbmmaakkee is run with _j then output for each target is
prefixed with a token `--- target ---' the first part of
- which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X.
+ which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X. If
+ _._M_A_K_E_._J_O_B_._P_R_E_F_I_X is empty, no token is printed.
For example:
.MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
would produce tokens like `---make[1234] target ---' mak-
@@ -484,6 +543,9 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
in `_._C_U_R_D_I_R'. This can be overridden by set-
ting _b_f to a value which represents True.
+ _e_n_v For debugging, it can be useful to inlcude
+ the environment in the .meta file.
+
_v_e_r_b_o_s_e If in "meta" mode, print a clue about the
target being built. This is useful if the
build is otherwise running silently. The
@@ -496,6 +558,9 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
out of date in "meta" mode. See also
..NNOOMMEETTAA__CCMMPP.
+ _s_i_l_e_n_t_= _b_f If _b_f is True, when a .meta file is created,
+ mark the target ..SSIILLEENNTT.
+
_._M_A_K_E_._M_E_T_A_._B_A_I_L_I_W_I_C_K
In "meta" mode, provides a list of prefixes which match
the directories controlled by bbmmaakkee. If a file that was
@@ -513,6 +578,12 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
to process the meta files to extract dependency informa-
tion.
+ _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___P_A_T_H_S
+ Provides a list of path prefixes that should be ignored;
+ because the contents are expected to change over time.
+ The default list includes: `_/_d_e_v _/_e_t_c _/_p_r_o_c _/_t_m_p _/_v_a_r_/_r_u_n
+ _/_v_a_r_/_t_m_p'
+
_._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X
Defines the message printed for each meta file updated in
"meta verbose" mode. The default value is:
@@ -527,6 +598,11 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
`MAKEFLAGS' is re-exported whenever `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is
modified.
+ _._M_A_K_E_._P_A_T_H___F_I_L_E_M_O_N
+ If bbmmaakkee was built with filemon(4) support, this is set
+ to the path of the device node. This allows makefiles to
+ test for this support.
+
_._M_A_K_E_._P_I_D The process-id of bbmmaakkee.
_._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
@@ -581,7 +657,9 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
_._P_A_R_S_E_F_I_L_E The basename of the current `_M_a_k_e_f_i_l_e' being parsed.
This variable and `_._P_A_R_S_E_D_I_R' are both set only while the
- `_M_a_k_e_f_i_l_e_s' are being parsed.
+ `_M_a_k_e_f_i_l_e_s' are being parsed. If you want to retain
+ their current values, assign them to a variable using
+ assignment with expansion: (`::==').
_._P_A_T_H A variable that represents the list of directories that
bbmmaakkee will search for files. The search list should be
@@ -635,7 +713,13 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
::MM_p_a_t_t_e_r_n
Select only those words that match _p_a_t_t_e_r_n. The standard shell
wildcard characters (`*', `?', and `[]') may be used. The wildcard
- characters may be escaped with a backslash (`\').
+ characters may be escaped with a backslash (`\'). As a consequence
+ of the way values are split into words, matched, and then joined, a
+ construct like
+ ${VAR:M*}
+ will normalise the inter-word spacing, removing all leading and
+ trailing space, and converting multiple consecutive spaces to single
+ spaces.
::NN_p_a_t_t_e_r_n
This is identical to `::MM', but selects all words which do not match
@@ -722,18 +806,21 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
::CC/_p_a_t_t_e_r_n/_r_e_p_l_a_c_e_m_e_n_t/[11ggWW]
The ::CC modifier is just like the ::SS modifier except that the old and
- new strings, instead of being simple strings, are a regular expres-
- sion (see regex(3)) string _p_a_t_t_e_r_n and an ed(1)-style string
- _r_e_p_l_a_c_e_m_e_n_t. Normally, the first occurrence of the pattern _p_a_t_t_e_r_n
- in each word of the value is substituted with _r_e_p_l_a_c_e_m_e_n_t. The `1'
- modifier causes the substitution to apply to at most one word; the
- `g' modifier causes the substitution to apply to as many instances
- of the search pattern _p_a_t_t_e_r_n as occur in the word or words it is
- found in; the `W' modifier causes the value to be treated as a sin-
- gle word (possibly containing embedded white space). Note that `1'
- and `g' are orthogonal; the former specifies whether multiple words
- are potentially affected, the latter whether multiple substitutions
- can potentially occur within each affected word.
+ new strings, instead of being simple strings, are an extended regu-
+ lar expression (see regex(3)) string _p_a_t_t_e_r_n and an ed(1)-style
+ string _r_e_p_l_a_c_e_m_e_n_t. Normally, the first occurrence of the pattern
+ _p_a_t_t_e_r_n in each word of the value is substituted with _r_e_p_l_a_c_e_m_e_n_t.
+ The `1' modifier causes the substitution to apply to at most one
+ word; the `g' modifier causes the substitution to apply to as many
+ instances of the search pattern _p_a_t_t_e_r_n as occur in the word or
+ words it is found in; the `W' modifier causes the value to be
+ treated as a single word (possibly containing embedded white space).
+ Note that `1' and `g' are orthogonal; the former specifies whether
+ multiple words are potentially affected, the latter whether multiple
+ substitutions can potentially occur within each affected word.
+
+ As for the ::SS modifier, the _p_a_t_t_e_r_n and _r_e_p_l_a_c_e_m_e_n_t are subjected to
+ variable expansion before being parsed as regular expressions.
::TT Replaces each word in the variable with its last component.
@@ -773,6 +860,9 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
period. For example.
${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+ However a single character variable is often more readable:
+ ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+
::UU_n_e_w_v_a_l
If the variable is undefined _n_e_w_v_a_l is the value. If the variable
is defined, the existing value is returned. This is another ODE
@@ -789,7 +879,8 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
::PP The path of the node which has the same name as the variable is the
value. If no such node exists or its path is null, then the name of
- the variable is used.
+ the variable is used. In order for this modifier to work, the name
+ (node) must at least have appeared on the rhs of a dependency.
::!!_c_m_d!!
The output of running _c_m_d is the value.
@@ -880,7 +971,8 @@ IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOO
Export the specified global variable. If no variable list is
provided, all globals are exported except for internal variables
(those that start with `.'). This is not affected by the --XX
- flag, so should be used with caution.
+ flag, so should be used with caution. For compatibility with
+ other bbmmaakkee programs `export variable=value' is also accepted.
Appending a variable name to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to
exporting a variable.
@@ -1047,11 +1139,12 @@ SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS))
..MMAAKKEE Execute the commands associated with this target even if the --nn
or --tt options were specified. Normally used to mark recursive
- bbmmaakkee's.
+ bbmmaakkees.
..MMEETTAA Create a meta file for the target, even if it is flagged as
..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL. Usage in conjunction with ..MMAAKKEE is
- the most likely case.
+ the most likely case. In "meta" mode, the target is out-of-
+ date if the meta file is missing.
..NNOOMMEETTAA Do not create a meta file for the target. Meta files are also
not created for ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL targets.
@@ -1060,7 +1153,19 @@ SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS))
Ignore differences in commands when deciding if target is out
of date. This is useful if the command contains a value which
always changes. If the number of commands change, though, the
- target will still be out of date.
+ target will still be out of date. The same effect applies to
+ any command line that uses the variable _._O_O_D_A_T_E, which can be
+ used for that purpose even when not otherwise needed or
+ desired:
+
+
+ skip-compare-for-some:
+ @echo this will be compared
+ @echo this will not ${.OODATE:M.NOMETA_CMP}
+ @echo this will also be compared
+
+ The ::MM pattern suppresses any expansion of the unwanted vari-
+ able.
..NNOOPPAATTHH Do not search for the target in the directories specified by
..PPAATTHH.
@@ -1184,6 +1289,10 @@ SSPPEECCIIAALL TTAARRGGEETTSS
source is the special ..DDOOTTLLAASSTT target, then the current working
directory is searched last.
+ ..PPAATTHH.._s_u_f_f_i_x
+ Like ..PPAATTHH but applies only to files with a particular suffix.
+ The suffix must have been previously declared with ..SSUUFFFFIIXXEESS.
+
..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources.
..PPRREECCIIOOUUSS
@@ -1232,6 +1341,9 @@ SSPPEECCIIAALL TTAARRGGEETTSS
sources are specified, the ..SSIILLEENNTT attribute is applied to every
command in the file.
+ ..SSTTAALLEE This target gets run when a dependency file contains stale
+ entries, having _._A_L_L_S_R_C set to the name of that dependency file.
+
..SSUUFFFFIIXXEESS
Each source specifies a suffix to bbmmaakkee. If no sources are
specified, any previously specified suffixes are deleted. It
@@ -1260,1322 +1372,81 @@ FFIILLEESS
/usr/share/mk system makefile directory
CCOOMMPPAATTIIBBIILLIITTYY
- The basic make syntax is compatible between different versions of make,
+ The basic make syntax is compatible between different versions of make;
however the special variables, variable modifiers and conditionals are
not.
- The way that parallel makes are scheduled changed in NetBSD 4.0 so that
- .ORDER and .WAIT apply recursively to the dependant nodes. The algo-
- rithms used may change again in the future.
+ OOllddeerr vveerrssiioonnss
+ An incomplete list of changes in older versions of bbmmaakkee:
The way that .for loop variables are substituted changed after NetBSD 5.0
so that they still appear to be variable expansions. In particular this
stops them being treated as syntax, and removes some obscure problems
using them in .if statements.
- Unlike other bbmmaakkee programs, this implementation by default executes all
- commands for a given target using a single shell invocation. This is
- done for both efficiency and to simplify error handling in remote command
- invocations. Typically this is transparent to the user, unless the tar-
- get commands change the current working directory using ``cd'' or
- ``chdir''. To be compatible with Makefiles that do this, one can use --BB
- to disable this behavior.
-
-SSEEEE AALLSSOO
- mkdep(1)
-
-HHIISSTTOORRYY
- bbmmaakkee is derived from NetBSD's make(1). It uses autoconf to facilitate
-MAKE(1) NetBSD General Commands Manual MAKE(1)
-
- portability to other platforms.
-
-NNAAMMEE
- bbmmaakkee -- maintain program dependencies
-
-SSYYNNOOPPSSIISS
- bbmmaakkee [--BBeeiikkNNnnqqrrssttWWXX] [--CC _d_i_r_e_c_t_o_r_y] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s]
- [--ff _m_a_k_e_f_i_l_e] [--II _d_i_r_e_c_t_o_r_y] [--JJ _p_r_i_v_a_t_e] [--jj _m_a_x___j_o_b_s]
- [--mm _d_i_r_e_c_t_o_r_y] [--TT _f_i_l_e] [--VV _v_a_r_i_a_b_l_e] [_v_a_r_i_a_b_l_e_=_v_a_l_u_e]
- [_t_a_r_g_e_t _._._.]
-
-DDEESSCCRRIIPPTTIIOONN
- bbmmaakkee is a program designed to simplify the maintenance of other pro-
- grams. Its input is a list of specifications as to the files upon which
- programs and other files depend. If no --ff _m_a_k_e_f_i_l_e makefile option is
- given, bbmmaakkee will try to open `_m_a_k_e_f_i_l_e' then `_M_a_k_e_f_i_l_e' in order to find
- the specifications. If the file `_._d_e_p_e_n_d' exists, it is read (see
- mkdep(1)).
-
- This manual page is intended as a reference document only. For a more
- thorough description of bbmmaakkee and makefiles, please refer to _M_a_k_e _- _A
- _T_u_t_o_r_i_a_l.
-
- bbmmaakkee will prepend the contents of the _M_A_K_E_F_L_A_G_S environment variable to
- the command line arguments before parsing them.
-
- The options are as follows:
-
- --BB Try to be backwards compatible by executing a single shell per
- command and by executing the commands to make the sources of a
- dependency line in sequence.
-
- --CC _d_i_r_e_c_t_o_r_y
- Change to _d_i_r_e_c_t_o_r_y before reading the makefiles or doing any-
- thing else. If multiple --CC options are specified, each is inter-
- preted relative to the previous one: --CC _/ --CC _e_t_c is equivalent to
- --CC _/_e_t_c.
-
- --DD _v_a_r_i_a_b_l_e
- Define _v_a_r_i_a_b_l_e to be 1, in the global context.
-
- --dd _[_-_]_f_l_a_g_s
- Turn on debugging, and specify which portions of bbmmaakkee are to
- print debugging information. Unless the flags are preceded by
- `-' they are added to the _M_A_K_E_F_L_A_G_S environment variable and will
- be processed by any child make processes. By default, debugging
- information is printed to standard error, but this can be changed
- using the _F debugging flag. The debugging output is always
- unbuffered; in addition, if debugging is enabled but debugging
- output is not directed to standard output, then the standard out-
- put is line buffered. _F_l_a_g_s is one or more of the following:
-
- _A Print all possible debugging information; equivalent to
- specifying all of the debugging flags.
-
- _a Print debugging information about archive searching and
- caching.
-
- _C Print debugging information about current working direc-
- tory.
-
- _c Print debugging information about conditional evaluation.
-
- _d Print debugging information about directory searching and
- caching.
-
- _e Print debugging information about failed commands and
- targets.
-
- _F[++]_f_i_l_e_n_a_m_e
- Specify where debugging output is written. This must be
- the last flag, because it consumes the remainder of the
- argument. If the character immediately after the `F'
- flag is `+', then the file will be opened in append mode;
- otherwise the file will be overwritten. If the file name
- is `stdout' or `stderr' then debugging output will be
- written to the standard output or standard error output
- file descriptors respectively (and the `+' option has no
- effect). Otherwise, the output will be written to the
- named file. If the file name ends `.%d' then the `%d' is
- replaced by the pid.
-
- _f Print debugging information about loop evaluation.
-
- _g_1 Print the input graph before making anything.
-
- _g_2 Print the input graph after making everything, or before
- exiting on error.
-
- _g_3 Print the input graph before exiting on error.
-
- _j Print debugging information about running multiple
- shells.
-
- _l Print commands in Makefiles regardless of whether or not
- they are prefixed by `@' or other "quiet" flags. Also
- known as "loud" behavior.
-
- _M Print debugging information about "meta" mode decisions
- about targets.
-
- _m Print debugging information about making targets, includ-
- ing modification dates.
-
- _n Don't delete the temporary command scripts created when
- running commands. These temporary scripts are created in
- the directory referred to by the TMPDIR environment vari-
- able, or in _/_t_m_p if TMPDIR is unset or set to the empty
- string. The temporary scripts are created by mkstemp(3),
- and have names of the form _m_a_k_e_X_X_X_X_X_X. _N_O_T_E: This can
- create many files in TMPDIR or _/_t_m_p, so use with care.
-
- _p Print debugging information about makefile parsing.
-
- _s Print debugging information about suffix-transformation
- rules.
-
- _t Print debugging information about target list mainte-
- nance.
-
- _v Print debugging information about variable assignment.
-
- _x Run shell commands with --xx so the actual commands are
- printed as they are executed.
-
- --ee Specify that environment variables override macro assignments
- within makefiles.
-
- --ff _m_a_k_e_f_i_l_e
- Specify a makefile to read instead of the default `_m_a_k_e_f_i_l_e'. If
- _m_a_k_e_f_i_l_e is `--', standard input is read. Multiple makefiles may
- be specified, and are read in the order specified.
-
- --II _d_i_r_e_c_t_o_r_y
- Specify a directory in which to search for makefiles and included
- makefiles. The system makefile directory (or directories, see
- the --mm option) is automatically included as part of this list.
-
- --ii Ignore non-zero exit of shell commands in the makefile. Equiva-
- lent to specifying `--' before each command line in the makefile.
-
- --JJ _p_r_i_v_a_t_e
- This option should _n_o_t be specified by the user.
-
- When the _j option is in use in a recursive build, this option is
- passed by a make to child makes to allow all the make processes
- in the build to cooperate to avoid overloading the system.
-
- --jj _m_a_x___j_o_b_s
- Specify the maximum number of jobs that bbmmaakkee may have running at
- any one time. The value is saved in _._M_A_K_E_._J_O_B_S. Turns compati-
- bility mode off, unless the _B flag is also specified. When com-
- patibility mode is off, all commands associated with a target are
- executed in a single shell invocation as opposed to the tradi-
- tional one shell invocation per line. This can break traditional
- scripts which change directories on each command invocation and
- then expect to start with a fresh environment on the next line.
- It is more efficient to correct the scripts rather than turn
- backwards compatibility on.
-
- --kk Continue processing after errors are encountered, but only on
- those targets that do not depend on the target whose creation
- caused the error.
-
- --mm _d_i_r_e_c_t_o_r_y
- Specify a directory in which to search for sys.mk and makefiles
- included via the <_f_i_l_e>-style include statement. The --mm option
- can be used multiple times to form a search path. This path will
- override the default system include path: /usr/share/mk. Fur-
- thermore the system include path will be appended to the search
- path used for "_f_i_l_e"-style include statements (see the --II
- option).
-
- If a file or directory name in the --mm argument (or the
- MAKESYSPATH environment variable) starts with the string ".../"
- then bbmmaakkee will search for the specified file or directory named
- in the remaining part of the argument string. The search starts
- with the current directory of the Makefile and then works upward
- towards the root of the filesystem. If the search is successful,
- then the resulting directory replaces the ".../" specification in
- the --mm argument. If used, this feature allows bbmmaakkee to easily
- search in the current source tree for customized sys.mk files
- (e.g., by using ".../mk/sys.mk" as an argument).
-
- --nn Display the commands that would have been executed, but do not
- actually execute them unless the target depends on the .MAKE spe-
- cial source (see below).
-
- --NN Display the commands which would have been executed, but do not
- actually execute any of them; useful for debugging top-level
- makefiles without descending into subdirectories.
-
- --qq Do not execute any commands, but exit 0 if the specified targets
- are up-to-date and 1, otherwise.
-
- --rr Do not use the built-in rules specified in the system makefile.
-
- --ss Do not echo any commands as they are executed. Equivalent to
- specifying `@@' before each command line in the makefile.
-
- --TT _t_r_a_c_e_f_i_l_e
- When used with the --jj flag, append a trace record to _t_r_a_c_e_f_i_l_e
- for each job started and completed.
-
- --tt Rather than re-building a target as specified in the makefile,
- create it or update its modification time to make it appear up-
- to-date.
-
- --VV _v_a_r_i_a_b_l_e
- Print bbmmaakkee's idea of the value of _v_a_r_i_a_b_l_e, in the global con-
- text. Do not build any targets. Multiple instances of this
- option may be specified; the variables will be printed one per
- line, with a blank line for each null or undefined variable. If
- _v_a_r_i_a_b_l_e contains a `$' then the value will be expanded before
- printing.
-
- --WW Treat any warnings during makefile parsing as errors.
-
- --XX Don't export variables passed on the command line to the environ-
- ment individually. Variables passed on the command line are
- still exported via the _M_A_K_E_F_L_A_G_S environment variable. This
- option may be useful on systems which have a small limit on the
- size of command arguments.
-
- _v_a_r_i_a_b_l_e_=_v_a_l_u_e
- Set the value of the variable _v_a_r_i_a_b_l_e to _v_a_l_u_e. Normally, all
- values passed on the command line are also exported to sub-makes
- in the environment. The --XX flag disables this behavior. Vari-
- able assignments should follow options for POSIX compatibility
- but no ordering is enforced.
-
- There are seven different types of lines in a makefile: file dependency
- specifications, shell commands, variable assignments, include statements,
- conditional directives, for loops, and comments.
-
- In general, lines may be continued from one line to the next by ending
- them with a backslash (`\'). The trailing newline character and initial
- whitespace on the following line are compressed into a single space.
-
-FFIILLEE DDEEPPEENNDDEENNCCYY SSPPEECCIIFFIICCAATTIIOONNSS
- Dependency lines consist of one or more targets, an operator, and zero or
- more sources. This creates a relationship where the targets ``depend''
- on the sources and are usually created from them. The exact relationship
- between the target and the source is determined by the operator that sep-
- arates them. The three operators are as follows:
-
- :: A target is considered out-of-date if its modification time is less
- than those of any of its sources. Sources for a target accumulate
- over dependency lines when this operator is used. The target is
- removed if bbmmaakkee is interrupted.
-
- !! Targets are always re-created, but not until all sources have been
- examined and re-created as necessary. Sources for a target accumu-
- late over dependency lines when this operator is used. The target
- is removed if bbmmaakkee is interrupted.
-
- :::: If no sources are specified, the target is always re-created. Oth-
- erwise, a target is considered out-of-date if any of its sources
- has been modified more recently than the target. Sources for a
- target do not accumulate over dependency lines when this operator
- is used. The target will not be removed if bbmmaakkee is interrupted.
-
- Targets and sources may contain the shell wildcard values `?', `*', `[]',
- and `{}'. The values `?', `*', and `[]' may only be used as part of the
- final component of the target or source, and must be used to describe
- existing files. The value `{}' need not necessarily be used to describe
- existing files. Expansion is in directory order, not alphabetically as
- done in the shell.
-
-SSHHEELLLL CCOOMMMMAANNDDSS
- Each target may have associated with it a series of shell commands, nor-
- mally used to create the target. Each of the commands in this script
- _m_u_s_t be preceded by a tab. While any target may appear on a dependency
- line, only one of these dependencies may be followed by a creation
- script, unless the `::::' operator is used.
-
- If the first characters of the command line are any combination of `@@',
- `++', or `--', the command is treated specially. A `@@' causes the command
- not to be echoed before it is executed. A `++' causes the command to be
- executed even when --nn is given. This is similar to the effect of the
- .MAKE special source, except that the effect can be limited to a single
- line of a script. A `--' causes any non-zero exit status of the command
- line to be ignored.
-
-VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
- Variables in make are much like variables in the shell, and, by tradi-
- tion, consist of all upper-case letters.
-
- VVaarriiaabbllee aassssiiggnnmmeenntt mmooddiiffiieerrss
- The five operators that can be used to assign values to variables are as
- follows:
-
- == Assign the value to the variable. Any previous value is overrid-
- den.
-
- ++== Append the value to the current value of the variable.
-
- ??== Assign the value to the variable if it is not already defined.
-
- ::== Assign with expansion, i.e. expand the value before assigning it
- to the variable. Normally, expansion is not done until the vari-
- able is referenced. _N_O_T_E: References to undefined variables are
- _n_o_t expanded. This can cause problems when variable modifiers
- are used.
-
- !!== Expand the value and pass it to the shell for execution and
- assign the result to the variable. Any newlines in the result
- are replaced with spaces.
-
- Any white-space before the assigned _v_a_l_u_e is removed; if the value is
- being appended, a single space is inserted between the previous contents
- of the variable and the appended value.
-
- Variables are expanded by surrounding the variable name with either curly
- braces (`{}') or parentheses (`()') and preceding it with a dollar sign
- (`$'). If the variable name contains only a single letter, the surround-
- ing braces or parentheses are not required. This shorter form is not
- recommended.
-
- If the variable name contains a dollar, then the name itself is expanded
- first. This allows almost arbitrary variable names, however names con-
- taining dollar, braces, parenthesis, or whitespace are really best
- avoided!
-
- If the result of expanding a variable contains a dollar sign (`$') the
- string is expanded again.
-
- Variable substitution occurs at three distinct times, depending on where
- the variable is being used.
-
- 1. Variables in dependency lines are expanded as the line is read.
-
- 2. Variables in shell commands are expanded when the shell command is
- executed.
-
- 3. ``.for'' loop index variables are expanded on each loop iteration.
- Note that other variables are not expanded inside loops so the fol-
- lowing example code:
-
-
- .for i in 1 2 3
- a+= ${i}
- j= ${i}
- b+= ${j}
- .endfor
-
- all:
- @echo ${a}
- @echo ${b}
-
- will print:
-
- 1 2 3
- 3 3 3
-
- Because while ${a} contains ``1 2 3'' after the loop is executed,
- ${b} contains ``${j} ${j} ${j}'' which expands to ``3 3 3'' since
- after the loop completes ${j} contains ``3''.
-
- VVaarriiaabbllee ccllaasssseess
- The four different classes of variables (in order of increasing prece-
- dence) are:
-
- Environment variables
- Variables defined as part of bbmmaakkee's environment.
-
- Global variables
- Variables defined in the makefile or in included makefiles.
-
- Command line variables
- Variables defined as part of the command line.
-
- Local variables
- Variables that are defined specific to a certain target. The
- seven local variables are as follows:
-
- _._A_L_L_S_R_C The list of all sources for this target; also known as
- `_>'.
-
- _._A_R_C_H_I_V_E The name of the archive file.
-
- _._I_M_P_S_R_C In suffix-transformation rules, the name/path of the
- source from which the target is to be transformed (the
- ``implied'' source); also known as `_<'. It is not
- defined in explicit rules.
-
- _._M_E_M_B_E_R The name of the archive member.
-
- _._O_O_D_A_T_E The list of sources for this target that were deemed
- out-of-date; also known as `_?'.
-
- _._P_R_E_F_I_X The file prefix of the target, containing only the file
- portion, no suffix or preceding directory components;
- also known as `_*'.
-
- _._T_A_R_G_E_T The name of the target; also known as `_@'.
-
- The shorter forms `_@', `_?', `_<', `_>', and `_*' are permitted for
- backward compatibility with historical makefiles and are not rec-
- ommended. The six variables `_@_F', `_@_D', `_<_F', `_<_D', `_*_F', and
- `_*_D' are permitted for compatibility with AT&T System V UNIX
- makefiles and are not recommended.
-
- Four of the local variables may be used in sources on dependency
- lines because they expand to the proper value for each target on
- the line. These variables are `_._T_A_R_G_E_T', `_._P_R_E_F_I_X', `_._A_R_C_H_I_V_E',
- and `_._M_E_M_B_E_R'.
-
- AAddddiittiioonnaall bbuuiilltt--iinn vvaarriiaabblleess
- In addition, bbmmaakkee sets or knows about the following variables:
-
- _$ A single dollar sign `$', i.e. `$$' expands to a single
- dollar sign.
-
- _._A_L_L_T_A_R_G_E_T_S The list of all targets encountered in the Makefile. If
- evaluated during Makefile parsing, lists only those tar-
- gets encountered thus far.
-
- _._C_U_R_D_I_R A path to the directory where bbmmaakkee was executed. Refer
- to the description of `PWD' for more details.
-
- MAKE The name that bbmmaakkee was executed with (_a_r_g_v_[_0_]). For
- compatibility bbmmaakkee also sets _._M_A_K_E with the same value.
- The preferred variable to use is the environment variable
- MAKE because it is more compatible with other versions of
- bbmmaakkee and cannot be confused with the special target with
- the same name.
-
- _._M_A_K_E_._D_E_P_E_N_D_F_I_L_E
- Names the makefile (default `_._d_e_p_e_n_d') from which gener-
- ated dependencies are read.
-
- _._M_A_K_E_._E_X_P_O_R_T_E_D The list of variables exported by bbmmaakkee.
-
- _._M_A_K_E_._J_O_B_S The argument to the --jj option.
-
- _._M_A_K_E_._J_O_B_._P_R_E_F_I_X
- If bbmmaakkee is run with _j then output for each target is
- prefixed with a token `--- target ---' the first part of
- which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X.
- For example:
- .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
- would produce tokens like `---make[1234] target ---' mak-
- ing it easier to track the degree of parallelism being
- achieved.
-
- MAKEFLAGS The environment variable `MAKEFLAGS' may contain anything
- that may be specified on bbmmaakkee's command line. Anything
- specified on bbmmaakkee's command line is appended to the
- `MAKEFLAGS' variable which is then entered into the envi-
- ronment for all programs which bbmmaakkee executes.
-
- _._M_A_K_E_._L_E_V_E_L The recursion depth of bbmmaakkee. The initial instance of
- bbmmaakkee will be 0, and an incremented value is put into the
- environment to be seen by the next generation. This
- allows tests like: .if ${.MAKE.LEVEL} == 0 to protect
- things which should only be evaluated in the initial
- instance of bbmmaakkee.
-
- _._M_A_K_E_._M_A_K_E_F_I_L_E___P_R_E_F_E_R_E_N_C_E
- The ordered list of makefile names (default `_m_a_k_e_f_i_l_e',
- `_M_a_k_e_f_i_l_e') that bbmmaakkee will look for.
-
- _._M_A_K_E_._M_A_K_E_F_I_L_E_S
- The list of makefiles read by bbmmaakkee, which is useful for
- tracking dependencies. Each makefile is recorded only
- once, regardless of the number of times read.
-
- _._M_A_K_E_._M_O_D_E Processed after reading all makefiles. Can affect the
- mode that bbmmaakkee runs in. It can contain a number of key-
- words:
-
- _c_o_m_p_a_t Like --BB, puts bbmmaakkee into "compat" mode.
-
- _m_e_t_a Puts bbmmaakkee into "meta" mode, where meta files
- are created for each target to capture the
- command run, the output generated and if
- filemon(4) is available, the system calls
- which are of interest to bbmmaakkee. The captured
- output can be very useful when diagnosing
- errors.
-
- _c_u_r_d_i_r_O_k_= _b_f Normally bbmmaakkee will not create .meta files
- in `_._C_U_R_D_I_R'. This can be overridden by set-
- ting _b_f to a value which represents True.
-
- _v_e_r_b_o_s_e If in "meta" mode, print a clue about the
- target being built. This is useful if the
- build is otherwise running silently. The
- message printed the value of:
- _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X.
-
- _i_g_n_o_r_e_-_c_m_d Some makefiles have commands which are simply
- not stable. This keyword causes them to be
- ignored for determining whether a target is
- out of date in "meta" mode. See also
- ..NNOOMMEETTAA__CCMMPP.
-
- _._M_A_K_E_._M_E_T_A_._B_A_I_L_I_W_I_C_K
- In "meta" mode, provides a list of prefixes which match
- the directories controlled by bbmmaakkee. If a file that was
- generated outside of _._O_B_J_D_I_R but within said bailiwick is
- missing, the current target is considered out-of-date.
-
- _._M_A_K_E_._M_E_T_A_._C_R_E_A_T_E_D
- In "meta" mode, this variable contains a list of all the
- meta files updated. If not empty, it can be used to
- trigger processing of _._M_A_K_E_._M_E_T_A_._F_I_L_E_S.
-
- _._M_A_K_E_._M_E_T_A_._F_I_L_E_S
- In "meta" mode, this variable contains a list of all the
- meta files used (updated or not). This list can be used
- to process the meta files to extract dependency informa-
- tion.
-
- _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X
- Defines the message printed for each meta file updated in
- "meta verbose" mode. The default value is:
- Building ${.TARGET:H:tA}/${.TARGET:T}
-
- _._M_A_K_E_O_V_E_R_R_I_D_E_S This variable is used to record the names of variables
- assigned to on the command line, so that they may be
- exported as part of `MAKEFLAGS'. This behaviour can be
- disabled by assigning an empty value to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'
- within a makefile. Extra variables can be exported from
- a makefile by appending their names to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'.
- `MAKEFLAGS' is re-exported whenever `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is
- modified.
-
- _._M_A_K_E_._P_I_D The process-id of bbmmaakkee.
-
- _._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
-
- _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R
- When bbmmaakkee stops due to an error, it prints its name and
- the value of `_._C_U_R_D_I_R' as well as the value of any vari-
- ables named in `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R'.
-
- _._n_e_w_l_i_n_e This variable is simply assigned a newline character as
- its value. This allows expansions using the ::@@ modifier
- to put a newline between iterations of the loop rather
- than a space. For example, the printing of
- `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R' could be done as
- ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}.
-
- _._O_B_J_D_I_R A path to the directory where the targets are built. Its
- value is determined by trying to chdir(2) to the follow-
- ing directories in order and using the first match:
-
- 1. ${MAKEOBJDIRPREFIX}${.CURDIR}
-
- (Only if `MAKEOBJDIRPREFIX' is set in the environ-
- ment or on the command line.)
-
- 2. ${MAKEOBJDIR}
-
- (Only if `MAKEOBJDIR' is set in the environment or
- on the command line.)
-
- 3. ${.CURDIR}_/_o_b_j_.${MACHINE}
-
- 4. ${.CURDIR}_/_o_b_j
-
- 5. _/_u_s_r_/_o_b_j_/${.CURDIR}
-
- 6. ${.CURDIR}
-
- Variable expansion is performed on the value before it's
- used, so expressions such as
- ${.CURDIR:S,^/usr/src,/var/obj,}
- may be used. This is especially useful with
- `MAKEOBJDIR'.
-
- `_._O_B_J_D_I_R' may be modified in the makefile as a global
- variable. In all cases, bbmmaakkee will chdir(2) to `_._O_B_J_D_I_R'
- and set `PWD' to that directory before executing any tar-
- gets.
-
- _._P_A_R_S_E_D_I_R A path to the directory of the current `_M_a_k_e_f_i_l_e' being
- parsed.
-
- _._P_A_R_S_E_F_I_L_E The basename of the current `_M_a_k_e_f_i_l_e' being parsed.
- This variable and `_._P_A_R_S_E_D_I_R' are both set only while the
- `_M_a_k_e_f_i_l_e_s' are being parsed.
-
- _._P_A_T_H A variable that represents the list of directories that
- bbmmaakkee will search for files. The search list should be
- updated using the target `_._P_A_T_H' rather than the vari-
- able.
-
- PWD Alternate path to the current directory. bbmmaakkee normally
- sets `_._C_U_R_D_I_R' to the canonical path given by getcwd(3).
- However, if the environment variable `PWD' is set and
- gives a path to the current directory, then bbmmaakkee sets
- `_._C_U_R_D_I_R' to the value of `PWD' instead. This behaviour
- is disabled if `MAKEOBJDIRPREFIX' is set or `MAKEOBJDIR'
- contains a variable transform. `PWD' is set to the value
- of `_._O_B_J_D_I_R' for all programs which bbmmaakkee executes.
-
- .TARGETS The list of targets explicitly specified on the command
- line, if any.
-
- VPATH Colon-separated (``:'') lists of directories that bbmmaakkee
- will search for files. The variable is supported for
- compatibility with old make programs only, use `_._P_A_T_H'
- instead.
-
- VVaarriiaabbllee mmooddiiffiieerrss
- Variable expansion may be modified to select or modify each word of the
- variable (where a ``word'' is white-space delimited sequence of charac-
- ters). The general format of a variable expansion is as follows:
-
- ${variable[:modifier[:...]]}
-
- Each modifier begins with a colon, which may be escaped with a backslash
- (`\').
-
- A set of modifiers can be specified via a variable, as follows:
-
- modifier_variable=modifier[:...]
- ${variable:${modifier_variable}[:...]}
-
- In this case the first modifier in the modifier_variable does not start
- with a colon, since that must appear in the referencing variable. If any
- of the modifiers in the modifier_variable contain a dollar sign (`$'),
- these must be doubled to avoid early expansion.
-
- The supported modifiers are:
-
- ::EE Replaces each word in the variable with its suffix.
-
- ::HH Replaces each word in the variable with everything but the last com-
- ponent.
-
- ::MM_p_a_t_t_e_r_n
- Select only those words that match _p_a_t_t_e_r_n. The standard shell
- wildcard characters (`*', `?', and `[]') may be used. The wildcard
- characters may be escaped with a backslash (`\').
-
- ::NN_p_a_t_t_e_r_n
- This is identical to `::MM', but selects all words which do not match
- _p_a_t_t_e_r_n.
-
- ::OO Order every word in variable alphabetically. To sort words in
- reverse order use the `::OO::[[--11....11]]' combination of modifiers.
-
- ::OOxx Randomize words in variable. The results will be different each
- time you are referring to the modified variable; use the assignment
- with expansion (`::==') to prevent such behaviour. For example,
-
- LIST= uno due tre quattro
- RANDOM_LIST= ${LIST:Ox}
- STATIC_RANDOM_LIST:= ${LIST:Ox}
-
- all:
- @echo "${RANDOM_LIST}"
- @echo "${RANDOM_LIST}"
- @echo "${STATIC_RANDOM_LIST}"
- @echo "${STATIC_RANDOM_LIST}"
- may produce output similar to:
-
- quattro due tre uno
- tre due quattro uno
- due uno quattro tre
- due uno quattro tre
-
- ::QQ Quotes every shell meta-character in the variable, so that it can be
- passed safely through recursive invocations of bbmmaakkee.
-
- ::RR Replaces each word in the variable with everything but its suffix.
-
- ::ggmmttiimmee
- The value is a format string for strftime(3), using the current
- gmtime(3).
-
- ::hhaasshh
- Compute a 32bit hash of the value and encode it as hex digits.
-
- ::llooccaallttiimmee
- The value is a format string for strftime(3), using the current
- localtime(3).
-
- ::ttAA Attempt to convert variable to an absolute path using realpath(3),
- if that fails, the value is unchanged.
-
- ::ttll Converts variable to lower-case letters.
-
- ::ttss_c
- Words in the variable are normally separated by a space on expan-
- sion. This modifier sets the separator to the character _c. If _c is
- omitted, then no separator is used. The common escapes (including
- octal numeric codes), work as expected.
-
- ::ttuu Converts variable to upper-case letters.
-
- ::ttWW Causes the value to be treated as a single word (possibly containing
- embedded white space). See also `::[[**]]'.
-
- ::ttww Causes the value to be treated as a sequence of words delimited by
- white space. See also `::[[@@]]'.
-
- ::SS/_o_l_d___s_t_r_i_n_g/_n_e_w___s_t_r_i_n_g/[11ggWW]
- Modify the first occurrence of _o_l_d___s_t_r_i_n_g in the variable's value,
- replacing it with _n_e_w___s_t_r_i_n_g. If a `g' is appended to the last
- slash of the pattern, all occurrences in each word are replaced. If
- a `1' is appended to the last slash of the pattern, only the first
- word is affected. If a `W' is appended to the last slash of the
- pattern, then the value is treated as a single word (possibly con-
- taining embedded white space). If _o_l_d___s_t_r_i_n_g begins with a caret
- (`^'), _o_l_d___s_t_r_i_n_g is anchored at the beginning of each word. If
- _o_l_d___s_t_r_i_n_g ends with a dollar sign (`$'), it is anchored at the end
- of each word. Inside _n_e_w___s_t_r_i_n_g, an ampersand (`&') is replaced by
- _o_l_d___s_t_r_i_n_g (without any `^' or `$'). Any character may be used as a
- delimiter for the parts of the modifier string. The anchoring,
- ampersand and delimiter characters may be escaped with a backslash
- (`\').
-
- Variable expansion occurs in the normal fashion inside both
- _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g with the single exception that a backslash
- is used to prevent the expansion of a dollar sign (`$'), not a pre-
- ceding dollar sign as is usual.
-
- ::CC/_p_a_t_t_e_r_n/_r_e_p_l_a_c_e_m_e_n_t/[11ggWW]
- The ::CC modifier is just like the ::SS modifier except that the old and
- new strings, instead of being simple strings, are a regular expres-
- sion (see regex(3)) string _p_a_t_t_e_r_n and an ed(1)-style string
- _r_e_p_l_a_c_e_m_e_n_t. Normally, the first occurrence of the pattern _p_a_t_t_e_r_n
- in each word of the value is substituted with _r_e_p_l_a_c_e_m_e_n_t. The `1'
- modifier causes the substitution to apply to at most one word; the
- `g' modifier causes the substitution to apply to as many instances
- of the search pattern _p_a_t_t_e_r_n as occur in the word or words it is
- found in; the `W' modifier causes the value to be treated as a sin-
- gle word (possibly containing embedded white space). Note that `1'
- and `g' are orthogonal; the former specifies whether multiple words
- are potentially affected, the latter whether multiple substitutions
- can potentially occur within each affected word.
-
- ::TT Replaces each word in the variable with its last component.
-
- ::uu Remove adjacent duplicate words (like uniq(1)).
-
- ::??_t_r_u_e___s_t_r_i_n_g::_f_a_l_s_e___s_t_r_i_n_g
- If the variable name (not its value), when parsed as a .if condi-
- tional expression, evaluates to true, return as its value the
- _t_r_u_e___s_t_r_i_n_g, otherwise return the _f_a_l_s_e___s_t_r_i_n_g. Since the variable
- name is used as the expression, :? must be the first modifier after
- the variable name itself - which will, of course, usually contain
- variable expansions. A common error is trying to use expressions
- like
- ${NUMBERS:M42:?match:no}
- which actually tests defined(NUMBERS), to determine is any words
- match "42" you need to use something like:
- ${"${NUMBERS:M42}" != "":?match:no}.
-
- _:_o_l_d___s_t_r_i_n_g_=_n_e_w___s_t_r_i_n_g
- This is the AT&T System V UNIX style variable substitution. It must
- be the last modifier specified. If _o_l_d___s_t_r_i_n_g or _n_e_w___s_t_r_i_n_g do not
- contain the pattern matching character _% then it is assumed that
- they are anchored at the end of each word, so only suffixes or
- entire words may be replaced. Otherwise _% is the substring of
- _o_l_d___s_t_r_i_n_g to be replaced in _n_e_w___s_t_r_i_n_g.
-
- Variable expansion occurs in the normal fashion inside both
- _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g with the single exception that a backslash
- is used to prevent the expansion of a dollar sign (`$'), not a pre-
- ceding dollar sign as is usual.
-
- ::@@_t_e_m_p@@_s_t_r_i_n_g@@
- This is the loop expansion mechanism from the OSF Development Envi-
- ronment (ODE) make. Unlike ..ffoorr loops expansion occurs at the time
- of reference. Assign _t_e_m_p to each word in the variable and evaluate
- _s_t_r_i_n_g. The ODE convention is that _t_e_m_p should start and end with a
- period. For example.
- ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
-
- ::UU_n_e_w_v_a_l
- If the variable is undefined _n_e_w_v_a_l is the value. If the variable
- is defined, the existing value is returned. This is another ODE
- make feature. It is handy for setting per-target CFLAGS for
- instance:
- ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}}
- If a value is only required if the variable is undefined, use:
- ${VAR:D:Unewval}
-
- ::DD_n_e_w_v_a_l
- If the variable is defined _n_e_w_v_a_l is the value.
-
- ::LL The name of the variable is the value.
-
- ::PP The path of the node which has the same name as the variable is the
- value. If no such node exists or its path is null, then the name of
- the variable is used.
-
- ::!!_c_m_d!!
- The output of running _c_m_d is the value.
-
- ::sshh If the variable is non-empty it is run as a command and the output
- becomes the new value.
-
- ::::==_s_t_r
- The variable is assigned the value _s_t_r after substitution. This
- modifier and its variations are useful in obscure situations such as
- wanting to set a variable when shell commands are being parsed.
- These assignment modifiers always expand to nothing, so if appearing
- in a rule line by themselves should be preceded with something to
- keep bbmmaakkee happy.
-
- The `::::' helps avoid false matches with the AT&T System V UNIX style
- ::== modifier and since substitution always occurs the ::::== form is
- vaguely appropriate.
-
- ::::??==_s_t_r
- As for ::::== but only if the variable does not already have a value.
-
- ::::++==_s_t_r
- Append _s_t_r to the variable.
-
- ::::!!==_c_m_d
- Assign the output of _c_m_d to the variable.
-
- ::[[_r_a_n_g_e]]
- Selects one or more words from the value, or performs other opera-
- tions related to the way in which the value is divided into words.
-
- Ordinarily, a value is treated as a sequence of words delimited by
- white space. Some modifiers suppress this behaviour, causing a
- value to be treated as a single word (possibly containing embedded
- white space). An empty value, or a value that consists entirely of
- white-space, is treated as a single word. For the purposes of the
- `::[[]]' modifier, the words are indexed both forwards using positive
- integers (where index 1 represents the first word), and backwards
- using negative integers (where index -1 represents the last word).
-
- The _r_a_n_g_e is subjected to variable expansion, and the expanded
- result is then interpreted as follows:
-
- _i_n_d_e_x Selects a single word from the value.
-
- _s_t_a_r_t...._e_n_d
- Selects all words from _s_t_a_r_t to _e_n_d, inclusive. For example,
- `::[[22....--11]]' selects all words from the second word to the last
- word. If _s_t_a_r_t is greater than _e_n_d, then the words are out-
- put in reverse order. For example, `::[[--11....11]]' selects all
- the words from last to first.
-
- ** Causes subsequent modifiers to treat the value as a single
- word (possibly containing embedded white space). Analogous
- to the effect of "$*" in Bourne shell.
-
- 0 Means the same as `::[[**]]'.
-
- @@ Causes subsequent modifiers to treat the value as a sequence
- of words delimited by white space. Analogous to the effect
- of "$@" in Bourne shell.
-
- ## Returns the number of words in the value.
-
-IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOONNAALLSS AANNDD FFOORR LLOOOOPPSS
- Makefile inclusion, conditional structures and for loops reminiscent of
- the C programming language are provided in bbmmaakkee. All such structures
- are identified by a line beginning with a single dot (`.') character.
- Files are included with either ..iinncclluuddee <_f_i_l_e> or ..iinncclluuddee "_f_i_l_e". Vari-
- ables between the angle brackets or double quotes are expanded to form
- the file name. If angle brackets are used, the included makefile is
- expected to be in the system makefile directory. If double quotes are
- used, the including makefile's directory and any directories specified
- using the --II option are searched before the system makefile directory.
- For compatibility with other versions of bbmmaakkee `include file ...' is also
- accepted. If the include statement is written as ..--iinncclluuddee or as
- ..ssiinncclluuddee then errors locating and/or opening include files are ignored.
-
- Conditional expressions are also preceded by a single dot as the first
- character of a line. The possible conditionals are as follows:
-
- ..eerrrroorr _m_e_s_s_a_g_e
- The message is printed along with the name of the makefile and
- line number, then bbmmaakkee will exit.
-
- ..eexxppoorrtt _v_a_r_i_a_b_l_e _._._.
- Export the specified global variable. If no variable list is
- provided, all globals are exported except for internal variables
- (those that start with `.'). This is not affected by the --XX
- flag, so should be used with caution.
-
- Appending a variable name to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to
- exporting a variable.
-
- ..eexxppoorrtt--eennvv _v_a_r_i_a_b_l_e _._._.
- The same as `.export', except that the variable is not appended
- to _._M_A_K_E_._E_X_P_O_R_T_E_D. This allows exporting a value to the environ-
- ment which is different from that used by bbmmaakkee internally.
-
- ..iinnffoo _m_e_s_s_a_g_e
- The message is printed along with the name of the makefile and
- line number.
-
- ..uunnddeeff _v_a_r_i_a_b_l_e
- Un-define the specified global variable. Only global variables
- may be un-defined.
-
- ..uunneexxppoorrtt _v_a_r_i_a_b_l_e _._._.
- The opposite of `.export'. The specified global _v_a_r_i_a_b_l_e will be
- removed from _._M_A_K_E_._E_X_P_O_R_T_E_D. If no variable list is provided,
- all globals are unexported, and _._M_A_K_E_._E_X_P_O_R_T_E_D deleted.
-
- ..uunneexxppoorrtt--eennvv
- Unexport all globals previously exported and clear the environ-
- ment inherited from the parent. This operation will cause a mem-
- ory leak of the original environment, so should be used spar-
- ingly. Testing for _._M_A_K_E_._L_E_V_E_L being 0, would make sense. Also
- note that any variables which originated in the parent environ-
- ment should be explicitly preserved if desired. For example:
-
- .if ${.MAKE.LEVEL} == 0
- PATH := ${PATH}
- .unexport-env
- .export PATH
- .endif
-
- Would result in an environment containing only `PATH', which is
- the minimal useful environment. Actually `.MAKE.LEVEL' will also
- be pushed into the new environment.
-
- ..wwaarrnniinngg _m_e_s_s_a_g_e
- The message prefixed by `_w_a_r_n_i_n_g_:' is printed along with the name
- of the makefile and line number.
-
- ..iiff [!]_e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.]
- Test the value of an expression.
-
- ..iiffddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
- Test the value of a variable.
-
- ..iiffnnddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
- Test the value of a variable.
-
- ..iiffmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
- Test the target being built.
-
- ..iiffnnmmaakkee [!] _t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
- Test the target being built.
-
- ..eellssee Reverse the sense of the last conditional.
-
- ..eelliiff [!] _e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n _._._.]
- A combination of `..eellssee' followed by `..iiff'.
-
- ..eelliiffddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
- A combination of `..eellssee' followed by `..iiffddeeff'.
-
- ..eelliiffnnddeeff [!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e _._._.]
- A combination of `..eellssee' followed by `..iiffnnddeeff'.
-
- ..eelliiffmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
- A combination of `..eellssee' followed by `..iiffmmaakkee'.
-
- ..eelliiffnnmmaakkee [!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t _._._.]
- A combination of `..eellssee' followed by `..iiffnnmmaakkee'.
-
- ..eennddiiff End the body of the conditional.
-
- The _o_p_e_r_a_t_o_r may be any one of the following:
-
- |||| Logical OR.
-
- &&&& Logical AND; of higher precedence than ``||''.
-
- As in C, bbmmaakkee will only evaluate a conditional as far as is necessary to
- determine its value. Parentheses may be used to change the order of
- evaluation. The boolean operator `!!' may be used to logically negate an
- entire conditional. It is of higher precedence than `&&&&'.
-
- The value of _e_x_p_r_e_s_s_i_o_n may be any of the following:
-
- ddeeffiinneedd Takes a variable name as an argument and evaluates to true if
- the variable has been defined.
-
- mmaakkee Takes a target name as an argument and evaluates to true if the
- target was specified as part of bbmmaakkee's command line or was
- declared the default target (either implicitly or explicitly,
- see _._M_A_I_N) before the line containing the conditional.
-
- eemmppttyy Takes a variable, with possible modifiers, and evaluates to true
- if the expansion of the variable would result in an empty
- string.
-
- eexxiissttss Takes a file name as an argument and evaluates to true if the
- file exists. The file is searched for on the system search path
- (see _._P_A_T_H).
-
- ttaarrggeett Takes a target name as an argument and evaluates to true if the
- target has been defined.
-
- ccoommmmaannddss
- Takes a target name as an argument and evaluates to true if the
- target has been defined and has commands associated with it.
-
- _E_x_p_r_e_s_s_i_o_n may also be an arithmetic or string comparison. Variable
- expansion is performed on both sides of the comparison, after which the
- integral values are compared. A value is interpreted as hexadecimal if
- it is preceded by 0x, otherwise it is decimal; octal numbers are not sup-
- ported. The standard C relational operators are all supported. If after
- variable expansion, either the left or right hand side of a `====' or `!!=='
- operator is not an integral value, then string comparison is performed
- between the expanded variables. If no relational operator is given, it
- is assumed that the expanded variable is being compared against 0 or an
- empty string in the case of a string comparison.
-
- When bbmmaakkee is evaluating one of these conditional expressions, and it
- encounters a (white-space separated) word it doesn't recognize, either
- the ``make'' or ``defined'' expression is applied to it, depending on the
- form of the conditional. If the form is `..iiffddeeff', `..iiffnnddeeff', or `..iiff'
- the ``defined'' expression is applied. Similarly, if the form is
- `..iiffmmaakkee' or `..iiffnnmmaakkee, tthhee' ``make'' expression is applied.
-
- If the conditional evaluates to true the parsing of the makefile contin-
- ues as before. If it evaluates to false, the following lines are
- skipped. In both cases this continues until a `..eellssee' or `..eennddiiff' is
- found.
-
- For loops are typically used to apply a set of rules to a list of files.
- The syntax of a for loop is:
-
- ..ffoorr _v_a_r_i_a_b_l_e [_v_a_r_i_a_b_l_e _._._.] iinn _e_x_p_r_e_s_s_i_o_n
- <make-rules>
- ..eennddffoorr
-
- After the for eexxpprreessssiioonn is evaluated, it is split into words. On each
- iteration of the loop, one word is taken and assigned to each vvaarriiaabbllee,
- in order, and these vvaarriiaabblleess are substituted into the mmaakkee--rruulleess inside
- the body of the for loop. The number of words must come out even; that
- is, if there are three iteration variables, the number of words provided
- must be a multiple of three.
-
-CCOOMMMMEENNTTSS
- Comments begin with a hash (`#') character, anywhere but in a shell com-
- mand line, and continue to the end of an unescaped new line.
-
-SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS))
- ..EEXXEECC Target is never out of date, but always execute commands any-
- way.
-
- ..IIGGNNOORREE Ignore any errors from the commands associated with this tar-
- get, exactly as if they all were preceded by a dash (`-').
-
- ..MMAADDEE Mark all sources of this target as being up-to-date.
-
- ..MMAAKKEE Execute the commands associated with this target even if the --nn
- or --tt options were specified. Normally used to mark recursive
- bbmmaakkee's.
-
- ..MMEETTAA Create a meta file for the target, even if it is flagged as
- ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL. Usage in conjunction with ..MMAAKKEE is
- the most likely case.
-
- ..NNOOMMEETTAA Do not create a meta file for the target. Meta files are also
- not created for ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL targets.
-
- ..NNOOMMEETTAA__CCMMPP
- Ignore differences in commands when deciding if target is out
- of date. This is useful if the command contains a value which
- always changes. If the number of commands change, though, the
- target will still be out of date.
-
- ..NNOOPPAATTHH Do not search for the target in the directories specified by
- ..PPAATTHH.
-
- ..NNOOTTMMAAIINN Normally bbmmaakkee selects the first target it encounters as the
- default target to be built if no target was specified. This
- source prevents this target from being selected.
-
- ..OOPPTTIIOONNAALL
- If a target is marked with this attribute and bbmmaakkee can't fig-
- ure out how to create it, it will ignore this fact and assume
- the file isn't needed or already exists.
-
- ..PPHHOONNYY The target does not correspond to an actual file; it is always
- considered to be out of date, and will not be created with the
- --tt option. Suffix-transformation rules are not applied to
- ..PPHHOONNYY targets.
-
- ..PPRREECCIIOOUUSS
- When bbmmaakkee is interrupted, it normally removes any partially
- made targets. This source prevents the target from being
- removed.
-
- ..RREECCUURRSSIIVVEE
- Synonym for ..MMAAKKEE.
-
- ..SSIILLEENNTT Do not echo any of the commands associated with this target,
- exactly as if they all were preceded by an at sign (`@').
-
- ..UUSSEE Turn the target into bbmmaakkee's version of a macro. When the tar-
- get is used as a source for another target, the other target
- acquires the commands, sources, and attributes (except for
- ..UUSSEE) of the source. If the target already has commands, the
- ..UUSSEE target's commands are appended to them.
-
- ..UUSSEEBBEEFFOORREE
- Exactly like ..UUSSEE, but prepend the ..UUSSEEBBEEFFOORREE target commands
- to the target.
-
- ..WWAAIITT If ..WWAAIITT appears in a dependency line, the sources that precede
- it are made before the sources that succeed it in the line.
- Since the dependents of files are not made until the file
- itself could be made, this also stops the dependents being
- built unless they are needed for another branch of the depen-
- dency tree. So given:
-
- x: a .WAIT b
- echo x
- a:
- echo a
- b: b1
- echo b
- b1:
- echo b1
-
- the output is always `a', `b1', `b', `x'.
- The ordering imposed by ..WWAAIITT is only relevant for parallel
- makes.
-
-SSPPEECCIIAALL TTAARRGGEETTSS
- Special targets may not be included with other targets, i.e. they must be
- the only target specified.
-
- ..BBEEGGIINN Any command lines attached to this target are executed before
- anything else is done.
-
- ..DDEEFFAAUULLTT
- This is sort of a ..UUSSEE rule for any target (that was used only
- as a source) that bbmmaakkee can't figure out any other way to cre-
- ate. Only the shell script is used. The ..IIMMPPSSRRCC variable of a
- target that inherits ..DDEEFFAAUULLTT's commands is set to the target's
- own name.
-
- ..EENNDD Any command lines attached to this target are executed after
- everything else is done.
-
- ..EERRRROORR Any command lines attached to this target are executed when
- another target fails. The ..EERRRROORR__TTAARRGGEETT variable is set to the
- target that failed. See also MMAAKKEE__PPRRIINNTT__VVAARR__OONN__EERRRROORR.
-
- ..IIGGNNOORREE Mark each of the sources with the ..IIGGNNOORREE attribute. If no
- sources are specified, this is the equivalent of specifying the
- --ii option.
-
- ..IINNTTEERRRRUUPPTT
- If bbmmaakkee is interrupted, the commands for this target will be
- executed.
-
- ..MMAAIINN If no target is specified when bbmmaakkee is invoked, this target
- will be built.
-
- ..MMAAKKEEFFLLAAGGSS
- This target provides a way to specify flags for bbmmaakkee when the
- makefile is used. The flags are as if typed to the shell,
- though the --ff option will have no effect.
-
- ..NNOOPPAATTHH Apply the ..NNOOPPAATTHH attribute to any specified sources.
-
- ..NNOOTTPPAARRAALLLLEELL
- Disable parallel mode.
-
- ..NNOO__PPAARRAALLLLEELL
- Synonym for ..NNOOTTPPAARRAALLLLEELL, for compatibility with other pmake
- variants.
-
- ..OORRDDEERR The named targets are made in sequence. This ordering does not
- add targets to the list of targets to be made. Since the depen-
- dents of a target do not get built until the target itself could
- be built, unless `a' is built by another part of the dependency
- graph, the following is a dependency loop:
-
- .ORDER: b a
- b: a
-
- The ordering imposed by ..OORRDDEERR is only relevant for parallel
- makes.
-
- ..PPAATTHH The sources are directories which are to be searched for files
- not found in the current directory. If no sources are speci-
- fied, any previously specified directories are deleted. If the
- source is the special ..DDOOTTLLAASSTT target, then the current working
- directory is searched last.
-
- ..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources.
-
- ..PPRREECCIIOOUUSS
- Apply the ..PPRREECCIIOOUUSS attribute to any specified sources. If no
- sources are specified, the ..PPRREECCIIOOUUSS attribute is applied to
- every target in the file.
-
- ..SSHHEELLLL Sets the shell that bbmmaakkee will use to execute commands. The
- sources are a set of _f_i_e_l_d_=_v_a_l_u_e pairs.
-
- _n_a_m_e This is the minimal specification, used to select
- one of the builtin shell specs; _s_h, _k_s_h, and _c_s_h.
-
- _p_a_t_h Specifies the path to the shell.
-
- _h_a_s_E_r_r_C_t_l Indicates whether the shell supports exit on error.
-
- _c_h_e_c_k The command to turn on error checking.
-
- _i_g_n_o_r_e The command to disable error checking.
-
- _e_c_h_o The command to turn on echoing of commands executed.
-
- _q_u_i_e_t The command to turn off echoing of commands exe-
- cuted.
-
- _f_i_l_t_e_r The output to filter after issuing the _q_u_i_e_t com-
- mand. It is typically identical to _q_u_i_e_t.
-
- _e_r_r_F_l_a_g The flag to pass the shell to enable error checking.
-
- _e_c_h_o_F_l_a_g The flag to pass the shell to enable command echo-
- ing.
-
- _n_e_w_l_i_n_e The string literal to pass the shell that results in
- a single newline character when used outside of any
- quoting characters.
- Example:
-
- .SHELL: name=ksh path=/bin/ksh hasErrCtl=true \
- check="set -e" ignore="set +e" \
- echo="set -v" quiet="set +v" filter="set +v" \
- echoFlag=v errFlag=e newline="'\n'"
-
- ..SSIILLEENNTT Apply the ..SSIILLEENNTT attribute to any specified sources. If no
- sources are specified, the ..SSIILLEENNTT attribute is applied to every
- command in the file.
+ The way that parallel makes are scheduled changed in NetBSD 4.0 so that
+ .ORDER and .WAIT apply recursively to the dependent nodes. The algo-
+ rithms used may change again in the future.
- ..SSUUFFFFIIXXEESS
- Each source specifies a suffix to bbmmaakkee. If no sources are
- specified, any previously specified suffixes are deleted. It
- allows the creation of suffix-transformation rules.
+ OOtthheerr mmaakkee ddiiaalleeccttss
+ Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not sup-
+ port most of the features of bbmmaakkee as described in this manual. Most
+ notably:
- Example:
+ ++oo The ..WWAAIITT and ..OORRDDEERR declarations and most functionality per-
+ taining to parallelization. (GNU make supports parallelization
+ but lacks these features needed to control it effectively.)
- .SUFFIXES: .o
- .c.o:
- cc -o ${.TARGET} -c ${.IMPSRC}
+ ++oo Directives, including for loops and conditionals and most of
+ the forms of include files. (GNU make has its own incompatible
+ and less powerful syntax for conditionals.)
-EENNVVIIRROONNMMEENNTT
- bbmmaakkee uses the following environment variables, if they exist: MACHINE,
- MACHINE_ARCH, MAKE, MAKEFLAGS, MAKEOBJDIR, MAKEOBJDIRPREFIX, MAKESYSPATH,
- PWD, and TMPDIR.
-
- MAKEOBJDIRPREFIX and MAKEOBJDIR may only be set in the environment or on
- the command line to bbmmaakkee and not as makefile variables; see the descrip-
- tion of `_._O_B_J_D_I_R' for more details.
+ ++oo All built-in variables that begin with a dot.
-FFIILLEESS
- .depend list of dependencies
- Makefile list of dependencies
- makefile list of dependencies
- sys.mk system makefile
- /usr/share/mk system makefile directory
+ ++oo Most of the special sources and targets that begin with a dot,
+ with the notable exception of ..PPHHOONNYY, ..PPRREECCIIOOUUSS, and ..SSUUFFFFIIXXEESS.
-CCOOMMPPAATTIIBBIILLIITTYY
- The basic make syntax is compatible between different versions of make,
- however the special variables, variable modifiers and conditionals are
- not.
+ ++oo Variable modifiers, except for the
+ :old=new
+ string substitution, which does not portably support globbing
+ with `%' and historically only works on declared suffixes.
- The way that parallel makes are scheduled changed in NetBSD 4.0 so that
- .ORDER and .WAIT apply recursively to the dependant nodes. The algo-
- rithms used may change again in the future.
+ ++oo The $$>> variable even in its short form; most makes support this
+ functionality but its name varies.
- The way that .for loop variables are substituted changed after NetBSD 5.0
- so that they still appear to be variable expansions. In particular this
- stops them being treated as syntax, and removes some obscure problems
- using them in .if statements.
+ Some features are somewhat more portable, such as assignment with ++==, ??==,
+ and !!==. The ..PPAATTHH functionality is based on an older feature VVPPAATTHH found
+ in GNU make and many versions of SVR4 make; however, historically its
+ behavior is too ill-defined (and too buggy) to rely upon.
- Unlike other bbmmaakkee programs, this implementation by default executes all
- commands for a given target using a single shell invocation. This is
- done for both efficiency and to simplify error handling in remote command
- invocations. Typically this is transparent to the user, unless the tar-
- get commands change the current working directory using ``cd'' or
- ``chdir''. To be compatible with Makefiles that do this, one can use --BB
- to disable this behavior.
+ The $$@@ and $$<< variables are more or less universally portable, as is the
+ $$((MMAAKKEE)) variable. Basic use of suffix rules (for files only in the cur-
+ rent directory, not trying to chain transformations together, etc.) is
+ also reasonably portable.
SSEEEE AALLSSOO
mkdep(1)
HHIISSTTOORRYY
- bbmmaakkee is derived from NetBSD's make(1). It uses autoconf to facilitate
+ bbmmaakkee is derived from NetBSD make(1). It uses autoconf to facilitate
portability to other platforms.
-NetBSD 5.1 May 29, 2011 NetBSD 5.1
+ A make command appeared in Version 7 AT&T UNIX. This make implementation
+ is based on Adam De Boor's pmake program which was written for Sprite at
+ Berkeley. It was designed to be a parallel distributed make running jobs
+ on different machines using a daemon called ``customs''.
+
+ Historically the target/dependency ``FRC'' has been used to FoRCe
+ rebuilding (since the target/dependency does not exist... unless someone
+ creates an ``FRC'' file).
+
+BBUUGGSS
+ The make syntax is difficult to parse without actually acting of the
+ data. For instance finding the end of a variable use should involve
+ scanning each the modifiers using the correct terminator for each field.
+ In many places make just counts {} and () in order to find the end of a
+ variable expansion.
+
+ There is no way of escaping a space character in a filename.
+
+NetBSD 5.1 April 9, 2015 NetBSD 5.1
diff --git a/devel/bmake/files/boot-strap b/devel/bmake/files/boot-strap
index 9ecb73fd373..8bfce51e746 100755
--- a/devel/bmake/files/boot-strap
+++ b/devel/bmake/files/boot-strap
@@ -3,23 +3,52 @@
# boot-strap
#
# SYNOPSIS:
-# boot-strap [--"configure_arg" ... ][-s "srcdir"][-m "mksrc"]\\
-# ["prefix" ["bmakesrc" ["mksrc"]]]
+# boot-strap ["options"]
+# boot-strap --prefix=/opt --install
+# boot-strap --prefix=$HOME --install-host-target -DWITH_PROG_VERSION
+# boot-strap ["options"] op=build
+# boot-strap ["options"] op=install
#
# DESCRIPTION:
# This script is used to configure/build bmake it builds for
-# each OS in a subdir to keep the src clean.
-# On successful completion it echos commands to put the new
-# bmake binary into the /configs tree (if it exists)
-# (http://www.crufty.net/FreeWare/configs.html), $prefix/bin
-# and a suitable ~/*bin directory.
+# each host-target in a different subdir to keep the src clean.
+# There is no requirement for an existing make(1).
#
+# On successful completion if no '--install' flag is given,
+# it echos a command to do installation.
+#
+# The variable "op" defaults to 'all', and is affected by
+# '--install' flag as above.
+# Other values include:
+#
+# configure
+# Just run 'configure'
+#
+# build
+# If 'configure' has not been done, do it, then
+# run the build script, and finally 'test'.
+#
+# install
+# If 'build' has not been done, do it, 'test' then
+# install.
+#
+# clean
+# attempt to clean up
+#
+# test
+# run the unit-tests. Done automatically after 'build'
+# and before 'install'.
+#
+# The above are leveraged by a trivial makefile for the benefit
+# of those that have './configure; make; make install' baked
+# into them.
+#
# Options:
#
# -c "rc"
# Pick up settings from "rc".
# We look for '.bmake-boot-strap.rc' before processing
-# options.
+# options (unless SKIP_RC is set in environment).
#
# --share "share_dir"
# Where to put man pages and mk files.
@@ -28,9 +57,28 @@
#
# --mksrc "mksrc"
# Indicate where the mk files can be found.
-# Default is ./mk or ../mk, set to 'none' to force
-# building without "mksrc" but in that case a sys.mk
-# needs to exist in the default syspath ($share_dir/mk)
+# Default is $Mydir/mk
+#
+# --install
+# If build and test work, run bmake install.
+# BINDIR=$prefix/bin
+# SHAREDIR=$prefix/share
+#
+# --install-host-target
+# As for '--install' but BINDIR=$prefix/$HOST_TARGET/bin
+# This is useful when $prefix/ is shared by multiple
+# machines.
+#
+# Flags relevant when installing:
+#
+# -DWITHOUT_INSTALL_MK
+# Skip installing mk files.
+# By default they will be installed to $prefix/share/mk
+#
+# -DWITH_PROG_VERSION
+# Install 'bmake' as 'bmake-$MAKE_VERSION'
+# A symlink will be made as 'bmake' unless
+# -DWITHOUT_PROG_LINK is set.
#
# Possibly useful configure_args:
#
@@ -63,7 +111,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: boot-strap,v 1.1.1.10 2011/06/18 22:17:47 bsiegert Exp $
+# $Id: boot-strap,v 1.1.1.11 2015/05/19 21:36:43 joerg Exp $
#
# @(#) Copyright (c) 2001 Simon J. Gerraty
#
@@ -85,11 +133,10 @@ case "$Mydir" in
*) Mydir=`cd "$Mydir" && 'pwd'`;;
esac
-
Usage() {
[ "$1" ] && echo "ERROR: $@" >&2
echo "Usage:" >&2
- echo "$0 [--<configure_arg> ...][-s <srcdir>][-m <mksrc>][<prefix> [[<srcdir>] [<mksrc>]]]" >&2
+ echo "$0 [--<configure_arg> ...][<prefix>][--install]" >&2
exit 1
}
@@ -110,28 +157,58 @@ source_rc() {
done
}
+cmd_args="$@"
+
+# clear some things from the environment that we care about
+unset MAKEOBJDIR MAKEOBJDIRPREFIX
+
+# --install[-host-target] will set this
+INSTALL_PREFIX=
+# other things we pass to install step
+INSTALL_ARGS=
CONFIGURE_ARGS=
MAKESYSPATH=
# pick a useful default prefix (for me at least ;-)
for prefix in /opt/$HOST_TARGET "$HOME/$HOST_TARGET" /usr/pkg /usr/local ""
do
- [ -d "${prefix:-.}" ] && break
+ [ -d "${prefix:-.}" ] || continue
+ case "$prefix" in
+ */$HOST_TARGET)
+ p=`dirname $prefix`
+ if [ -d $p/share ]; then
+ INSTALL_BIN=$HOST_TARGET/bin
+ prefix=$p
+ fi
+ ;;
+ esac
+ echo "NOTE: default prefix=$prefix ${INSTALL_BIN:+INSTALL_BIN=$INSTALL_BIN}"
+ break
done
-srcdir=
-mksrc=
+srcdir=$Mydir
+mksrc=$Mydir/mk
objdir=
quiet=:
-source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
+${SKIP_RC:+:} source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
get_optarg() {
expr "x$1" : "x[^=]*=\\(.*\\)"
}
+here=`'pwd'`
+if [ $here = $Mydir ]; then
+ # avoid pollution
+ OBJROOT=../
+fi
+
+op=all
+BMAKE=
+
while :
do
case "$1" in
--) shift; break;;
+ --help) sed -n -e "1d;/RCSid/,\$d" -e '/^#\.[a-z]/d' -e '/^#/s,^# *,,p' $0; exit 0;;
--prefix) prefix="$2"; shift;;
--prefix=*) prefix=`get_optarg "$1"`;;
--src=*) srcdir=`get_optarg "$1"`;;
@@ -139,18 +216,23 @@ do
--share=*) share_dir=`get_optarg "$1"`;;
--share) share_dir="$2"; shift;;
--with-default-sys-path=*)
- CONFIGURE_ARGS="$1"
- MAKESYSPATH=`get_optarg "$1"`;;
+ CONFIGURE_ARGS="$1";;
--with-default-sys-path)
- CONFIGURE_ARGS="$1 $2"
- MAKESYSPATH="$2"; shift;;
+ CONFIGURE_ARGS="$1 $2";;
+ --install) INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix};;
+ --install-host-target)
+ INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
+ INSTALL_BIN=$HOST_TARGET/bin;;
+ --install-destdir=*) INSTALL_DESTDIR=`get_optarg "$1"`;;
+ --install-prefix=*) INSTALL_PREFIX=`get_optarg "$1"`;;
+ -DWITH*) INSTALL_ARGS="$INSTALL_ARGS $1";;
-s|--src) srcdir="$2"; shift;;
-m|--mksrc) mksrc="$2"; shift;;
-o|--objdir) objdir="$2"; shift;;
-q) quiet=;;
-c) source_rc "$2"; shift;;
--*) CONFIGURE_ARGS="$CONFIGURE_ARGS $1";;
- *=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]\\)=.*"`;;
+ *=*) eval "$1"; export `expr "x$1" : "x\\(.[^=]*\\)=.*"`;;
*) break;;
esac
shift
@@ -166,6 +248,8 @@ AddConfigure() {
GetDir() {
match="$1"
shift
+ fmatch="$1"
+ shift
for dir in $*
do
[ -d "$dir" ] || continue
@@ -173,6 +257,10 @@ GetDir() {
*$match*) ;;
*) continue;;
esac
+ case "$fmatch" in
+ .) ;;
+ *) [ -s $dir/$fmatch ] || continue;;
+ esac
case "$dir/" in
*./*) cd "$dir" && 'pwd';;
/*) echo $dir;;
@@ -237,23 +325,25 @@ add_path () {
}
-srcdir=`GetDir /bmake "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
+srcdir=`GetDir /bmake make-bootstrap.sh.in "$srcdir" "$2" "$Mydir" ./bmake* "$Mydir"/../bmake*`
[ -d "${srcdir:-/dev/null}" ] || Usage
case "$mksrc" in
-none|-) # we don't want it
- mksrc=
+none|-) # we ignore this now
+ mksrc=$Mydir/mk
;;
.../*) # find here or above
- mksrc=`FindHereOrAbove -C "$Mydir" -d "$mksrc"`
+ mksrc=`FindHereOrAbove -C "$Mydir" -s "$mksrc/sys.mk"`
+ # that found a file
+ mksrc=`dirname $mksrc`
;;
*) # guess we want mksrc...
- mksrc=`GetDir /mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
+ mksrc=`GetDir /mk sys.mk "$mksrc" "$3" ./mk* "$srcdir"/mk* "$srcdir"/../mk*`
[ -d "${mksrc:-/dev/null}" ] || Usage "Use '-m none' to build without mksrc"
;;
esac
# Ok, get to work...
-objdir="${objdir:-$OS}"
+objdir="${objdir:-$OBJROOT$HOST_TARGET}"
[ -d "$objdir" ] || mkdir -p "$objdir"
[ -d "$objdir" ] || mkdir "$objdir"
cd "$objdir" || exit 1
@@ -293,88 +383,80 @@ if [ "$mksrc" ]; then
export CFLAGS_MF CFLAGS_MD
fi
-$srcdir/configure $CONFIGURE_ARGS || exit 1
-chmod 755 make-bootstrap.sh || exit 1
-./make-bootstrap.sh || exit 1
-if [ -z "$MAKESYSPATH" ]; then
- add_path "${share_dir:-...}/mk" MAKESYSPATH
- case "$HOST_TARGET" in
- netbsd*) add_path /usr/share/mk MAKESYSPATH;;
- esac
-fi
-if [ -s "${mksrc:-/dev/null}/install-mk" ]; then
- sh "${mksrc}/install-mk" "$objdir/mk"
- case "$MAKESYSPATH" in
- .../mk*) ;;
- *) MAKESYSPATH=".../mk:${MAKESYSPATH}";;
- esac
-fi
+# this makes it easy to run the bmake we just built
+# the :tA dance is needed because 'pwd' and even /bin/pwd
+# may not give the same result as realpath().
+Bmake() {
+ (
+ cd $Mydir &&
+ MAKESYSPATH=$mksrc SRCTOP=$Mydir OBJTOP=$objdir \
+ MAKEOBJDIR='${.CURDIR:S,${SRCTOP:tA},${OBJTOP:tA},}' \
+ ${BMAKE:-$objdir/bmake} -f $Mydir/Makefile "$@"
+ )
+}
+
# make sure test below uses the same diff that configure did
TOOL_DIFF=`type diff | sed 's,[()],,g;s,^[^/][^/]*,,;q'`
-export MAKESYSPATH TOOL_DIFF
-if [ "$mksrc" ]; then
- $objdir/bmake test || exit 1
-else
- # assume nothing
- $objdir/bmake -r -m / test || exit 1
-fi
-# If -q given, we don't want all the install instructions
-$quiet exit 0
-
-make_version=`./bmake -r -m / -f ./Makefile -V MAKE_VERSION | ( read one two; echo $one )`
-bmake_version=bmake-$make_version
-
-if [ -s /usr/share/tmac/andoc.tmac ]; then
- # this should be ok
- man_subdir=man1
- man_src=$srcdir/bmake.1
-else
- # guess not
- man_subdir=cat1
- man_src=$srcdir/bmake.cat1
-fi
+export TOOL_DIFF
-install_prefix() {
- (
- bin_dir=
- share_dir=
- man_dir=
- mk_dir=
- while :
- do
- case "$1" in
- *=*) eval "$1"; shift;;
- *) break;;
- esac
- done
- bin_dir=${bin_dir:-$1/bin}
- share_dir=${share_dir:-`ShareDir "$1"`}
- man_dir=${man_dir:-$share_dir/man}
- mk_dir=${mk_dir:-$share_dir/mk}
- echo
- echo Commands to install into $1/
- echo
- echo mkdir -p $bin_dir
- echo cp $objdir/bmake $bin_dir/$bmake_version
- echo rm -f $bin_dir/bmake
- echo ln -s $bmake_version $bin_dir/bmake
- echo mkdir -p $man_dir/$man_subdir
- echo cp $man_src $man_dir/$man_subdir/bmake.1
- if [ "$mksrc" ]; then
- ev=`env | grep '_MK='`
- echo $ev sh $mksrc/install-mk $mk_dir
+op_configure() {
+ $srcdir/configure $CONFIGURE_ARGS || exit 1
+}
+
+op_build() {
+ [ -s make-bootstrap.sh ] || op_configure
+ chmod 755 make-bootstrap.sh || exit 1
+ ./make-bootstrap.sh || exit 1
+ case "$op" in
+ build) op_test;;
+ esac
+}
+
+op_test() {
+ [ -x bmake ] || op_build
+ Bmake test || exit 1
+}
+
+op_clean() {
+ if [ -x bmake ]; then
+ ln bmake bmake$$
+ BMAKE=$objdir/bmake$$ Bmake clean
+ rm -f bmake$$
+ elif [ $objdir != $srcdir ]; then
+ rm -rf *
fi
- )
}
-case "$prefix/" in
-"$HOME"/*) ;;
-*) CONFIGS=${CONFIGS:-/configs}
- [ -d $CONFIGS ] &&
- install_prefix mksrc= "$CONFIGS/$OS/$OSMAJOR.X/$MACHINE_ARCH$prefix"
- # I like to keep a copy here...
- install_prefix share_dir="$HOME/share" "$HOME/$HOST_TARGET"
- ;;
-esac
+op_install() {
+ op_test
+ case "$INSTALL_PREFIX,$INSTALL_BIN,$prefix" in
+ ,$HOST_TARGET/bin,*/$HOST_TARGET)
+ INSTALL_PREFIX=`dirname $prefix`
+ ;;
+ esac
+ INSTALL_PREFIX=${INSTALL_PREFIX:-$prefix}
+ Bmake install prefix=$INSTALL_PREFIX BINDIR=$INSTALL_PREFIX/${INSTALL_BIN:-bin} ${INSTALL_DESTDIR:+DESTDIR=$INSTALL_DESTDIR} $INSTALL_ARGS || exit 1
+}
+
+op_all() {
+ rm -f make-bootstrap.sh bmake *.o
+ if [ -n "$INSTALL_PREFIX" ]; then
+ op_install
+ else
+ op_test
+ MAKE_VERSION=`sed -n '/^MAKE_VERSION/ { s,.*= *,,;p; }' $srcdir/Makefile`
+ echo You can install by running:
+ echo
+ echo $0 $cmd_args op=install
+ echo
+ echo "Use --install-prefix=/something to install somewhere other than $prefix"
+ echo "Use --install-destdir=/somewhere to set DESTDIR during install"
+ echo "Use --install-host-target to use INSTALL_BIN=$HOST_TARGET/bin"
+ echo "Use -DWITH_PROG_VERSION to install as bmake-$MAKE_VERSION"
+ echo "Use -DWITHOUT_PROG_LINK to suppress bmake -> bmake-$MAKE_VERSION symlink"
+ echo "Use -DWITHOUT_INSTALL_MK to skip installing files to $prefix/share/mk"
+ fi
+}
-install_prefix "$prefix"
+op_$op
+exit 0
diff --git a/devel/bmake/files/bsd.after-import.mk b/devel/bmake/files/bsd.after-import.mk
new file mode 100644
index 00000000000..c92c5a1ee7f
--- /dev/null
+++ b/devel/bmake/files/bsd.after-import.mk
@@ -0,0 +1,111 @@
+# $Id: bsd.after-import.mk,v 1.1.1.1 2015/05/19 21:36:43 joerg Exp $
+
+# This makefile is for use when integrating bmake into a BSD build
+# system. Use this makefile after importing bmake.
+# It will bootstrap the new version,
+# capture the generated files we need, and add an after-import
+# target to allow the process to be easily repeated.
+
+# The goal is to allow the benefits of autoconf without
+# the overhead of running configure.
+
+all: _makefile
+all: after-import
+
+# we rely on bmake
+.if !defined(.PARSEDIR)
+.error this makefile requires bmake
+.endif
+
+_this := ${MAKEFILE:tA}
+BMAKE_SRC := ${.PARSEDIR}
+
+# it helps to know where the top of the tree is.
+.if !defined(SRCTOP)
+srctop := ${.MAKE.MAKEFILES:M*src/share/mk/sys.mk:H:H:H}
+.if empty(srctop)
+# likely locations?
+.for d in contrib/bmake external/bsd/bmake/dist
+.if ${BMAKE_SRC:M*/$d} != ""
+srctop := ${BMAKE_SRC:tA:S,/$d,,}
+.endif
+.endfor
+.endif
+.if !empty(srctop)
+SRCTOP := ${srctop}
+.endif
+.endif
+
+# This lets us match what boot-strap does
+.if !defined(HOST_OS)
+HOST_OS!= uname
+.endif
+
+BOOTSTRAP_ARGS = \
+ --prefix /usr \
+ --share /usr/share
+
+.if !empty(DEFAULT_SYS_PATH)
+BOOTSTRAP_ARGS += --with-default-sys-path='${DEFAULT_SYS_PATH}'
+.endif
+
+# run boot-strap with minimal influence
+bootstrap: ${BMAKE_SRC}/boot-strap ${MAKEFILE}
+ HOME=/ ${BMAKE_SRC}/boot-strap -o ${HOST_OS} ${BOOTSTRAP_ARGS} ${BOOTSTRAP_XTRAS}
+ touch ${.TARGET}
+
+# Makefiles need a little more tweaking than say config.h
+MAKEFILE_SED = sed -e '/^MACHINE/d' \
+ -e '/^PROG/ { s,=,?=,;s,bmake,$${.CURDIR:T},; }' \
+ -e 's,^.-include,.sinclude,' \
+ -e '/^\..*include *</ { s,<,<bsd.,;/autoconf/d; }' \
+ -e 's,${SRCTOP},$${SRCTOP},g'
+
+# These are the simple files we want to capture
+configured_files= config.h Makefile.config unit-tests/Makefile
+
+after-import: bootstrap ${MAKEFILE}
+.for f in ${configured_files:M*.[ch]}
+ @echo Capturing $f
+ @mkdir -p ${${.CURDIR}/$f:L:H}
+ @(echo '/* $$${HOST_OS}$$ */'; cat ${HOST_OS}/$f) > ${.CURDIR}/$f
+.endfor
+.for f in ${configured_files:M*Makefile*}
+ @echo Capturing $f
+ @mkdir -p ${${.CURDIR}/$f:L:H}
+ @(echo '# This is a generated file, do NOT edit!'; \
+ echo '# See ${_this:S,${SRCTOP}/,,}'; \
+ echo '#'; echo '# $$${HOST_OS}$$'; echo; \
+ echo 'SRCTOP?= $${.CURDIR:${${.CURDIR}/$f:L:H:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; echo; \
+ ${MAKEFILE_SED} ${HOST_OS}/$f ) > ${.CURDIR}/$f
+.endfor
+
+# this needs the most work
+_makefile: bootstrap ${MAKEFILE}
+ @echo Generating ${.CURDIR}/Makefile
+ @(echo '# This is a generated file, do NOT edit!'; \
+ echo '# See ${_this:S,${SRCTOP}/,,}'; \
+ echo '#'; echo '# $$${HOST_OS}$$'; \
+ echo; echo '.sinclude "Makefile.inc"'; \
+ echo; echo 'SRCTOP?= $${.CURDIR:${.CURDIR:S,${SRCTOP}/,,:C,[^/]+,H,g:S,/,:,g}}'; \
+ echo; echo '# look here first for config.h'; \
+ echo 'CFLAGS+= -I$${.CURDIR}'; echo; \
+ echo '# for after-import'; \
+ echo 'CLEANDIRS+= ${HOST_OS}'; \
+ echo 'CLEANFILES+= bootstrap'; echo; \
+ ${MAKEFILE_SED} \
+ ${1 2:L:@n@-e '/start-delete$n/,/end-delete$n/d'@} \
+ ${BMAKE_SRC}/Makefile; \
+ echo; echo '# override some simple things'; \
+ echo 'BINDIR= /usr/bin'; \
+ echo 'MANDIR= ${MANDIR:U/usr/share/man}'; \
+ echo; echo '# make sure we get this'; \
+ echo 'CFLAGS+= $${COPTS.$${.IMPSRC:T}}'; \
+ echo; echo 'after-import: ${_this:S,${SRCTOP},\${SRCTOP},}'; \
+ echo ' cd $${.CURDIR} && $${.MAKE} -f ${_this:S,${SRCTOP},\${SRCTOP},}'; \
+ echo ) > ${.TARGET}
+ @cmp -s ${.TARGET} ${.CURDIR}/Makefile || \
+ mv ${.TARGET} ${.CURDIR}/Makefile
+
+.include <bsd.obj.mk>
+
diff --git a/devel/bmake/files/buf.c b/devel/bmake/files/buf.c
index 5df1a688715..8bb28af4ab5 100644
--- a/devel/bmake/files/buf.c
+++ b/devel/bmake/files/buf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.c,v 1.1.1.5 2009/09/18 20:55:23 joerg Exp $ */
+/* $NetBSD: buf.c,v 1.1.1.6 2015/05/19 21:36:43 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: buf.c,v 1.1.1.5 2009/09/18 20:55:23 joerg Exp $";
+static char rcsid[] = "$NetBSD: buf.c,v 1.1.1.6 2015/05/19 21:36:43 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: buf.c,v 1.1.1.5 2009/09/18 20:55:23 joerg Exp $");
+__RCSID("$NetBSD: buf.c,v 1.1.1.6 2015/05/19 21:36:43 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -248,3 +248,44 @@ Buf_Destroy(Buffer *buf, Boolean freeData)
return data;
}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_DestroyCompact --
+ * Nuke a buffer and return its data.
+ *
+ * Input:
+ * buf Buffer to destroy
+ *
+ * Results:
+ * Data buffer
+ *
+ * Side Effects:
+ * If the buffer size is much greater than its content,
+ * a new buffer will be allocated and the old one freed.
+ *
+ *-----------------------------------------------------------------------
+ */
+#ifndef BUF_COMPACT_LIMIT
+# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */
+#endif
+
+Byte *
+Buf_DestroyCompact(Buffer *buf)
+{
+#if BUF_COMPACT_LIMIT > 0
+ Byte *data;
+
+ if (buf->size - buf->count >= BUF_COMPACT_LIMIT) {
+ /* We trust realloc to be smart */
+ data = bmake_realloc(buf->buffer, buf->count + 1);
+ if (data) {
+ data[buf->count] = 0;
+ Buf_Destroy(buf, FALSE);
+ return data;
+ }
+ }
+#endif
+ return Buf_Destroy(buf, FALSE);
+}
diff --git a/devel/bmake/files/buf.h b/devel/bmake/files/buf.h
index f35704e5fd0..03c4be4fbc6 100644
--- a/devel/bmake/files/buf.h
+++ b/devel/bmake/files/buf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: buf.h,v 1.1.1.4 2009/09/18 20:55:23 joerg Exp $ */
+/* $NetBSD: buf.h,v 1.1.1.5 2015/05/19 21:36:43 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -114,5 +114,6 @@ Byte *Buf_GetAll(Buffer *, int *);
void Buf_Empty(Buffer *);
void Buf_Init(Buffer *, int);
Byte *Buf_Destroy(Buffer *, Boolean);
+Byte *Buf_DestroyCompact(Buffer *);
#endif /* _BUF_H */
diff --git a/devel/bmake/files/compat.c b/devel/bmake/files/compat.c
index 45d5686d6fe..3486cd33706 100644
--- a/devel/bmake/files/compat.c
+++ b/devel/bmake/files/compat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: compat.c,v 1.1.1.8 2011/06/18 22:17:48 bsiegert Exp $ */
+/* $NetBSD: compat.c,v 1.1.1.9 2015/05/19 21:36:43 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: compat.c,v 1.1.1.8 2011/06/18 22:17:48 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.1.1.9 2015/05/19 21:36:43 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: compat.c,v 1.1.1.8 2011/06/18 22:17:48 bsiegert Exp $");
+__RCSID("$NetBSD: compat.c,v 1.1.1.9 2015/05/19 21:36:43 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -133,7 +133,7 @@ Compat_Init(void)
Shell_Init(); /* setup default shell */
- for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
+ for (cp = "~#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
meta[(unsigned char) *cp] = 1;
}
/*
@@ -183,7 +183,10 @@ CompatInterrupt(int signo)
}
}
- exit(signo);
+ if (signo == SIGQUIT)
+ _exit(signo);
+ bmake_signal(signo, SIG_DFL);
+ kill(myPid, signo);
}
/*-
@@ -244,7 +247,6 @@ CompatRunCommand(void *cmdp, void *gnp)
if (*cmdStart == '\0') {
free(cmdStart);
- Error("%s expands to empty string", cmd);
return(0);
}
cmd = cmdStart;
@@ -279,6 +281,12 @@ CompatRunCommand(void *cmdp, void *gnp)
while (isspace((unsigned char)*cmd))
cmd++;
+ /*
+ * If we did not end up with a command, just skip it.
+ */
+ if (!*cmd)
+ return (0);
+
#if !defined(MAKE_NATIVE)
/*
* In a non-native build, the host environment might be weird enough
@@ -324,18 +332,23 @@ again:
* We need to pass the command off to the shell, typically
* because the command contains a "meta" character.
*/
- static const char *shargv[4];
+ static const char *shargv[5];
+ int shargc;
- shargv[0] = shellPath;
+ shargc = 0;
+ shargv[shargc++] = shellPath;
/*
* The following work for any of the builtin shell specs.
*/
+ if (errCheck && shellErrFlag) {
+ shargv[shargc++] = shellErrFlag;
+ }
if (DEBUG(SHELL))
- shargv[1] = "-xc";
+ shargv[shargc++] = "-xc";
else
- shargv[1] = "-c";
- shargv[2] = cmd;
- shargv[3] = NULL;
+ shargv[shargc++] = "-c";
+ shargv[shargc++] = cmd;
+ shargv[shargc++] = NULL;
av = shargv;
argc = 0;
bp = NULL;
@@ -350,7 +363,7 @@ again:
useShell = 1;
goto again;
}
- av = (const char **)mav;
+ av = (void *)mav;
}
local = TRUE;
@@ -369,7 +382,6 @@ again:
Fatal("Could not fork");
}
if (cpid == 0) {
- Check_Cwd(av);
Var_ExportVars();
#ifdef USE_META
if (useMeta) {
diff --git a/devel/bmake/files/cond.c b/devel/bmake/files/cond.c
index c4345a85982..5633ea375db 100644
--- a/devel/bmake/files/cond.c
+++ b/devel/bmake/files/cond.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.1.1.7 2011/06/18 22:17:48 bsiegert Exp $ */
+/* $NetBSD: cond.c,v 1.1.1.8 2015/05/19 21:36:43 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: cond.c,v 1.1.1.7 2011/06/18 22:17:48 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: cond.c,v 1.1.1.8 2015/05/19 21:36:43 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: cond.c,v 1.1.1.7 2011/06/18 22:17:48 bsiegert Exp $");
+__RCSID("$NetBSD: cond.c,v 1.1.1.8 2015/05/19 21:36:43 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -181,6 +181,15 @@ static Token condPushBack=TOK_NONE; /* Single push-back token used in
static unsigned int cond_depth = 0; /* current .if nesting level */
static unsigned int cond_min_depth = 0; /* depth at makefile open */
+/*
+ * Indicate when we should be strict about lhs of comparisons.
+ * TRUE when Cond_EvalExpression is called from Cond_Eval (.if etc)
+ * FALSE when Cond_EvalExpression is called from var.c:ApplyModifiers
+ * since lhs is already expanded and we cannot tell if
+ * it was a variable reference or not.
+ */
+static Boolean lhsStrict;
+
static int
istoken(const char *str, const char *tok, size_t len)
{
@@ -327,7 +336,7 @@ CondGetArg(char **linePtr, char **argPtr, const char *func)
*-----------------------------------------------------------------------
*/
static Boolean
-CondDoDefined(int argLen __unused, const char *arg)
+CondDoDefined(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
char *p1;
Boolean result;
@@ -376,7 +385,7 @@ CondStrMatch(const void *string, const void *pattern)
*-----------------------------------------------------------------------
*/
static Boolean
-CondDoMake(int argLen __unused, const char *arg)
+CondDoMake(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
return Lst_Find(create, arg, CondStrMatch) != NULL;
}
@@ -395,7 +404,7 @@ CondDoMake(int argLen __unused, const char *arg)
*-----------------------------------------------------------------------
*/
static Boolean
-CondDoExists(int argLen __unused, const char *arg)
+CondDoExists(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
Boolean result;
char *path;
@@ -428,7 +437,7 @@ CondDoExists(int argLen __unused, const char *arg)
*-----------------------------------------------------------------------
*/
static Boolean
-CondDoTarget(int argLen __unused, const char *arg)
+CondDoTarget(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
GNode *gn;
@@ -452,7 +461,7 @@ CondDoTarget(int argLen __unused, const char *arg)
*-----------------------------------------------------------------------
*/
static Boolean
-CondDoCommands(int argLen __unused, const char *arg)
+CondDoCommands(int argLen MAKE_ATTR_UNUSED, const char *arg)
{
GNode *gn;
@@ -517,7 +526,7 @@ CondCvtArg(char *str, double *value)
*/
/* coverity:[+alloc : arg-*2] */
static char *
-CondGetString(Boolean doEval, Boolean *quoted, void **freeIt)
+CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
{
Buffer buf;
char *cp;
@@ -601,6 +610,16 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt)
condExpr--; /* don't skip over next char */
break;
default:
+ if (strictLHS && !qt && *start != '$' &&
+ !isdigit((unsigned char) *start)) {
+ /* lhs must be quoted, a variable reference or number */
+ if (*freeIt) {
+ free(*freeIt);
+ *freeIt = NULL;
+ }
+ str = NULL;
+ goto cleanup;
+ }
Buf_AddByte(&buf, *condExpr);
break;
}
@@ -648,7 +667,7 @@ compare_expression(Boolean doEval)
* Parse the variable spec and skip over it, saving its
* value in lhs.
*/
- lhs = CondGetString(doEval, &lhsQuoted, &lhsFree);
+ lhs = CondGetString(doEval, &lhsQuoted, &lhsFree, lhsStrict);
if (!lhs)
goto done;
@@ -709,7 +728,7 @@ compare_expression(Boolean doEval)
goto done;
}
- rhs = CondGetString(doEval, &rhsQuoted, &rhsFree);
+ rhs = CondGetString(doEval, &rhsQuoted, &rhsFree, FALSE);
if (!rhs)
goto done;
@@ -790,7 +809,7 @@ done:
}
static int
-get_mpt_arg(char **linePtr, char **argPtr, const char *func __unused)
+get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED)
{
/*
* Use Var_Parse to parse the spec in parens and return
@@ -831,7 +850,7 @@ get_mpt_arg(char **linePtr, char **argPtr, const char *func __unused)
}
static Boolean
-CondDoEmpty(int arglen, const char *arg __unused)
+CondDoEmpty(int arglen, const char *arg MAKE_ATTR_UNUSED)
{
return arglen == 1;
}
@@ -1135,7 +1154,7 @@ CondE(Boolean doEval)
*-----------------------------------------------------------------------
*/
int
-Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprint)
+Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprint, Boolean strictLHS)
{
static const struct If *dflt_info;
const struct If *sv_if_info = if_info;
@@ -1143,6 +1162,8 @@ Cond_EvalExpression(const struct If *info, char *line, Boolean *value, int eprin
Token sv_condPushBack = condPushBack;
int rval;
+ lhsStrict = strictLHS;
+
while (*line == ' ' || *line == '\t')
line++;
@@ -1227,7 +1248,8 @@ do_Cond_EvalExpression(Boolean *value)
int
Cond_Eval(char *line)
{
- #define MAXIF 64 /* maximum depth of .if'ing */
+#define MAXIF 128 /* maximum depth of .if'ing */
+#define MAXIF_BUMP 32 /* how much to grow by */
enum if_states {
IF_ACTIVE, /* .if or .elif part active */
ELSE_ACTIVE, /* .else part active */
@@ -1235,7 +1257,8 @@ Cond_Eval(char *line)
SKIP_TO_ELSE, /* has been true, but not seen '.else' */
SKIP_TO_ENDIF /* nothing else to execute */
};
- static enum if_states cond_state[MAXIF + 1] = { IF_ACTIVE };
+ static enum if_states *cond_state = NULL;
+ static unsigned int max_if_depth = MAXIF;
const struct If *ifp;
Boolean isElif;
@@ -1244,7 +1267,10 @@ Cond_Eval(char *line)
enum if_states state;
level = PARSE_FATAL;
-
+ if (!cond_state) {
+ cond_state = bmake_malloc(max_if_depth * sizeof(*cond_state));
+ cond_state[0] = IF_ACTIVE;
+ }
/* skip leading character (the '.') and any whitespace */
for (line++; *line == ' ' || *line == '\t'; line++)
continue;
@@ -1261,8 +1287,6 @@ Cond_Eval(char *line)
}
/* Return state for previous conditional */
cond_depth--;
- if (cond_depth > MAXIF)
- return COND_SKIP;
return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
}
@@ -1275,8 +1299,6 @@ Cond_Eval(char *line)
return COND_PARSE;
}
- if (cond_depth > MAXIF)
- return COND_SKIP;
state = cond_state[cond_depth];
switch (state) {
case SEARCH_FOR_ELIF:
@@ -1325,9 +1347,6 @@ Cond_Eval(char *line)
Parse_Error(level, "if-less elif");
return COND_PARSE;
}
- if (cond_depth > MAXIF)
- /* Error reported when we saw the .if ... */
- return COND_SKIP;
state = cond_state[cond_depth];
if (state == SKIP_TO_ENDIF || state == ELSE_ACTIVE) {
Parse_Error(PARSE_WARNING, "extra elif");
@@ -1341,10 +1360,15 @@ Cond_Eval(char *line)
}
} else {
/* Normal .if */
- if (cond_depth >= MAXIF) {
- cond_depth++;
- Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);
- return COND_SKIP;
+ if (cond_depth + 1 >= max_if_depth) {
+ /*
+ * This is rare, but not impossible.
+ * In meta mode, dirdeps.mk (only runs at level 0)
+ * can need more than the default.
+ */
+ max_if_depth += MAXIF_BUMP;
+ cond_state = bmake_realloc(cond_state, max_if_depth *
+ sizeof(*cond_state));
}
state = cond_state[cond_depth];
cond_depth++;
@@ -1356,7 +1380,7 @@ Cond_Eval(char *line)
}
/* And evaluate the conditional expresssion */
- if (Cond_EvalExpression(ifp, line, &value, 1) == COND_INVALID) {
+ if (Cond_EvalExpression(ifp, line, &value, 1, TRUE) == COND_INVALID) {
/* Syntax error in conditional, error message already output. */
/* Skip everything to matching .endif */
cond_state[cond_depth] = SKIP_TO_ELSE;
diff --git a/devel/bmake/files/config.h.in b/devel/bmake/files/config.h.in
index 2c7e4eb297c..ce30da1e36c 100644
--- a/devel/bmake/files/config.h.in
+++ b/devel/bmake/files/config.h.in
@@ -89,6 +89,12 @@
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
+/* Define to 1 if you have the `setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define to 1 if you have the `setsid' function. */
+#undef HAVE_SETSID
+
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
@@ -138,6 +144,9 @@
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
#undef HAVE_ST_RDEV
+/* Define to 1 if you have the `sysctl' function. */
+#undef HAVE_SYSCTL
+
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
@@ -158,6 +167,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#undef HAVE_SYS_SYSCTL_H
+
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
@@ -292,6 +304,9 @@
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
+/* C99 function name */
+#undef __func__
+
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/devel/bmake/files/configure b/devel/bmake/files/configure
index 9a0d5fe4206..08b21b324ab 100755
--- a/devel/bmake/files/configure
+++ b/devel/bmake/files/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for bmake 2010505.
+# Generated by GNU Autoconf 2.64 for bmake 20140214.
#
# Report bugs to <sjg@NetBSD.org>.
#
@@ -549,8 +549,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='bmake'
PACKAGE_TARNAME='bmake'
-PACKAGE_VERSION='2010505'
-PACKAGE_STRING='bmake 2010505'
+PACKAGE_VERSION='20140214'
+PACKAGE_STRING='bmake 20140214'
PACKAGE_BUGREPORT='sjg@NetBSD.org'
PACKAGE_URL=''
@@ -602,6 +602,7 @@ machine_arch
force_machine
machine
LIBOBJS
+bmake_path_max
ac_exe_suffix
INSTALL_DATA
INSTALL_SCRIPT
@@ -1220,7 +1221,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures bmake 2010505 to adapt to many kinds of systems.
+\`configure' configures bmake 20140214 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1281,7 +1282,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of bmake 2010505:";;
+ short | recursive ) echo "Configuration of bmake 20140214:";;
esac
cat <<\_ACEOF
@@ -1386,7 +1387,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-bmake configure 2010505
+bmake configure 20140214
generated by GNU Autoconf 2.64
Copyright (C) 2009 Free Software Foundation, Inc.
@@ -1907,7 +1908,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by bmake $as_me 2010505, which was
+It was created by bmake $as_me 20140214, which was
generated by GNU Autoconf 2.64. Invocation command line was
$ $0 $@
@@ -2257,6 +2258,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h"
+case "$srcdir" in
+/*) ;;
+*) srcdir=`cd $srcdir && pwd`;;
+esac
+
# Check whether --with-defshell was given.
if test "${with_defshell+set}" = set; then :
@@ -2294,7 +2300,7 @@ esac
else
OS=`uname -s`
-for d in "$srcdir/filemon" "$srcdir/../filemon"
+for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
do
for x in "/$OS" ""
do
@@ -4239,7 +4245,17 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
+if test -x /usr/bin/getconf; then
+ bmake_path_max=`getconf PATH_MAX / 2> /dev/null`
+ # only a numeric response is useful
+ test ${bmake_path_max:-0} -gt 0 2> /dev/null || bmake_path_max=
+fi
+bmake_path_max=${bmake_path_max:-1024}
+if test $bmake_path_max -gt 1024; then
+ # this is all we expect
+ bmake_path_max=1024
+fi
+echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
@@ -4564,6 +4580,7 @@ for ac_header in \
sys/mman.h \
sys/select.h \
sys/socket.h \
+ sys/sysctl.h \
sys/time.h \
sys/uio.h \
unistd.h \
@@ -5420,6 +5437,8 @@ for ac_func in \
putenv \
select \
setenv \
+ setpgid \
+ setsid \
sigaction \
sigvec \
snprintf \
@@ -5428,6 +5447,7 @@ for ac_func in \
strsep \
strtod \
strtol \
+ sysctl \
unsetenv \
vsnprintf \
wait3 \
@@ -5450,7 +5470,6 @@ done
for ac_func in \
- getenv \
realpath \
dirname \
stresep \
@@ -5691,6 +5710,32 @@ $as_echo "#define HAVE_ST_RDEV 1" >>confdefs.h
fi
+echo "checking if compiler supports __func__" >&6
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+const char *func = __func__;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+
+$as_echo "#define __func__ __FUNCTION__" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
if diff -u /dev/null /dev/null > /dev/null 2>&1; then
diff_u=-u
@@ -5853,7 +5898,7 @@ fi
-ac_config_files="$ac_config_files Makefile make-bootstrap.sh unit-tests/Makefile"
+ac_config_files="$ac_config_files makefile Makefile.config make-bootstrap.sh unit-tests/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -6361,7 +6406,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by bmake $as_me 2010505, which was
+This file was extended by bmake $as_me 20140214, which was
generated by GNU Autoconf 2.64. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6421,7 +6466,7 @@ Report bugs to <sjg@NetBSD.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
-bmake config.status 2010505
+bmake config.status 20140214
configured by $0, generated by GNU Autoconf 2.64,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -6536,7 +6581,8 @@ for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "makefile") CONFIG_FILES="$CONFIG_FILES makefile" ;;
+ "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
"make-bootstrap.sh") CONFIG_FILES="$CONFIG_FILES make-bootstrap.sh" ;;
"unit-tests/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/Makefile" ;;
@@ -7119,7 +7165,7 @@ cat <<EOF
You can now run
- ./make-bootstrap.sh
+ sh ./make-bootstrap.sh
to produce a fully functional bmake.
diff --git a/devel/bmake/files/configure.in b/devel/bmake/files/configure.in
index 212e7058506..65197e76db4 100644
--- a/devel/bmake/files/configure.in
+++ b/devel/bmake/files/configure.in
@@ -1,11 +1,18 @@
dnl
dnl RCSid:
-dnl $Id: configure.in,v 1.1.1.6 2011/06/18 22:17:53 bsiegert Exp $
+dnl $Id: configure.in,v 1.1.1.7 2015/05/19 21:36:43 joerg Exp $
dnl
dnl Process this file with autoconf to produce a configure script
dnl
-AC_INIT([bmake], [2010505], [sjg@NetBSD.org])
-AC_CONFIG_HEADER(config.h)
+AC_PREREQ(2.50)
+AC_INIT([bmake], [20140214], [sjg@NetBSD.org])
+AC_CONFIG_HEADERS(config.h)
+
+dnl make srcdir absolute
+case "$srcdir" in
+/*) ;;
+*) srcdir=`cd $srcdir && pwd`;;
+esac
dnl
AC_ARG_WITH(defshell,
@@ -39,7 +46,7 @@ AC_ARG_WITH(filemon,
esac],
[
OS=`uname -s`
-for d in "$srcdir/filemon" "$srcdir/../filemon"
+for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
do
for x in "/$OS" ""
do
@@ -71,7 +78,20 @@ AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL
dnl Executable suffix - normally empty; .exe on os2.
AC_SUBST(ac_exe_suffix)dnl
-
+dnl
+dnl Hurd refuses to define PATH_MAX or MAXPATHLEN
+if test -x /usr/bin/getconf; then
+ bmake_path_max=`getconf PATH_MAX / 2> /dev/null`
+ # only a numeric response is useful
+ test ${bmake_path_max:-0} -gt 0 2> /dev/null || bmake_path_max=
+fi
+bmake_path_max=${bmake_path_max:-1024}
+if test $bmake_path_max -gt 1024; then
+ # this is all we expect
+ bmake_path_max=1024
+fi
+echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
+AC_SUBST(bmake_path_max)dnl
dnl
dnl AC_C_CROSS
dnl
@@ -92,6 +112,7 @@ AC_CHECK_HEADERS( \
sys/mman.h \
sys/select.h \
sys/socket.h \
+ sys/sysctl.h \
sys/time.h \
sys/uio.h \
unistd.h \
@@ -143,6 +164,8 @@ AC_CHECK_FUNCS( \
putenv \
select \
setenv \
+ setpgid \
+ setsid \
sigaction \
sigvec \
snprintf \
@@ -151,6 +174,7 @@ AC_CHECK_FUNCS( \
strsep \
strtod \
strtol \
+ sysctl \
unsetenv \
vsnprintf \
wait3 \
@@ -162,7 +186,6 @@ AC_CHECK_FUNCS( \
dnl functions which we may need to provide
AC_REPLACE_FUNCS( \
- getenv \
realpath \
dirname \
stresep \
@@ -182,6 +205,11 @@ dnl
AC_HEADER_STAT
AC_STRUCT_ST_RDEV
dnl
+echo "checking if compiler supports __func__" >&6
+AC_LANG(C)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[[const char *func = __func__;]])],,
+ AC_DEFINE(__func__, __FUNCTION__, C99 function name))
+dnl
dnl we want this for unit-tests/Makefile
echo $ECHO_N "checking if diff -u works... $ECHO_C" >&6
if diff -u /dev/null /dev/null > /dev/null 2>&1; then
@@ -347,13 +375,13 @@ AC_SUBST(GCC)
AC_SUBST(diff_u)
AC_SUBST(use_meta)
AC_SUBST(filemon_h)
-AC_OUTPUT(Makefile make-bootstrap.sh unit-tests/Makefile)
+AC_OUTPUT(makefile Makefile.config make-bootstrap.sh unit-tests/Makefile)
cat <<EOF
You can now run
- ./make-bootstrap.sh
+ sh ./make-bootstrap.sh
to produce a fully functional bmake.
diff --git a/devel/bmake/files/dir.c b/devel/bmake/files/dir.c
index 680f7c37d2a..db94744340c 100644
--- a/devel/bmake/files/dir.c
+++ b/devel/bmake/files/dir.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.1.1.6 2011/06/18 22:17:55 bsiegert Exp $ */
+/* $NetBSD: dir.c,v 1.1.1.7 2015/05/19 21:36:43 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: dir.c,v 1.1.1.6 2011/06/18 22:17:55 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.1.1.7 2015/05/19 21:36:43 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: dir.c,v 1.1.1.6 2011/06/18 22:17:55 bsiegert Exp $");
+__RCSID("$NetBSD: dir.c,v 1.1.1.7 2015/05/19 21:36:43 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -145,6 +145,7 @@ __RCSID("$NetBSD: dir.c,v 1.1.1.6 2011/06/18 22:17:55 bsiegert Exp $");
#include "make.h"
#include "hash.h"
#include "dir.h"
+#include "job.h"
/*
* A search path consists of a Lst of Path structures. A Path structure
@@ -860,8 +861,8 @@ Dir_Expand(const char *word, Lst path, Lst expansions)
*-----------------------------------------------------------------------
*/
static char *
-DirLookup(Path *p, const char *name __unused, const char *cp,
- Boolean hasSlash __unused)
+DirLookup(Path *p, const char *name MAKE_ATTR_UNUSED, const char *cp,
+ Boolean hasSlash MAKE_ATTR_UNUSED)
{
char *file; /* the current filename to check */
@@ -1004,7 +1005,7 @@ DirLookupAbs(Path *p, const char *name, const char *cp)
*-----------------------------------------------------------------------
*/
static char *
-DirFindDot(Boolean hasSlash __unused, const char *name, const char *cp)
+DirFindDot(Boolean hasSlash MAKE_ATTR_UNUSED, const char *name, const char *cp)
{
if (Hash_FindEntry(&dot->files, cp) != NULL) {
@@ -1428,7 +1429,7 @@ Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
*-----------------------------------------------------------------------
*/
int
-Dir_MTime(GNode *gn)
+Dir_MTime(GNode *gn, Boolean recheck)
{
char *fullName; /* the full pathname of name */
struct stat stb; /* buffer for finding the mod time */
@@ -1463,9 +1464,11 @@ Dir_MTime(GNode *gn)
* so that we give that to the compiler.
*/
gn->path = bmake_strdup(fullName);
- fprintf(stdout,
- "%s: ignoring stale %s for %s, found %s\n",
- progname, makeDependfile, gn->name, fullName);
+ if (!Job_RunTarget(".STALE", gn->fname))
+ fprintf(stdout,
+ "%s: %s, %d: ignoring stale %s for %s, "
+ "found %s\n", progname, gn->fname, gn->lineno,
+ makeDependfile, gn->name, fullName);
}
}
}
@@ -1481,19 +1484,16 @@ Dir_MTime(GNode *gn)
fullName = bmake_strdup(gn->name);
}
- entry = Hash_FindEntry(&mtimes, fullName);
+ if (!recheck)
+ entry = Hash_FindEntry(&mtimes, fullName);
+ else
+ entry = NULL;
if (entry != NULL) {
- /*
- * Only do this once -- the second time folks are checking to
- * see if the file was actually updated, so we need to actually go
- * to the file system.
- */
if (DEBUG(DIR)) {
fprintf(debug_file, "Using cached time %s for %s\n",
Targ_FmtTime(Hash_GetTimeValue(entry)), fullName);
}
stb.st_mtime = Hash_GetTimeValue(entry);
- Hash_DeleteEntry(&mtimes, entry);
} else if (stat(fullName, &stb) < 0) {
if (gn->type & OP_MEMBER) {
if (fullName != gn->path)
@@ -1502,12 +1502,16 @@ Dir_MTime(GNode *gn)
} else {
stb.st_mtime = 0;
}
- } else if (stb.st_mtime == 0) {
- /*
- * 0 handled specially by the code, if the time is really 0, return
- * something else instead
- */
- stb.st_mtime = 1;
+ } else {
+ if (stb.st_mtime == 0) {
+ /*
+ * 0 handled specially by the code, if the time is really 0,
+ * return something else instead
+ */
+ stb.st_mtime = 1;
+ }
+ entry = Hash_CreateEntry(&mtimes, fullName, NULL);
+ Hash_SetTimeValue(entry, stb.st_mtime);
}
if (fullName && gn->path == NULL) {
diff --git a/devel/bmake/files/dir.h b/devel/bmake/files/dir.h
index 04132ca38d5..8c9eb62c02d 100644
--- a/devel/bmake/files/dir.h
+++ b/devel/bmake/files/dir.h
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.h,v 1.1.1.4 2009/09/18 20:55:25 joerg Exp $ */
+/* $NetBSD: dir.h,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -95,7 +95,7 @@ Boolean Dir_HasWildcards(char *);
void Dir_Expand(const char *, Lst, Lst);
char *Dir_FindFile(const char *, Lst);
int Dir_FindHereOrAbove(char *, char *, char *, int);
-int Dir_MTime(GNode *);
+int Dir_MTime(GNode *, Boolean);
Path *Dir_AddDir(Lst, const char *);
char *Dir_MakeFlags(const char *, Lst);
void Dir_ClearPath(Lst);
diff --git a/devel/bmake/files/for.c b/devel/bmake/files/for.c
index f98415563c4..3f33057d434 100644
--- a/devel/bmake/files/for.c
+++ b/devel/bmake/files/for.c
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.1.1.7 2011/06/18 22:17:55 bsiegert Exp $ */
+/* $NetBSD: for.c,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1992, The Regents of the University of California.
@@ -30,14 +30,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.1.1.7 2011/06/18 22:17:55 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: for.c,v 1.1.1.7 2011/06/18 22:17:55 bsiegert Exp $");
+__RCSID("$NetBSD: for.c,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -151,6 +151,8 @@ For_Eval(char *line)
int len;
int escapes;
unsigned char ch;
+ char **words, *word_buf;
+ int n, nwords;
/* Skip the '.' and any following whitespace */
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
@@ -216,35 +218,56 @@ For_Eval(char *line)
*/
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
- for (ptr = sub;; ptr += len) {
- while (*ptr && isspace((unsigned char)*ptr))
- ptr++;
- if (*ptr == 0)
- break;
- escapes = 0;
- for (len = 0; (ch = ptr[len]) != 0 && !isspace(ch); len++) {
- if (ch == ':' || ch == '$' || ch == '\\')
- escapes |= FOR_SUB_ESCAPE_CHAR;
- else if (ch == ')')
- escapes |= FOR_SUB_ESCAPE_PAREN;
- else if (ch == /*{*/ '}')
- escapes |= FOR_SUB_ESCAPE_BRACE;
- }
- strlist_add_str(&new_for->items, make_str(ptr, len), escapes);
- }
+ /*
+ * Split into words allowing for quoted strings.
+ */
+ words = brk_string(sub, &nwords, FALSE, &word_buf);
free(sub);
+
+ if (words != NULL) {
+ for (n = 0; n < nwords; n++) {
+ ptr = words[n];
+ if (!*ptr)
+ continue;
+ escapes = 0;
+ while ((ch = *ptr++)) {
+ switch(ch) {
+ case ':':
+ case '$':
+ case '\\':
+ escapes |= FOR_SUB_ESCAPE_CHAR;
+ break;
+ case ')':
+ escapes |= FOR_SUB_ESCAPE_PAREN;
+ break;
+ case /*{*/ '}':
+ escapes |= FOR_SUB_ESCAPE_BRACE;
+ break;
+ }
+ }
+ /*
+ * We have to dup words[n] to maintain the semantics of
+ * strlist.
+ */
+ strlist_add_str(&new_for->items, bmake_strdup(words[n]), escapes);
+ }
- if (strlist_num(&new_for->items) % strlist_num(&new_for->vars)) {
- Parse_Error(PARSE_FATAL,
- "Wrong number of words (%d) in .for substitution list"
- " with %d vars",
- strlist_num(&new_for->items), strlist_num(&new_for->vars));
- /*
- * Return 'success' so that the body of the .for loop is accumulated.
- * Remove all items so that the loop doesn't iterate.
- */
- strlist_clean(&new_for->items);
+ free(words);
+ free(word_buf);
+
+ if ((len = strlist_num(&new_for->items)) > 0 &&
+ len % (n = strlist_num(&new_for->vars))) {
+ Parse_Error(PARSE_FATAL,
+ "Wrong number of words (%d) in .for substitution list"
+ " with %d vars", len, n);
+ /*
+ * Return 'success' so that the body of the .for loop is
+ * accumulated.
+ * Remove all items so that the loop doesn't iterate.
+ */
+ strlist_clean(&new_for->items);
+ }
}
Buf_Init(&new_for->buf, 0);
diff --git a/devel/bmake/files/hash.c b/devel/bmake/files/hash.c
index 5651bfeba0b..2c3b130f65a 100644
--- a/devel/bmake/files/hash.c
+++ b/devel/bmake/files/hash.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hash.c,v 1.1.1.4 2009/09/18 20:55:26 joerg Exp $ */
+/* $NetBSD: hash.c,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: hash.c,v 1.1.1.4 2009/09/18 20:55:26 joerg Exp $";
+static char rcsid[] = "$NetBSD: hash.c,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: hash.c,v 1.1.1.4 2009/09/18 20:55:26 joerg Exp $");
+__RCSID("$NetBSD: hash.c,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -221,6 +221,9 @@ Hash_FindEntry(Hash_Table *t, const char *key)
unsigned h;
const char *p;
+ if (t == NULL || t->bucketPtr == NULL) {
+ return NULL;
+ }
for (h = 0, p = key; *p;)
h = (h << 5) - h + *p++;
p = key;
diff --git a/devel/bmake/files/job.c b/devel/bmake/files/job.c
index c7732eeafa0..e140b945aab 100644
--- a/devel/bmake/files/job.c
+++ b/devel/bmake/files/job.c
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.1.1.9 2011/06/18 22:17:58 bsiegert Exp $ */
+/* $NetBSD: job.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: job.c,v 1.1.1.9 2011/06/18 22:17:58 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: job.c,v 1.1.1.9 2011/06/18 22:17:58 bsiegert Exp $");
+__RCSID("$NetBSD: job.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -142,6 +142,7 @@ __RCSID("$NetBSD: job.c,v 1.1.1.9 2011/06/18 22:17:58 bsiegert Exp $");
#include <sys/time.h>
#include "wait.h"
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#if !defined(USE_SELECT) && defined(HAVE_POLL_H)
@@ -312,6 +313,7 @@ static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to
const char *shellPath = NULL, /* full pathname of
* executable image */
*shellName = NULL; /* last component of shell */
+char *shellErrFlag = NULL;
static const char *shellArgv = NULL; /* Custom shell args */
@@ -334,10 +336,7 @@ static int readyfd(Job *);
STATIC GNode *lastNode; /* The node for which output was most recently
* produced. */
-STATIC const char *targFmt; /* Format string to use to head output from a
- * job when it's not the most-recent job heard
- * from */
-static char *targPrefix = NULL; /* What we print at the start of targFmt */
+static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */
static Job tokenWaitJob; /* token wait pseudo-job */
static Job childExitJob; /* child exit pseudo-job */
@@ -346,7 +345,8 @@ static Job childExitJob; /* child exit pseudo-job */
#define TARG_FMT "%s %s ---\n" /* Default format */
#define MESSAGE(fp, gn) \
- (void)fprintf(fp, targFmt, targPrefix, gn->name)
+ if (maxJobs != 1 && targPrefix && *targPrefix) \
+ (void)fprintf(fp, TARG_FMT, targPrefix, gn->name)
static sigset_t caught_signals; /* Set of signals we handle */
#if defined(SYSV)
@@ -367,7 +367,7 @@ static int JobStart(GNode *, int);
static char *JobOutput(Job *, char *, char *, int);
static void JobDoOutput(Job *, Boolean);
static Shell *JobMatchShell(const char *);
-static void JobInterrupt(int, int);
+static void JobInterrupt(int, int) MAKE_ATTR_DEAD;
static void JobRestartJobs(void);
static void JobTokenAdd(void);
static void JobSigLock(sigset_t *);
@@ -415,6 +415,15 @@ JobCreatePipe(Job *job, int minfd)
if (pipe(job->jobPipe) == -1)
Punt("Cannot create pipe: %s", strerror(errno));
+ for (i = 0; i < 2; i++) {
+ /* Avoid using low numbered fds */
+ fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
+ if (fd != -1) {
+ close(job->jobPipe[i]);
+ job->jobPipe[i] = fd;
+ }
+ }
+
/* Set close-on-exec flag for both */
(void)fcntl(job->jobPipe[0], F_SETFD, 1);
(void)fcntl(job->jobPipe[1], F_SETFD, 1);
@@ -427,15 +436,6 @@ JobCreatePipe(Job *job, int minfd)
*/
fcntl(job->jobPipe[0], F_SETFL,
fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK);
-
- for (i = 0; i < 2; i++) {
- /* Avoid using low numbered fds */
- fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
- if (fd != -1) {
- close(job->jobPipe[i]);
- job->jobPipe[i] = fd;
- }
- }
}
/*-
@@ -490,9 +490,10 @@ JobCondPassSig(int signo)
*-----------------------------------------------------------------------
*/
static void
-JobChildSig(int signo __unused)
+JobChildSig(int signo MAKE_ATTR_UNUSED)
{
- write(childExitJob.outPipe, CHILD_EXIT, 1);
+ while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 && errno == EAGAIN)
+ continue;
}
@@ -513,13 +514,15 @@ JobChildSig(int signo __unused)
*-----------------------------------------------------------------------
*/
static void
-JobContinueSig(int signo __unused)
+JobContinueSig(int signo MAKE_ATTR_UNUSED)
{
/*
* Defer sending to SIGCONT to our stopped children until we return
* from the signal handler.
*/
- write(childExitJob.outPipe, DO_JOB_RESUME, 1);
+ while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 &&
+ errno == EAGAIN)
+ continue;
}
/*-
@@ -538,14 +541,14 @@ JobContinueSig(int signo __unused)
*
*-----------------------------------------------------------------------
*/
-static void
+MAKE_ATTR_DEAD static void
JobPassSig_int(int signo)
{
/* Run .INTERRUPT target then exit */
JobInterrupt(TRUE, signo);
}
-static void
+MAKE_ATTR_DEAD static void
JobPassSig_term(int signo)
{
/* Dont run .INTERRUPT target then exit */
@@ -690,7 +693,6 @@ JobPrintCommand(void *cmdp, void *jobp)
char *escCmd = NULL; /* Command with quotes/backticks escaped */
char *cmd = (char *)cmdp;
Job *job = (Job *)jobp;
- char *cp, *tmp;
int i, j;
noSpecials = NoExecute(job->node);
@@ -726,7 +728,6 @@ JobPrintCommand(void *cmdp, void *jobp)
shutUp = DEBUG(LOUD) ? FALSE : TRUE;
break;
case '-':
- job->flags |= JOB_IGNERR;
errOff = TRUE;
break;
case '+':
@@ -805,6 +806,7 @@ JobPrintCommand(void *cmdp, void *jobp)
* to ignore errors. Set cmdTemplate to use the weirdness
* instead of the simple "%s\n" template.
*/
+ job->flags |= JOB_IGNERR;
if (!(job->flags & JOB_SILENT) && !shutUp) {
if (commandShell->hasEchoCtl) {
DBPRINTF("%s\n", commandShell->echoOff);
@@ -862,11 +864,6 @@ JobPrintCommand(void *cmdp, void *jobp)
job->flags |= JOB_TRACED;
}
- if ((cp = Check_Cwd_Cmd(cmd)) != NULL) {
- DBPRINTF("test -d %s && ", cp);
- DBPRINTF("cd %s\n", cp);
- }
-
DBPRINTF(cmdTemplate, cmd);
free(cmdStart);
if (escCmd)
@@ -886,10 +883,6 @@ JobPrintCommand(void *cmdp, void *jobp)
if (shutUp && commandShell->hasEchoCtl) {
DBPRINTF("%s\n", commandShell->echoOn);
}
- if (cp != NULL) {
- DBPRINTF("test -d %s && ", cp);
- DBPRINTF("cd %s\n", Var_Value(".OBJDIR", VAR_GLOBAL, &tmp));
- }
return 0;
}
@@ -1149,7 +1142,8 @@ Job_Touch(GNode *gn, Boolean silent)
int streamID; /* ID of stream opened to do the touch */
struct utimbuf times; /* Times for utime() call */
- if (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC|OP_OPTIONAL|OP_PHONY)) {
+ if (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC|OP_OPTIONAL|
+ OP_SPECIAL|OP_PHONY)) {
/*
* .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets
* and, as such, shouldn't really be created.
@@ -1186,7 +1180,8 @@ Job_Touch(GNode *gn, Boolean silent)
*/
if (read(streamID, &c, 1) == 1) {
(void)lseek(streamID, (off_t)0, SEEK_SET);
- (void)write(streamID, &c, 1);
+ while (write(streamID, &c, 1) == -1 && errno == EAGAIN)
+ continue;
}
(void)close(streamID);
@@ -1241,7 +1236,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0);
if (p1)
free(p1);
- } else if (Dir_MTime(gn) == 0 && (gn->type & OP_SPECIAL) == 0) {
+ } else if (Dir_MTime(gn, 0) == 0 && (gn->type & OP_SPECIAL) == 0) {
/*
* The node wasn't the target of an operator we have no .DEFAULT
* rule to go on and the target doesn't already exist. There's
@@ -1252,8 +1247,10 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
static const char msg[] = ": don't know how to make";
if (gn->flags & FROM_DEPEND) {
- fprintf(stdout, "%s: ignoring stale %s for %s\n",
- progname, makeDependfile, gn->name);
+ if (!Job_RunTarget(".STALE", gn->fname))
+ fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n",
+ progname, gn->fname, gn->lineno, makeDependfile,
+ gn->name);
return TRUE;
}
@@ -1363,7 +1360,7 @@ JobExec(Job *job, char **argv)
(void)fcntl(0, F_SETFD, 0);
(void)lseek(0, (off_t)0, SEEK_SET);
- if (job->node->type & OP_MAKE) {
+ if (job->node->type & (OP_MAKE | OP_SUBMAKE)) {
/*
* Pass job token pipe to submakes.
*/
@@ -1396,11 +1393,15 @@ JobExec(Job *job, char **argv)
* we can kill it and all its descendants in one fell swoop,
* by killing its process family, but not commit suicide.
*/
-#if defined(SYSV)
+#if defined(HAVE_SETPGID)
+ (void)setpgid(0, getpid());
+#else
+#if defined(HAVE_SETSID)
/* XXX: dsl - I'm sure this should be setpgrp()... */
(void)setsid();
#else
- (void)setpgid(0, getpid());
+ (void)setpgrp(0, getpid());
+#endif
#endif
Var_ExportVars();
@@ -1607,6 +1608,9 @@ JobStart(GNode *gn, int flags)
#ifdef USE_META
if (useMeta) {
meta_job_start(job, gn);
+ if (Targ_Silent(gn)) { /* might have changed */
+ job->flags |= JOB_SILENT;
+ }
}
#endif
/*
@@ -1890,16 +1894,16 @@ end_loop:
(void)fflush(stdout);
}
}
- if (i < max - 1) {
- /* shift the remaining characters down */
- (void)memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
+ /*
+ * max is the last offset still in the buffer. Move any remaining
+ * characters to the start of the buffer and update the end marker
+ * curPos.
+ */
+ if (i < max) {
+ (void)memmove(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
job->curPos = max - (i + 1);
-
} else {
- /*
- * We have written everything out, so we just start over
- * from the start of the buffer. No copying. No nothing.
- */
+ assert(i == max);
job->curPos = 0;
}
}
@@ -2063,31 +2067,45 @@ Job_CatchOutput(void)
(void)fflush(stdout);
/* The first fd in the list is the job token pipe */
- nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
+ do {
+ nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
+ } while (nready < 0 && errno == EINTR);
- if (nready < 0 || readyfd(&childExitJob)) {
+ if (nready < 0)
+ Punt("poll: %s", strerror(errno));
+
+ if (nready > 0 && readyfd(&childExitJob)) {
char token = 0;
- nready -= 1;
- (void)read(childExitJob.inPipe, &token, 1);
- if (token == DO_JOB_RESUME[0])
- /* Complete relay requested from our SIGCONT handler */
- JobRestartJobs();
- Job_CatchChildren();
+ ssize_t count;
+ count = read(childExitJob.inPipe, &token, 1);
+ switch (count) {
+ case 0:
+ Punt("unexpected eof on token pipe");
+ case -1:
+ Punt("token pipe read: %s", strerror(errno));
+ case 1:
+ if (token == DO_JOB_RESUME[0])
+ /* Complete relay requested from our SIGCONT handler */
+ JobRestartJobs();
+ break;
+ default:
+ abort();
+ }
+ --nready;
}
- if (nready <= 0)
- return;
-
- if (wantToken && readyfd(&tokenWaitJob))
- nready--;
+ Job_CatchChildren();
+ if (nready == 0)
+ return;
for (i = 2; i < nfds; i++) {
if (!fds[i].revents)
continue;
job = jobfds[i];
- if (job->job_state != JOB_ST_RUNNING)
- continue;
- JobDoOutput(job, FALSE);
+ if (job->job_state == JOB_ST_RUNNING)
+ JobDoOutput(job, FALSE);
+ if (--nready == 0)
+ return;
}
}
@@ -2135,6 +2153,24 @@ Shell_Init(void)
if (commandShell->echo == NULL) {
commandShell->echo = "";
}
+ if (commandShell->hasErrCtl && *commandShell->exit) {
+ if (shellErrFlag &&
+ strcmp(commandShell->exit, &shellErrFlag[1]) != 0) {
+ free(shellErrFlag);
+ shellErrFlag = NULL;
+ }
+ if (!shellErrFlag) {
+ int n = strlen(commandShell->exit) + 2;
+
+ shellErrFlag = bmake_malloc(n);
+ if (shellErrFlag) {
+ snprintf(shellErrFlag, n, "-%s", commandShell->exit);
+ }
+ }
+ } else if (shellErrFlag) {
+ free(shellErrFlag);
+ shellErrFlag = NULL;
+ }
}
/*-
@@ -2178,8 +2214,7 @@ Job_SetPrefix(void)
void
Job_Init(void)
{
- GNode *begin; /* node for commands to do at the very start */
-
+ Job_SetPrefix();
/* Allocate space for all the job info */
job_table = bmake_malloc(maxJobs * sizeof *job_table);
memset(job_table, 0, maxJobs * sizeof *job_table);
@@ -2191,16 +2226,6 @@ Job_Init(void)
lastNode = NULL;
- if (maxJobs == 1) {
- /*
- * If only one job can run at a time, there's no need for a banner,
- * is there?
- */
- targFmt = "";
- } else {
- targFmt = TARG_FMT;
- }
-
/*
* There is a non-zero chance that we already have children.
* eg after 'make -f- <<EOF'
@@ -2265,15 +2290,7 @@ Job_Init(void)
ADDSIG(SIGCONT, JobContinueSig)
#undef ADDSIG
- begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
-
- if (begin != NULL) {
- JobRun(begin);
- if (begin->made == ERROR) {
- PrintOnError(begin, "\n\nStop.");
- exit(1);
- }
- }
+ (void)Job_RunTarget(".BEGIN", NULL);
postCommands = Targ_FindNode(".END", TARG_CREATE);
}
@@ -2445,7 +2462,7 @@ Job_ParseShell(char *line)
* If no path was given, the user wants one of the pre-defined shells,
* yes? So we find the one s/he wants with the help of JobMatchShell
* and set things up the right way. shellPath will be set up by
- * Job_Init.
+ * Shell_Init.
*/
if (newShell.name == NULL) {
Parse_Error(PARSE_FATAL, "Neither path nor name specified");
@@ -2460,6 +2477,12 @@ Job_ParseShell(char *line)
}
commandShell = sh;
shellName = newShell.name;
+ if (shellPath) {
+ /* Shell_Init has already been called! Do it again. */
+ free(UNCONST(shellPath));
+ shellPath = NULL;
+ Shell_Init();
+ }
}
} else {
/*
@@ -2493,6 +2516,8 @@ Job_ParseShell(char *line)
commandShell = bmake_malloc(sizeof(Shell));
*commandShell = newShell;
}
+ /* this will take care of shellErrFlag */
+ Shell_Init();
}
if (commandShell->echoOn && commandShell->echoOff) {
@@ -2803,7 +2828,8 @@ JobTokenAdd(void)
if (DEBUG(JOB))
fprintf(debug_file, "(%d) aborting %d, deposit token %c\n",
getpid(), aborting, JOB_TOKENS[aborting]);
- write(tokenWaitJob.outPipe, &tok, 1);
+ while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
+ continue;
}
/*-
@@ -2824,6 +2850,8 @@ Job_ServerStart(int max_tokens, int jp_0, int jp_1)
/* Pipe passed in from parent */
tokenWaitJob.inPipe = jp_0;
tokenWaitJob.outPipe = jp_1;
+ (void)fcntl(jp_0, F_SETFD, 1);
+ (void)fcntl(jp_1, F_SETFD, 1);
return;
}
@@ -2916,13 +2944,15 @@ Job_TokenWithdraw(void)
while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
continue;
/* And put the stopper back */
- write(tokenWaitJob.outPipe, &tok, 1);
+ while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
+ continue;
Fatal("A failure has been detected in another branch of the parallel make");
}
if (count == 1 && jobTokensRunning == 0)
/* We didn't want the token really */
- write(tokenWaitJob.outPipe, &tok, 1);
+ while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
+ continue;
jobTokensRunning++;
if (DEBUG(JOB))
@@ -2930,6 +2960,38 @@ Job_TokenWithdraw(void)
return TRUE;
}
+/*-
+ *-----------------------------------------------------------------------
+ * Job_RunTarget --
+ * Run the named target if found. If a filename is specified, then
+ * set that to the sources.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * exits if the target fails.
+ *
+ *-----------------------------------------------------------------------
+ */
+Boolean
+Job_RunTarget(const char *target, const char *fname) {
+ GNode *gn = Targ_FindNode(target, TARG_NOCREATE);
+
+ if (gn == NULL)
+ return FALSE;
+
+ if (fname)
+ Var_Set(ALLSRC, fname, gn, 0);
+
+ JobRun(gn);
+ if (gn->made == ERROR) {
+ PrintOnError(gn, "\n\nStop.");
+ exit(1);
+ }
+ return TRUE;
+}
+
#ifdef USE_SELECT
int
emul_poll(struct pollfd *fd, int nfd, int timeout)
diff --git a/devel/bmake/files/job.h b/devel/bmake/files/job.h
index b3e7e26c58e..fa4dbe4aa22 100644
--- a/devel/bmake/files/job.h
+++ b/devel/bmake/files/job.h
@@ -1,4 +1,4 @@
-/* $NetBSD: job.h,v 1.1.1.5 2011/06/18 22:17:58 bsiegert Exp $ */
+/* $NetBSD: job.h,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -243,6 +243,7 @@ typedef struct Shell {
extern const char *shellPath;
extern const char *shellName;
+extern char *shellErrFlag;
extern int jobTokensRunning; /* tokens currently "out" */
extern int maxJobs; /* Max jobs we can run */
@@ -268,5 +269,6 @@ void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int);
void Job_SetPrefix(void);
+Boolean Job_RunTarget(const char *, const char *);
#endif /* _JOB_H_ */
diff --git a/devel/bmake/files/lst.h b/devel/bmake/files/lst.h
index 2778bcc89ef..1994af1e824 100644
--- a/devel/bmake/files/lst.h
+++ b/devel/bmake/files/lst.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lst.h,v 1.1.1.4 2009/09/18 20:55:27 joerg Exp $ */
+/* $NetBSD: lst.h,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
diff --git a/devel/bmake/files/lst.lib/lstInt.h b/devel/bmake/files/lst.lib/lstInt.h
index 4eb873fc2f2..18660acf6b8 100644
--- a/devel/bmake/files/lst.lib/lstInt.h
+++ b/devel/bmake/files/lst.lib/lstInt.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lstInt.h,v 1.1.1.5 2009/09/18 20:55:33 joerg Exp $ */
+/* $NetBSD: lstInt.h,v 1.1.1.6 2015/05/19 21:36:45 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
diff --git a/devel/bmake/files/lst.lib/lstMember.c b/devel/bmake/files/lst.lib/lstMember.c
index 928ae2778ac..31535aed9d0 100644
--- a/devel/bmake/files/lst.lib/lstMember.c
+++ b/devel/bmake/files/lst.lib/lstMember.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lstMember.c,v 1.1.1.4 2009/09/18 20:55:33 joerg Exp $ */
+/* $NetBSD: lstMember.c,v 1.1.1.5 2015/05/19 21:36:45 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -33,14 +33,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstMember.c,v 1.1.1.4 2009/09/18 20:55:33 joerg Exp $";
+static char rcsid[] = "$NetBSD: lstMember.c,v 1.1.1.5 2015/05/19 21:36:45 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: lstMember.c,v 1.1.1.4 2009/09/18 20:55:33 joerg Exp $");
+__RCSID("$NetBSD: lstMember.c,v 1.1.1.5 2015/05/19 21:36:45 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -58,6 +58,9 @@ Lst_Member(Lst l, void *d)
List list = l;
ListNode lNode;
+ if (list == NULL) {
+ return NULL;
+ }
lNode = list->firstPtr;
if (lNode == NULL) {
return NULL;
diff --git a/devel/bmake/files/lst.lib/lstRemove.c b/devel/bmake/files/lst.lib/lstRemove.c
index 6a5a0858711..d6e3ac0edcf 100644
--- a/devel/bmake/files/lst.lib/lstRemove.c
+++ b/devel/bmake/files/lst.lib/lstRemove.c
@@ -1,4 +1,4 @@
-/* $NetBSD: lstRemove.c,v 1.1.1.4 2009/09/18 20:55:34 joerg Exp $ */
+/* $NetBSD: lstRemove.c,v 1.1.1.5 2015/05/19 21:36:45 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -33,14 +33,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: lstRemove.c,v 1.1.1.4 2009/09/18 20:55:34 joerg Exp $";
+static char rcsid[] = "$NetBSD: lstRemove.c,v 1.1.1.5 2015/05/19 21:36:45 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: lstRemove.c,v 1.1.1.4 2009/09/18 20:55:34 joerg Exp $");
+__RCSID("$NetBSD: lstRemove.c,v 1.1.1.5 2015/05/19 21:36:45 joerg Exp $");
#endif
#endif /* not lint */
#endif
diff --git a/devel/bmake/files/machine.sh b/devel/bmake/files/machine.sh
index 1f267b092ad..ecc269cc4e2 100755
--- a/devel/bmake/files/machine.sh
+++ b/devel/bmake/files/machine.sh
@@ -2,7 +2,7 @@
# derrived from /etc/rc_d/os.sh
# RCSid:
-# $Id: machine.sh,v 1.1.1.4 2011/06/18 22:17:59 bsiegert Exp $
+# $Id: machine.sh,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $
#
# @(#) Copyright (c) 1994-2002 Simon J. Gerraty
#
@@ -49,6 +49,10 @@ OpenBSD)
arch=`Which arch /usr/bin:/usr/ucb:$PATH`
MACHINE_ARCH=`$arch -s`;
;;
+Bitrig)
+ MACHINE=$OS$OSMAJOR.$machine
+ MACHINE_ARCH=`uname -m`;
+ ;;
*BSD)
MACHINE=$OS$OSMAJOR.$machine
;;
diff --git a/devel/bmake/files/main.c b/devel/bmake/files/main.c
index 0a8420f59f4..36ac02ced02 100644
--- a/devel/bmake/files/main.c
+++ b/devel/bmake/files/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $ */
+/* $NetBSD: main.c,v 1.1.1.11 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.1.1.11 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $");
+__RCSID("$NetBSD: main.c,v 1.1.1.11 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -99,14 +99,14 @@ __RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $");
*
* Error Print a tagged error message. The global
* MAKE variable must have been defined. This
- * takes a format string and two optional
- * arguments for it.
+ * takes a format string and optional arguments
+ * for it.
*
* Fatal Print an error message and exit. Also takes
- * a format string and two arguments.
+ * a format string and arguments for it.
*
* Punt Aborts all jobs and exits with a message. Also
- * takes a format string and two arguments.
+ * takes a format string and arguments for it.
*
* Finish Finish things up by printing the number of
* errors which occurred, as passed to it, and
@@ -117,19 +117,21 @@ __RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $");
#include <sys/time.h>
#include <sys/param.h>
#include <sys/resource.h>
-#include <signal.h>
#include <sys/stat.h>
-#ifdef MAKE_NATIVE
-#include <sys/utsname.h>
+#if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL)
+#include <sys/sysctl.h>
#endif
+#include <sys/utsname.h>
#include "wait.h"
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
+#include <ctype.h>
#include "make.h"
#include "hash.h"
@@ -146,6 +148,10 @@ __RCSID("$NetBSD: main.c,v 1.1.1.10 2011/06/18 22:18:00 bsiegert Exp $");
#define DEFMAXLOCAL DEFMAXJOBS
#endif /* DEFMAXLOCAL */
+#ifndef __arraycount
+# define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
+#endif
+
Lst create; /* Targets to be made */
time_t now; /* Time at start of make */
GNode *DEFAULT; /* .DEFAULT node */
@@ -159,11 +165,13 @@ int maxJobs; /* -j argument */
static int maxJobTokens; /* -j argument */
Boolean compatMake; /* -B argument */
int debug; /* -d argument */
+Boolean debugVflag; /* -dV */
Boolean noExecute; /* -n flag */
Boolean noRecursiveExecute; /* -N flag */
Boolean keepgoing; /* -k flag */
Boolean queryFlag; /* -q flag */
Boolean touchFlag; /* -t flag */
+Boolean enterFlag; /* -w flag */
Boolean ignoreErrors; /* -i flag */
Boolean beSilent; /* -s flag */
Boolean oldVars; /* variable substitution style */
@@ -175,12 +183,9 @@ Boolean varNoExportEnv; /* -X flag */
Boolean doing_depend; /* Set while reading .depend */
static Boolean jobsRunning; /* TRUE if the jobs might be running */
static const char * tracefile;
-#ifndef NO_CHECK_MAKE_CHDIR
-static char * Check_Cwd_av(int, char **, int);
-#endif
static void MainParseArgs(int, char **);
static int ReadMakefile(const void *, const void *);
-static void usage(void);
+static void usage(void) MAKE_ATTR_DEAD;
static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
@@ -188,6 +193,7 @@ char curdir[MAXPATHLEN + 1]; /* Startup directory */
char *progname; /* the program name */
char *makeDependfile;
pid_t myPid;
+int makelevel;
Boolean forceJobs = FALSE;
@@ -202,6 +208,38 @@ Boolean forceJobs = FALSE;
extern Lst parseIncPath;
+/*
+ * For compatibility with the POSIX version of MAKEFLAGS that includes
+ * all the options with out -, convert flags to -f -l -a -g -s.
+ */
+static char *
+explode(const char *flags)
+{
+ size_t len;
+ char *nf, *st;
+ const char *f;
+
+ if (flags == NULL)
+ return NULL;
+
+ for (f = flags; *f; f++)
+ if (!isalpha((unsigned char)*f))
+ break;
+
+ if (*f)
+ return bmake_strdup(flags);
+
+ len = strlen(flags);
+ st = nf = bmake_malloc(len * 3 + 1);
+ while (*flags) {
+ *nf++ = '-';
+ *nf++ = *flags++;
+ *nf++ = ' ';
+ }
+ *nf = '\0';
+ return st;
+}
+
static void
parse_debug_options(const char *argvalue)
{
@@ -271,6 +309,9 @@ parse_debug_options(const char *argvalue)
case 't':
debug |= DEBUG_TARG;
break;
+ case 'V':
+ debugVflag = TRUE;
+ break;
case 'v':
debug |= DEBUG_VAR;
break;
@@ -280,9 +321,10 @@ parse_debug_options(const char *argvalue)
case 'F':
if (debug_file != stdout && debug_file != stderr)
fclose(debug_file);
- if (*++modules == '+')
+ if (*++modules == '+') {
+ modules++;
mode = "a";
- else
+ } else
mode = "w";
if (strcmp(modules, "stdout") == 0) {
debug_file = stdout;
@@ -350,7 +392,7 @@ MainParseArgs(int argc, char **argv)
Boolean inOption, dashDash = FALSE;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
-#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst"
+#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw"
/* Can't actually use getopt(3) because rescanning is not portable */
getopt_def = OPTFLAGS;
@@ -558,6 +600,10 @@ rearg:
touchFlag = TRUE;
Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
break;
+ case 'w':
+ enterFlag = TRUE;
+ Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
+ break;
case '-':
dashDash = TRUE;
break;
@@ -735,7 +781,7 @@ str2Lst_Append(Lst lp, char *str, const char *sep)
#ifdef SIGINFO
/*ARGSUSED*/
static void
-siginfo(int signo __unused)
+siginfo(int signo MAKE_ATTR_UNUSED)
{
char dir[MAXPATHLEN];
char str[2 * MAXPATHLEN];
@@ -766,7 +812,7 @@ MakeMode(const char *mode)
}
#if USE_META
if (strstr(mode, "meta"))
- meta_init(mode);
+ meta_mode_init(mode);
#endif
}
if (mp)
@@ -796,7 +842,7 @@ main(int argc, char **argv)
Lst targs; /* target nodes to create -- passed to Make_Init */
Boolean outOfDate = FALSE; /* FALSE if all targets up to date */
struct stat sb, sa;
- char *p1, *path, *pwd;
+ char *p1, *path;
char mdpath[MAXPATHLEN];
#ifdef FORCE_MACHINE
const char *machine = FORCE_MACHINE;
@@ -811,9 +857,7 @@ main(int argc, char **argv)
static char defsyspath[] = _PATH_DEFSYSPATH;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
struct timeval rightnow; /* to initialize random seed */
-#ifdef MAKE_NATIVE
struct utsname utsname;
-#endif
/* default to writing debug to stderr */
debug_file = stderr;
@@ -832,7 +876,7 @@ main(int argc, char **argv)
progname++;
else
progname = argv[0];
-#ifdef RLIMIT_NOFILE
+#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
/*
* get rid of resource limit on file descriptors
*/
@@ -846,6 +890,12 @@ main(int argc, char **argv)
}
#endif
+ if (uname(&utsname) == -1) {
+ (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
+ strerror(errno));
+ exit(2);
+ }
+
/*
* Get the name of this type of MACHINE from utsname
* so we can share an executable for similar machines.
@@ -856,11 +906,6 @@ main(int argc, char **argv)
*/
if (!machine) {
#ifdef MAKE_NATIVE
- if (uname(&utsname) == -1) {
- (void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
- strerror(errno));
- exit(2);
- }
machine = utsname.machine;
#else
#ifdef MAKE_MACHINE
@@ -872,6 +917,20 @@ main(int argc, char **argv)
}
if (!machine_arch) {
+#if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL) && defined(CTL_HW) && defined(HW_MACHINE_ARCH)
+ static char machine_arch_buf[sizeof(utsname.machine)];
+ int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
+ size_t len = sizeof(machine_arch_buf);
+
+ if (sysctl(mib, __arraycount(mib), machine_arch_buf,
+ &len, NULL, 0) < 0) {
+ (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
+ strerror(errno));
+ exit(2);
+ }
+
+ machine_arch = machine_arch_buf;
+#else
#ifndef MACHINE_ARCH
#ifdef MAKE_MACHINE_ARCH
machine_arch = MAKE_MACHINE_ARCH;
@@ -881,6 +940,7 @@ main(int argc, char **argv)
#else
machine_arch = MACHINE_ARCH;
#endif
+#endif
}
myPid = getpid(); /* remember this for vFork() */
@@ -890,6 +950,7 @@ main(int argc, char **argv)
*/
Var_Init(); /* Initialize the lists of variables for
* parsing arguments */
+ Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0);
Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
#ifdef MAKE_VERSION
@@ -909,6 +970,7 @@ main(int argc, char **argv)
create = Lst_Init(FALSE);
makefiles = Lst_Init(FALSE);
printVars = FALSE;
+ debugVflag = FALSE;
variables = Lst_Init(FALSE);
beSilent = FALSE; /* Print commands as executed */
ignoreErrors = FALSE; /* Pay attention to non-zero returns */
@@ -962,32 +1024,43 @@ main(int argc, char **argv)
Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
+ /* some makefiles need to know this */
+ Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMD, 0);
/*
* Set some other useful macros
*/
{
- char tmp[64];
- const char *ep;
+ char tmp[64], *ep;
- if (!(ep = getenv(MAKE_LEVEL))) {
- ep = "0";
- }
- Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
+ makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0;
+ if (makelevel < 0)
+ makelevel = 0;
+ snprintf(tmp, sizeof(tmp), "%d", makelevel);
+ Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL, 0);
snprintf(tmp, sizeof(tmp), "%u", myPid);
Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
snprintf(tmp, sizeof(tmp), "%u", getppid());
Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
}
- Job_SetPrefix();
+ if (makelevel > 0) {
+ char pn[1024];
+ snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel);
+ progname = bmake_strdup(pn);
+ }
+#ifdef USE_META
+ meta_init();
+#endif
/*
* First snag any flags out of the MAKE environment variable.
* (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
* in a different format).
*/
#ifdef POSIX
- Main_ParseArgLine(getenv("MAKEFLAGS"));
+ p1 = explode(getenv("MAKEFLAGS"));
+ Main_ParseArgLine(p1);
+ free(p1);
#else
Main_ParseArgLine(getenv("MAKE"));
#endif
@@ -1004,6 +1077,9 @@ main(int argc, char **argv)
MainParseArgs(argc, argv);
+ if (enterFlag)
+ printf("%s: Entering directory `%s'\n", progname, curdir);
+
/*
* Verify that cwd is sane.
*/
@@ -1025,16 +1101,23 @@ main(int argc, char **argv)
* MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
*/
#ifndef NO_PWD_OVERRIDE
- if (!ignorePWD &&
- (pwd = getenv("PWD")) != NULL &&
- getenv("MAKEOBJDIRPREFIX") == NULL) {
- const char *makeobjdir = getenv("MAKEOBJDIR");
-
- if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
- if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
- sa.st_dev == sb.st_dev)
- (void)strncpy(curdir, pwd, MAXPATHLEN);
+ if (!ignorePWD) {
+ char *pwd, *ptmp1 = NULL, *ptmp2 = NULL;
+
+ if ((pwd = getenv("PWD")) != NULL &&
+ Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &ptmp1) == NULL) {
+ const char *makeobjdir = Var_Value("MAKEOBJDIR",
+ VAR_CMD, &ptmp2);
+
+ if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
+ if (stat(pwd, &sb) == 0 &&
+ sa.st_ino == sb.st_ino &&
+ sa.st_dev == sb.st_dev)
+ (void)strncpy(curdir, pwd, MAXPATHLEN);
+ }
}
+ free(ptmp1);
+ free(ptmp2);
}
#endif
Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
@@ -1051,11 +1134,13 @@ main(int argc, char **argv)
Dir_Init(curdir);
(void)Main_SetObjdir(curdir);
- if ((path = getenv("MAKEOBJDIRPREFIX")) != NULL) {
+ if ((path = Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &p1)) != NULL) {
(void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir);
(void)Main_SetObjdir(mdpath);
- } else if ((path = getenv("MAKEOBJDIR")) != NULL) {
+ free(p1);
+ } else if ((path = Var_Value("MAKEOBJDIR", VAR_CMD, &p1)) != NULL) {
(void)Main_SetObjdir(path);
+ free(p1);
} else {
(void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine);
if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) {
@@ -1195,10 +1280,6 @@ main(int argc, char **argv)
Main_ExportMAKEFLAGS(TRUE); /* initial export */
-#ifndef NO_CHECK_MAKE_CHDIR
- Check_Cwd_av(0, NULL, 0); /* initialize it */
-#endif
-
/*
* For compatibility, look at the directories in the VPATH variable
* and add them to the search path, if the variable is defined. The
@@ -1249,7 +1330,12 @@ main(int argc, char **argv)
/* print the values of any variables requested by the user */
if (printVars) {
LstNode ln;
+ Boolean expandVars;
+ if (debugVflag)
+ expandVars = FALSE;
+ else
+ expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
for (ln = Lst_First(variables); ln != NULL;
ln = Lst_Succ(ln)) {
char *var = (char *)Lst_Datum(ln);
@@ -1257,6 +1343,13 @@ main(int argc, char **argv)
if (strchr(var, '$')) {
value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0);
+ } else if (expandVars) {
+ char tmp[128];
+
+ if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp)))
+ Fatal("%s: variable name too big: %s",
+ progname, var);
+ value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
} else {
value = Var_Value(var, VAR_GLOBAL, &p1);
}
@@ -1313,6 +1406,9 @@ main(int argc, char **argv)
Trace_Log(MAKEEND, 0);
+ if (enterFlag)
+ printf("%s: Leaving directory `%s'\n", progname, curdir);
+
Suff_End();
Targ_End();
Arch_End();
@@ -1336,7 +1432,7 @@ main(int argc, char **argv)
* lots
*/
static int
-ReadMakefile(const void *p, const void *q __unused)
+ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
{
const char *fname = p; /* makefile to read */
int fd;
@@ -1345,7 +1441,7 @@ ReadMakefile(const void *p, const void *q __unused)
if (!strcmp(fname, "-")) {
Parse_File(NULL /*stdin*/, -1);
- Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
+ Var_Set("MAKEFILE", "", VAR_INTERNAL, 0);
} else {
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
@@ -1394,7 +1490,7 @@ ReadMakefile(const void *p, const void *q __unused)
*/
found:
if (!doing_depend)
- Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
+ Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0);
Parse_File(fname, fd);
}
free(path);
@@ -1402,208 +1498,6 @@ found:
}
-/*
- * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
- * in situations that would not arrise with ./obj (links or not).
- * This tends to break things like:
- *
- * build:
- * ${MAKE} includes
- *
- * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
- * opposed to an argument) in a command line and if so returns
- * ${.CURDIR} so caller can chdir() so that the assumptions made by
- * the Makefile hold true.
- *
- * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
- *
- * The chdir() only happens in the child process, and does nothing if
- * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
- * should not break anything. Also if NOCHECKMAKECHDIR is set we
- * do nothing - to ensure historic semantics can be retained.
- */
-#ifdef NO_CHECK_MAKE_CHDIR
-char *
-Check_Cwd_Cmd(cmd)
- char *cmd;
-{
- return 0;
-}
-
-void
-Check_Cwd(argv)
- char **argv;
-{
- return;
-}
-
-#else
-
-static int Check_Cwd_Off = 0;
-
-static char *
-Check_Cwd_av(int ac, char **av, int copy)
-{
- static char *make[4];
- static char *cur_dir = NULL;
- char **mp;
- char *cp;
- int is_cmd, next_cmd;
- int i;
- int n;
-
- if (Check_Cwd_Off) {
- if (DEBUG(CWD))
- fprintf(debug_file, "check_cwd: check is off.\n");
- return NULL;
- }
-
- if (make[0] == NULL) {
- if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
- Check_Cwd_Off = 1;
- if (DEBUG(CWD))
- fprintf(debug_file, "check_cwd: turning check off.\n");
- return NULL;
- }
-
- make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
- if ((make[0] = strrchr(make[1], '/')) == NULL) {
- make[0] = make[1];
- make[1] = NULL;
- } else
- ++make[0];
- make[2] = NULL;
- cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
- }
- if (ac == 0 || av == NULL) {
- if (DEBUG(CWD))
- fprintf(debug_file, "check_cwd: empty command.\n");
- return NULL; /* initialization only */
- }
-
- if (getenv("MAKEOBJDIR") == NULL &&
- getenv("MAKEOBJDIRPREFIX") == NULL) {
- if (DEBUG(CWD))
- fprintf(debug_file, "check_cwd: no obj dirs.\n");
- return NULL;
- }
-
-
- next_cmd = 1;
- for (i = 0; i < ac; ++i) {
- is_cmd = next_cmd;
-
- n = strlen(av[i]);
- cp = &(av[i])[n - 1];
- if (strspn(av[i], "|&;") == (size_t)n) {
- next_cmd = 1;
- continue;
- } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
- next_cmd = 1;
- if (copy) {
- do {
- *cp-- = '\0';
- } while (*cp == ';' || *cp == '&' || *cp == '|' ||
- *cp == ')' || *cp == '}') ;
- } else {
- /*
- * XXX this should not happen.
- */
- fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n",
- progname, av[i]);
- }
- } else
- next_cmd = 0;
-
- cp = av[i];
- if (*cp == ';' || *cp == '&' || *cp == '|')
- is_cmd = 1;
-
- if (DEBUG(CWD))
- fprintf(debug_file, "av[%d] == %s '%s'",
- i, (is_cmd) ? "cmd" : "arg", av[i]);
- if (is_cmd != 0) {
- if (*cp == '(' || *cp == '{' ||
- *cp == ';' || *cp == '&' || *cp == '|') {
- do {
- ++cp;
- } while (*cp == '(' || *cp == '{' ||
- *cp == ';' || *cp == '&' || *cp == '|');
- if (*cp == '\0') {
- next_cmd = 1;
- continue;
- }
- }
- if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
- if (DEBUG(CWD))
- fprintf(debug_file, " == cd, done.\n");
- return NULL;
- }
- for (mp = make; *mp != NULL; ++mp) {
- n = strlen(*mp);
- if (strcmp(cp, *mp) == 0) {
- if (DEBUG(CWD))
- fprintf(debug_file, " %s == '%s', chdir(%s)\n",
- cp, *mp, cur_dir);
- return cur_dir;
- }
- }
- }
- if (DEBUG(CWD))
- fprintf(debug_file, "\n");
- }
- return NULL;
-}
-
-char *
-Check_Cwd_Cmd(const char *cmd)
-{
- char *cp, *bp;
- char **av;
- int ac;
-
- if (Check_Cwd_Off)
- return NULL;
-
- if (cmd) {
- av = brk_string(cmd, &ac, TRUE, &bp);
- if (DEBUG(CWD))
- fprintf(debug_file, "splitting: '%s' -> %d words\n",
- cmd, ac);
- } else {
- ac = 0;
- av = NULL;
- bp = NULL;
- }
- cp = Check_Cwd_av(ac, av, 1);
- if (bp)
- free(bp);
- if (av)
- free(av);
- return cp;
-}
-
-void
-Check_Cwd(const char **argv)
-{
- char *cp;
- int ac;
-
- if (Check_Cwd_Off)
- return;
-
- for (ac = 0; argv[ac] != NULL; ++ac)
- /* NOTHING */;
- if (ac == 3 && *argv[1] == '-') {
- cp = Check_Cwd_Cmd(argv[2]);
- } else {
- cp = Check_Cwd_av(ac, UNCONST(argv), 0);
- }
- if (cp) {
- chdir(cp);
- }
-}
-#endif /* NO_CHECK_MAKE_CHDIR */
/*-
* Cmd_Exec --
@@ -1628,7 +1522,8 @@ Cmd_Exec(const char *cmd, const char **errnum)
WAIT_T status; /* command exit status */
Buffer buf; /* buffer to store the result */
char *cp;
- int cc;
+ int cc; /* bytes read, or -1 */
+ int savederr; /* saved errno */
*errnum = NULL;
@@ -1685,6 +1580,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
*/
(void)close(fds[1]);
+ savederr = 0;
Buf_Init(&buf, 0);
do {
@@ -1694,6 +1590,8 @@ Cmd_Exec(const char *cmd, const char **errnum)
Buf_AddBytes(&buf, cc, result);
}
while (cc > 0 || (cc == -1 && errno == EINTR));
+ if (cc == -1)
+ savederr = errno;
/*
* Close the input side of the pipe.
@@ -1710,7 +1608,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
cc = Buf_Size(&buf);
res = Buf_Destroy(&buf, FALSE);
- if (cc == 0)
+ if (savederr != 0)
*errnum = "Couldn't read shell's output for \"%s\"";
if (WIFSIGNALED(status))
@@ -1885,7 +1783,7 @@ Finish(int errors)
}
/*
- * enunlink --
+ * eunlink --
* Remove a file carefully, avoiding directories.
*/
int
@@ -1931,7 +1829,8 @@ execError(const char *af, const char *av)
IOADD(")\n");
#ifdef USE_IOVEC
- (void)writev(2, iov, 8);
+ while (writev(2, iov, 8) == -1 && errno == EAGAIN)
+ continue;
#endif
}
@@ -1942,8 +1841,12 @@ execError(const char *af, const char *av)
static void
usage(void)
{
+ char *p;
+ if ((p = strchr(progname, '[')) != NULL)
+ *p = '\0';
+
(void)fprintf(stderr,
-"usage: %s [-BeikNnqrstWX] \n\
+"usage: %s [-BeikNnqrstWwX] \n\
[-C directory] [-D variable] [-d flags] [-f makefile]\n\
[-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
[-V variable] [variable=value] [target ...]\n", progname);
@@ -2072,3 +1975,49 @@ mkTempFile(const char *pattern, char **fnamep)
}
return fd;
}
+
+
+/*
+ * Return a Boolean based on setting of a knob.
+ *
+ * If the knob is not set, the supplied default is the return value.
+ * If set, anything that looks or smells like "No", "False", "Off", "0" etc,
+ * is FALSE, otherwise TRUE.
+ */
+Boolean
+getBoolean(const char *name, Boolean bf)
+{
+ char tmp[64];
+ char *cp;
+
+ if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) {
+ cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+
+ if (cp) {
+ switch(*cp) {
+ case '\0': /* not set - the default wins */
+ break;
+ case '0':
+ case 'f':
+ case 'n':
+ bf = FALSE;
+ break;
+ case 'o':
+ switch (cp[1]) {
+ case 'f':
+ bf = FALSE;
+ break;
+ default:
+ bf = TRUE;
+ break;
+ }
+ break;
+ default:
+ bf = TRUE;
+ break;
+ }
+ free(cp);
+ }
+ }
+ return (bf);
+}
diff --git a/devel/bmake/files/make-bootstrap.sh.in b/devel/bmake/files/make-bootstrap.sh.in
index 07942d6f87e..2bb4c25a705 100644
--- a/devel/bmake/files/make-bootstrap.sh.in
+++ b/devel/bmake/files/make-bootstrap.sh.in
@@ -11,9 +11,9 @@ yes) XDEFS="-DUSE_META ${XDEFS}";;
esac
CC="@CC@"
-CFLAGS="@CFLAGS@ -I. -I${srcdir} @DEFS@ @CPPFLAGS@ -DMAKE_NATIVE ${XDEFS}"
+CFLAGS="@CFLAGS@ -I. -I${srcdir} @DEFS@ @CPPFLAGS@ -DMAKE_NATIVE ${XDEFS} -DBMAKE_PATH_MAX=@bmake_path_max@"
-MAKE_VERSION=`sed -n '/^MAKE_VERSION=/s,.*=[^0-9]*,,p' Makefile`
+MAKE_VERSION=`sed -n '/^MAKE_VERSION=/s,.*=[^0-9]*,,p' $srcdir/Makefile`
MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \
-D@force_machine@MACHINE=\"@machine@\" -DMACHINE_ARCH=\"@machine_arch@\" \
@@ -47,8 +47,8 @@ do_compile() {
do_link() {
output="$1"; shift
- echo ${CC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
- ${CC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
+ echo ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
+ ${CC} ${LDSTATIC} ${LDFLAGS} -o "$output" "$@" ${LIBS}
}
BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \
diff --git a/devel/bmake/files/make-conf.h b/devel/bmake/files/make-conf.h
index 732903a7122..0d433e7b26c 100644
--- a/devel/bmake/files/make-conf.h
+++ b/devel/bmake/files/make-conf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make-conf.h,v 1.1.1.4 2009/09/18 20:55:23 joerg Exp $ */
+/* $NetBSD: make-conf.h,v 1.1.1.5 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -133,6 +133,12 @@
#define SYSVVARSUB
/*
+ * GMAKEEXPORT
+ * Recognize gmake like variable export directives [export <VAR>=<VALUE>]
+ */
+#define GMAKEEXPORT
+
+/*
* SUNSHCMD
* Recognize SunOS and Solaris:
* VAR :sh= CMD # Assign VAR to the command substitution of CMD
diff --git a/devel/bmake/files/make.1 b/devel/bmake/files/make.1
index 179f8e20668..5241ec12307 100644
--- a/devel/bmake/files/make.1
+++ b/devel/bmake/files/make.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.1.1.9 2011/06/18 22:18:01 bsiegert Exp $
+.\" $NetBSD: make.1,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd May 29, 2011
+.Dd April 9, 2015
.Dt MAKE 1
.Os
.Sh NAME
@@ -37,41 +37,19 @@
.Nd maintain program dependencies
.Sh SYNOPSIS
.Nm
-.Op Fl BeikNnqrstWX
-.Bk -words
+.Op Fl BeikNnqrstWwX
.Op Fl C Ar directory
-.Ek
-.Bk -words
.Op Fl D Ar variable
-.Ek
-.Bk -words
.Op Fl d Ar flags
-.Ek
-.Bk -words
.Op Fl f Ar makefile
-.Ek
-.Bk -words
.Op Fl I Ar directory
-.Ek
-.Bk -words
.Op Fl J Ar private
-.Ek
-.Bk -words
.Op Fl j Ar max_jobs
-.Ek
-.Bk -words
.Op Fl m Ar directory
-.Ek
-.Bk -words
.Op Fl T Ar file
-.Ek
-.Bk -words
.Op Fl V Ar variable
-.Ek
.Op Ar variable=value
-.Bk -words
.Op Ar target ...
-.Ek
.Sh DESCRIPTION
.Nm
is a program designed to simplify the maintenance of other programs.
@@ -95,7 +73,7 @@ This manual page is intended as a reference document only.
For a more thorough description of
.Nm
and makefiles, please refer to
-.%T "Make \- A Tutorial" .
+.%T "PMake \- A Tutorial" .
.Pp
.Nm
will prepend the contents of the
@@ -126,7 +104,7 @@ Turn on debugging, and specify which portions of
.Nm
are to print debugging information.
Unless the flags are preceded by
-.Ql -
+.Ql \-
they are added to the
.Va MAKEFLAGS
environment variable and will be processed by any child make processes.
@@ -225,6 +203,10 @@ Print debugging information about makefile parsing.
Print debugging information about suffix-transformation rules.
.It Ar t
Print debugging information about target list maintenance.
+.It Ar V
+Force the
+.Fl V
+option to print raw values of variables.
.It Ar v
Print debugging information about variable assignment.
.It Ar x
@@ -368,6 +350,8 @@ contains a
then the value will be expanded before printing.
.It Fl W
Treat any warnings during makefile parsing as errors.
+.It Fl w
+Print entering and leaving directory messages, pre and post processing.
.It Fl X
Don't export variables passed on the command line to the environment
individually.
@@ -457,17 +441,29 @@ The value
need not necessarily be used to describe existing files.
Expansion is in directory order, not alphabetically as done in the shell.
.Sh SHELL COMMANDS
-Each target may have associated with it a series of shell commands, normally
+Each target may have associated with it one or more lines of shell
+commands, normally
used to create the target.
-Each of the commands in this script
+Each of the lines in this script
.Em must
be preceded by a tab.
-While any target may appear on a dependency line, only one of these
-dependencies may be followed by a creation script, unless the
+(For historical reasons, spaces are not accepted.)
+While targets can appear in many dependency lines if desired, by
+default only one of these rules may be followed by a creation
+script.
+If the
.Ql Ic \&::
-operator is used.
+operator is used, however, all rules may include scripts and the
+scripts are executed in the order found.
.Pp
-If the first characters of the command line are any combination of
+Each line is treated as a separate shell command, unless the end of
+line is escaped with a backslash
+.Pq Ql \e
+in which case that line and the next are combined.
+.\" The escaped newline is retained and passed to the shell, which
+.\" normally ignores it.
+.\" However, the tab at the beginning of the following line is removed.
+If the first characters of the command are any combination of
.Ql Ic @ ,
.Ql Ic + ,
or
@@ -485,7 +481,63 @@ This is similar to the effect of the .MAKE special source,
except that the effect can be limited to a single line of a script.
A
.Ql Ic \-
+in compatibility mode
causes any non-zero exit status of the command line to be ignored.
+.Pp
+When
+.Nm
+is run in jobs mode with
+.Fl j Ar max_jobs ,
+the entire script for the target is fed to a
+single instance of the shell.
+In compatibility (non-jobs) mode, each command is run in a separate process.
+If the command contains any shell meta characters
+.Pq Ql #=|^(){};&<>*?[]:$`\e\en
+it will be passed to the shell; otherwise
+.Nm
+will attempt direct execution.
+If a line starts with
+.Ql Ic \-
+and the shell has ErrCtl enabled then failure of the command line
+will be ignored as in compatibility mode.
+Otherwise
+.Ql Ic \-
+affects the entire job;
+the script will stop at the first command line that fails,
+but the target will not be deemed to have failed.
+.Pp
+Makefiles should be written so that the mode of
+.Nm
+operation does not change their behavior.
+For example, any command which needs to use
+.Dq cd
+or
+.Dq chdir
+without potentially changing the directory for subsequent commands
+should be put in parentheses so it executes in a subshell.
+To force the use of one shell, escape the line breaks so as to make
+the whole script one command.
+For example:
+.Bd -literal -offset indent
+avoid-chdir-side-effects:
+ @echo Building $@ in `pwd`
+ @(cd ${.CURDIR} && ${MAKE} $@)
+ @echo Back in `pwd`
+
+ensure-one-shell-regardless-of-mode:
+ @echo Building $@ in `pwd`; \e
+ (cd ${.CURDIR} && ${MAKE} $@); \e
+ echo Back in `pwd`
+.Ed
+.Pp
+Since
+.Nm
+will
+.Xr chdir 2
+to
+.Ql Va .OBJDIR
+before executing any targets, each child process
+starts with that as its current working directory.
.Sh VARIABLE ASSIGNMENTS
Variables in make are much like variables in the shell, and, by tradition,
consist of all upper-case letters.
@@ -596,13 +648,19 @@ Variables defined in the makefile or in included makefiles.
Variables defined as part of the command line.
.It Local variables
Variables that are defined specific to a certain target.
+.El
+.Pp
+Local variables are all built in and their values vary magically from
+target to target.
+It is not currently possible to define new local variables.
The seven local variables are as follows:
-.Bl -tag -width ".ARCHIVE"
+.Bl -tag -width ".ARCHIVE" -offset indent
.It Va .ALLSRC
The list of all sources for this target; also known as
.Ql Va \&\*[Gt] .
.It Va .ARCHIVE
-The name of the archive file.
+The name of the archive file; also known as
+.Ql Va \&! .
.It Va .IMPSRC
In suffix-transformation rules, the name/path of the source from which the
target is to be transformed (the
@@ -611,7 +669,8 @@ source); also known as
.Ql Va \&\*[Lt] .
It is not defined in explicit rules.
.It Va .MEMBER
-The name of the archive member.
+The name of the archive member; also known as
+.Ql Va % .
.It Va .OODATE
The list of sources for this target that were deemed out-of-date; also
known as
@@ -620,31 +679,41 @@ known as
The file prefix of the target, containing only the file portion, no suffix
or preceding directory components; also known as
.Ql Va * .
+The suffix must be one of the known suffixes declared with
+.Ic .SUFFIXES
+or it will not be recognized.
.It Va .TARGET
The name of the target; also known as
.Ql Va @ .
.El
.Pp
The shorter forms
-.Ql Va @ ,
+.Ql ( Va \*[Gt] ,
+.Ql Va \&! ,
+.Ql Va \*[Lt] ,
+.Ql Va % ,
.Ql Va \&? ,
-.Ql Va \&\*[Lt] ,
-.Ql Va \&\*[Gt] ,
+.Ql Va * ,
and
-.Ql Va *
+.Ql Va @ )
are permitted for backward
-compatibility with historical makefiles and are not recommended.
-The six variables
-.Ql Va "@F" ,
-.Ql Va "@D" ,
-.Ql Va "\*[Lt]F" ,
-.Ql Va "\*[Lt]D" ,
-.Ql Va "*F" ,
+compatibility with historical makefiles and legacy POSIX make and are
+not recommended.
+.Pp
+Variants of these variables with the punctuation followed immediately by
+.Ql D
+or
+.Ql F ,
+e.g.
+.Ql Va $(@D) ,
+are legacy forms equivalent to using the
+.Ql :H
and
-.Ql Va "*D"
-are permitted for compatibility with
+.Ql :T
+modifiers.
+These forms are accepted for compatibility with
.At V
-makefiles and are not recommended.
+makefiles and POSIX but are not recommended.
.Pp
Four of the local variables may be used in sources on dependency lines
because they expand to the proper value for each target on the line.
@@ -654,7 +723,6 @@ These variables are
.Ql Va .ARCHIVE ,
and
.Ql Va .MEMBER .
-.El
.Ss Additional built-in variables
In addition,
.Nm
@@ -678,6 +746,10 @@ was executed.
Refer to the description of
.Ql Ev PWD
for more details.
+.It Va .INCLUDEDFROMDIR
+The directory of the file this Makefile was included from.
+.It Va .INCLUDEDFROMFILE
+The filename of the file this Makefile was included from.
.It Ev MAKE
The name that
.Nm
@@ -697,6 +769,10 @@ and cannot be confused with the special target with the same name.
Names the makefile (default
.Ql Pa .depend )
from which generated dependencies are read.
+.It Va .MAKE.EXPAND_VARIABLES
+A boolean that controls the default behavior of the
+.Fl V
+option.
.It Va .MAKE.EXPORTED
The list of variables exported by
.Nm .
@@ -713,6 +789,9 @@ then output for each target is prefixed with a token
.Ql --- target ---
the first part of which can be controlled via
.Va .MAKE.JOB.PREFIX .
+If
+.Va .MAKE.JOB.PREFIX
+is empty, no token is printed.
.br
For example:
.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
@@ -788,6 +867,9 @@ will not create .meta files in
This can be overridden by setting
.Va bf
to a value which represents True.
+.It Pa env
+For debugging, it can be useful to inlcude the environment
+in the .meta file.
.It Pa verbose
If in "meta" mode, print a clue about the target being built.
This is useful if the build is otherwise running silently.
@@ -799,6 +881,11 @@ This keyword causes them to be ignored for
determining whether a target is out of date in "meta" mode.
See also
.Ic .NOMETA_CMP .
+.It Pa silent= Ar bf
+If
+.Va bf
+is True, when a .meta file is created, mark the target
+.Ic .SILENT .
.El
.It Va .MAKE.META.BAILIWICK
In "meta" mode, provides a list of prefixes which
@@ -818,6 +905,11 @@ In "meta" mode, this variable contains a list of all the meta files
used (updated or not).
This list can be used to process the meta files to extract dependency
information.
+.It Va .MAKE.META.IGNORE_PATHS
+Provides a list of path prefixes that should be ignored;
+because the contents are expected to change over time.
+The default list includes:
+.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp
.It Va .MAKE.META.PREFIX
Defines the message printed for each meta file updated in "meta verbose" mode.
The default value is:
@@ -836,6 +928,13 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
is modified.
+.It Va .MAKE.PATH_FILEMON
+If
+.Nm
+was built with
+.Xr filemon 4
+support, this is set to the path of the device node.
+This allows makefiles to test for this support.
.It Va .MAKE.PID
The process-id of
.Nm .
@@ -918,6 +1017,9 @@ This variable and
are both set only while the
.Ql Pa Makefiles
are being parsed.
+If you want to retain their current values, assign them to a variable
+using assignment with expansion:
+.Pq Ql Cm \&:= .
.It Va .PATH
A variable that represents the list of directories that
.Nm
@@ -1008,6 +1110,13 @@ may
be used.
The wildcard characters may be escaped with a backslash
.Pq Ql \e .
+As a consequence of the way values are split into words, matched,
+and then joined, a construct like
+.Dl ${VAR:M*}
+will normalise the inter-word spacing, removing all leading and
+trailing space, and converting multiple consecutive spaces
+to single spaces.
+.
.It Cm \&:N Ns Ar pattern
This is identical to
.Ql Cm \&:M ,
@@ -1151,7 +1260,7 @@ The
modifier is just like the
.Cm \&:S
modifier except that the old and new strings, instead of being
-simple strings, are a regular expression (see
+simple strings, are an extended regular expression (see
.Xr regex 3 )
string
.Ar pattern
@@ -1181,6 +1290,15 @@ and
are orthogonal; the former specifies whether multiple words are
potentially affected, the latter whether multiple substitutions can
potentially occur within each affected word.
+.Pp
+As for the
+.Cm \&:S
+modifier, the
+.Ar pattern
+and
+.Ar replacement
+are subjected to variable expansion before being parsed as
+regular expressions.
.It Cm \&:T
Replaces each word in the variable with its last component.
.It Cm \&:u
@@ -1249,6 +1367,9 @@ The ODE convention is that
should start and end with a period.
For example.
.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+.Pp
+However a single character variable is often more readable:
+.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
.It Cm \&:U Ns Ar newval
If the variable is undefined
.Ar newval
@@ -1270,6 +1391,8 @@ The path of the node which has the same name as the variable
is the value.
If no such node exists or its path is null, then the
name of the variable is used.
+In order for this modifier to work, the name (node) must at least have
+appeared on the rhs of a dependency.
.Sm off
.It Cm \&:\&! Ar cmd Cm \&!
.Sm on
@@ -1330,7 +1453,7 @@ For the purposes of the
modifier, the words are indexed both forwards using positive integers
(where index 1 represents the first word),
and backwards using negative integers
-(where index -1 represents the last word).
+(where index \-1 represents the last word).
.Pp
The
.Ar range
@@ -1429,6 +1552,11 @@ except for internal variables (those that start with
This is not affected by the
.Fl X
flag, so should be used with caution.
+For compatibility with other
+.Nm
+programs
+.Ql export variable=value
+is also accepted.
.Pp
Appending a variable name to
.Va .MAKE.EXPORTED
@@ -1683,7 +1811,7 @@ or
.Fl t
options were specified.
Normally used to mark recursive
-.Nm Ns 's .
+.Nm Ns s .
.It Ic .META
Create a meta file for the target, even if it is flagged as
.Ic .PHONY ,
@@ -1693,6 +1821,7 @@ or
Usage in conjunction with
.Ic .MAKE
is the most likely case.
+In "meta" mode, the target is out-of-date if the meta file is missing.
.It Ic .NOMETA
Do not create a meta file for the target.
Meta files are also not created for
@@ -1705,6 +1834,20 @@ targets.
Ignore differences in commands when deciding if target is out of date.
This is useful if the command contains a value which always changes.
If the number of commands change, though, the target will still be out of date.
+The same effect applies to any command line that uses the variable
+.Va .OODATE ,
+which can be used for that purpose even when not otherwise needed or desired:
+.Bd -literal -offset indent
+
+skip-compare-for-some:
+ @echo this will be compared
+ @echo this will not ${.OODATE:M.NOMETA_CMP}
+ @echo this will also be compared
+
+.Ed
+The
+.Cm \&:M
+pattern suppresses any expansion of the unwanted variable.
.It Ic .NOPATH
Do not search for the target in the directories specified by
.Ic .PATH .
@@ -1888,6 +2031,12 @@ If the source is the special
.Ic .DOTLAST
target, then the current working
directory is searched last.
+.It Ic .PATH. Ns Va suffix
+Like
+.Ic .PATH
+but applies only to files with a particular suffix.
+The suffix must have been previously declared with
+.Ic .SUFFIXES .
.It Ic .PHONY
Apply the
.Ic .PHONY
@@ -1944,8 +2093,8 @@ character when used outside of any quoting characters.
Example:
.Bd -literal
\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
- check="set -e" ignore="set +e" \e
- echo="set -v" quiet="set +v" filter="set +v" \e
+ check="set \-e" ignore="set +e" \e
+ echo="set \-v" quiet="set +v" filter="set +v" \e
echoFlag=v errFlag=e newline="'\en'"
.Ed
.It Ic .SILENT
@@ -1956,6 +2105,10 @@ If no sources are specified, the
.Ic .SILENT
attribute is applied to every
command in the file.
+.It Ic .STALE
+This target gets run when a dependency file contains stale entries, having
+.Va .ALLSRC
+set to the name of that dependency file.
.It Ic .SUFFIXES
Each source specifies a suffix to
.Nm .
@@ -1966,7 +2119,7 @@ Example:
.Bd -literal
\&.SUFFIXES: .o
\&.c.o:
- cc -o ${.TARGET} -c ${.IMPSRC}
+ cc \-o ${.TARGET} \-c ${.IMPSRC}
.Ed
.El
.Sh ENVIRONMENT
@@ -2006,13 +2159,11 @@ system makefile
system makefile directory
.El
.Sh COMPATIBILITY
-The basic make syntax is compatible between different versions of make,
+The basic make syntax is compatible between different versions of make;
however the special variables, variable modifiers and conditionals are not.
-.Pp
-The way that parallel makes are scheduled changed in
-.Nx 4.0
-so that .ORDER and .WAIT apply recursively to the dependant nodes.
-The algorithms used may change again in the future.
+.Ss Older versions
+An incomplete list of changes in older versions of
+.Nm :
.Pp
The way that .for loop variables are substituted changed after
.Nx 5.0
@@ -2020,20 +2171,75 @@ so that they still appear to be variable expansions.
In particular this stops them being treated as syntax, and removes some
obscure problems using them in .if statements.
.Pp
-Unlike other
+The way that parallel makes are scheduled changed in
+.Nx 4.0
+so that .ORDER and .WAIT apply recursively to the dependent nodes.
+The algorithms used may change again in the future.
+.Ss Other make dialects
+Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not
+support most of the features of
.Nm
-programs, this implementation by default executes all commands for a given
-target using a single shell invocation.
-This is done for both efficiency and to simplify error handling in remote
-command invocations.
-Typically this is transparent to the user, unless the target commands change
-the current working directory using
-.Dq cd
-or
-.Dq chdir .
-To be compatible with Makefiles that do this, one can use
-.Fl B
-to disable this behavior.
+as described in this manual.
+Most notably:
+.Bl -bullet -offset indent
+.It
+The
+.Ic .WAIT
+and
+.Ic .ORDER
+declarations and most functionality pertaining to parallelization.
+(GNU make supports parallelization but lacks these features needed to
+control it effectively.)
+.It
+Directives, including for loops and conditionals and most of the
+forms of include files.
+(GNU make has its own incompatible and less powerful syntax for
+conditionals.)
+.It
+All built-in variables that begin with a dot.
+.It
+Most of the special sources and targets that begin with a dot,
+with the notable exception of
+.Ic .PHONY ,
+.Ic .PRECIOUS ,
+and
+.Ic .SUFFIXES .
+.It
+Variable modifiers, except for the
+.Dl :old=new
+string substitution, which does not portably support globbing with
+.Ql %
+and historically only works on declared suffixes.
+.It
+The
+.Ic $>
+variable even in its short form; most makes support this functionality
+but its name varies.
+.El
+.Pp
+Some features are somewhat more portable, such as assignment with
+.Ic += ,
+.Ic ?= ,
+and
+.Ic != .
+The
+.Ic .PATH
+functionality is based on an older feature
+.Ic VPATH
+found in GNU make and many versions of SVR4 make; however,
+historically its behavior is too ill-defined (and too buggy) to rely
+upon.
+.Pp
+The
+.Ic $@
+and
+.Ic $<
+variables are more or less universally portable, as is the
+.Ic $(MAKE)
+variable.
+Basic use of suffix rules (for files only in the current directory,
+not trying to chain transformations together, etc.) is also reasonably
+portable.
.Sh SEE ALSO
.Xr mkdep 1
.Sh HISTORY
@@ -2044,10 +2250,17 @@ command appeared in
This
.Nm
implementation is based on Adam De Boor's pmake program which was written
-for Sprint at Berkeley.
+for Sprite at Berkeley.
It was designed to be a parallel distributed make running jobs on different
machines using a daemon called
.Dq customs .
+.Pp
+Historically the target/dependency
+.Dq FRC
+has been used to FoRCe rebuilding (since the target/dependency
+does not exist... unless someone creates an
+.Dq FRC
+file).
.Sh BUGS
The
.Nm
diff --git a/devel/bmake/files/make.c b/devel/bmake/files/make.c
index 1ba3c659760..8cab32254c7 100644
--- a/devel/bmake/files/make.c
+++ b/devel/bmake/files/make.c
@@ -1,4 +1,4 @@
-/* $NetBSD: make.c,v 1.1.1.7 2011/06/18 22:18:02 bsiegert Exp $ */
+/* $NetBSD: make.c,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: make.c,v 1.1.1.7 2011/06/18 22:18:02 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: make.c,v 1.1.1.7 2011/06/18 22:18:02 bsiegert Exp $");
+__RCSID("$NetBSD: make.c,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -139,7 +139,7 @@ static int MakeCheckOrder(void *, void *);
static int MakeBuildChild(void *, void *);
static int MakeBuildParent(void *, void *);
-static void
+MAKE_ATTR_DEAD static void
make_abort(GNode *gn, int line)
{
static int two = 2;
@@ -221,7 +221,7 @@ Make_OODate(GNode *gn)
* doesn't depend on their modification time...
*/
if ((gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC)) == 0) {
- (void)Dir_MTime(gn);
+ (void)Dir_MTime(gn, 1);
if (DEBUG(MAKE)) {
if (gn->mtime != 0) {
fprintf(debug_file, "modified %s...", Targ_FmtTime(gn->mtime));
@@ -406,7 +406,7 @@ MakeFindChild(void *gnp, void *pgnp)
GNode *gn = (GNode *)gnp;
GNode *pgn = (GNode *)pgnp;
- (void)Dir_MTime(gn);
+ (void)Dir_MTime(gn, 0);
Make_TimeStamp(pgn, gn);
pgn->unmade--;
@@ -563,7 +563,7 @@ MakeHandleUse(void *cgnp, void *pgnp)
* in the comments below.
*
* Results:
- * returns 0 if the gnode does not exist, or it's filesystem
+ * returns 0 if the gnode does not exist, or its filesystem
* time if it does.
*
* Side Effects:
@@ -574,7 +574,7 @@ MakeHandleUse(void *cgnp, void *pgnp)
time_t
Make_Recheck(GNode *gn)
{
- time_t mtime = Dir_MTime(gn);
+ time_t mtime = Dir_MTime(gn, 1);
#ifndef RECHECK
/*
@@ -867,7 +867,7 @@ Make_Update(GNode *cgn)
*-----------------------------------------------------------------------
*/
static int
-MakeUnmark(void *cgnp, void *pgnp __unused)
+MakeUnmark(void *cgnp, void *pgnp MAKE_ATTR_UNUSED)
{
GNode *cgn = (GNode *)cgnp;
@@ -1005,7 +1005,7 @@ Make_DoAllVar(GNode *gn)
*/
static int
-MakeCheckOrder(void *v_bn, void *ignore __unused)
+MakeCheckOrder(void *v_bn, void *ignore MAKE_ATTR_UNUSED)
{
GNode *bn = v_bn;
@@ -1032,7 +1032,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
/* Can't build this (or anything else in this child list) yet */
cn->made = DEFERRED;
- return 1;
+ return 0; /* but keep looking */
}
if (DEBUG(MAKE))
@@ -1055,7 +1055,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
return cn->type & OP_WAIT && cn->unmade > 0;
}
-/* When a .ORDER RHS node completes we do this on each LHS */
+/* When a .ORDER LHS node completes we do this on each RHS */
static int
MakeBuildParent(void *v_pn, void *toBeMade_next)
{
@@ -1336,7 +1336,7 @@ Make_ExpandUse(Lst targs)
*eon = ')';
}
- (void)Dir_MTime(gn);
+ (void)Dir_MTime(gn, 0);
Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
Lst_ForEach(gn->children, MakeUnmark, gn);
Lst_ForEach(gn->children, MakeHandleUse, gn);
diff --git a/devel/bmake/files/make.h b/devel/bmake/files/make.h
index 796e3683ecf..61e7577d815 100644
--- a/devel/bmake/files/make.h
+++ b/devel/bmake/files/make.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.1.1.7 2011/06/18 22:18:03 bsiegert Exp $ */
+/* $NetBSD: make.h,v 1.1.1.8 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -98,22 +98,33 @@
#include <unistd.h>
#include <sys/cdefs.h>
-#if !defined(__GNUC_PREREQ__)
#if defined(__GNUC__)
-#define __GNUC_PREREQ__(x, y) \
+#define MAKE_GNUC_PREREQ(x, y) \
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
(__GNUC__ > (x)))
#else /* defined(__GNUC__) */
-#define __GNUC_PREREQ__(x, y) 0
+#define MAKE_GNUC_PREREQ(x, y) 0
#endif /* defined(__GNUC__) */
-#endif /* !defined(__GNUC_PREREQ__) */
-#if !defined(__unused)
-#if __GNUC_PREREQ__(2, 7)
-#define __unused __attribute__((__unused__))
+#if MAKE_GNUC_PREREQ(2, 7)
+#define MAKE_ATTR_UNUSED __attribute__((__unused__))
#else
-#define __unused /* delete */
+#define MAKE_ATTR_UNUSED /* delete */
#endif
+
+#if MAKE_GNUC_PREREQ(2, 5)
+#define MAKE_ATTR_DEAD __attribute__((__noreturn__))
+#elif defined(__GNUC__)
+#define MAKE_ATTR_DEAD __volatile
+#else
+#define MAKE_ATTR_DEAD /* delete */
+#endif
+
+#if MAKE_GNUC_PREREQ(2, 7)
+#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#else
+#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
#endif
#include "sprite.h"
@@ -278,6 +289,7 @@ typedef struct GNode {
#define OP_NOMETA 0x00080000 /* .NOMETA do not create a .meta file */
#define OP_META 0x00100000 /* .META we _do_ want a .meta file */
#define OP_NOMETA_CMP 0x00200000 /* Do not compare commands in .meta file */
+#define OP_SUBMAKE 0x00400000 /* Possibly a submake node */
/* Attributes applied by PMake */
#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */
#define OP_MEMBER 0x40000000 /* Target is a member of an archive */
@@ -393,6 +405,10 @@ extern Boolean varNoExportEnv; /* TRUE if we should not export variables
extern GNode *DEFAULT; /* .DEFAULT rule */
+extern GNode *VAR_INTERNAL; /* Variables defined internally by make
+ * which should not override those set by
+ * makefiles.
+ */
extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
* in the Makefile itself */
extern GNode *VAR_CMD; /* Variables defined on the command line */
@@ -413,6 +429,7 @@ extern Lst defIncPath; /* The default include path. */
extern char curdir[]; /* Startup directory */
extern char *progname; /* The program name */
extern char *makeDependfile; /* .depend */
+extern char **savedEnv; /* if we replaced environ this will be non-NULL */
/*
* We cannot vfork() in a child of vfork().
@@ -430,6 +447,9 @@ extern pid_t myPid;
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
#define MAKE_MODE ".MAKE.MODE"
+#ifndef MAKE_LEVEL_ENV
+# define MAKE_LEVEL_ENV "MAKELEVEL"
+#endif
/*
* debug control:
@@ -499,4 +519,8 @@ int str2Lst_Append(Lst, char *, const char *);
#define MAX(a, b) ((a > b) ? a : b)
#endif
+#ifndef MAXPATHLEN
+#define MAXPATHLEN BMAKE_PATH_MAX
+#endif
+
#endif /* _MAKE_H_ */
diff --git a/devel/bmake/files/make_malloc.c b/devel/bmake/files/make_malloc.c
index f6f8a421d56..7802ea30c2e 100644
--- a/devel/bmake/files/make_malloc.c
+++ b/devel/bmake/files/make_malloc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: make_malloc.c,v 1.1.1.2 2011/06/18 22:18:03 bsiegert Exp $ */
+/* $NetBSD: make_malloc.c,v 1.1.1.3 2015/05/19 21:36:44 joerg Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
#ifdef MAKE_NATIVE
#include <sys/cdefs.h>
-__RCSID("$NetBSD: make_malloc.c,v 1.1.1.2 2011/06/18 22:18:03 bsiegert Exp $");
+__RCSID("$NetBSD: make_malloc.c,v 1.1.1.3 2015/05/19 21:36:44 joerg Exp $");
#endif
#include <stdio.h>
@@ -36,9 +36,11 @@ __RCSID("$NetBSD: make_malloc.c,v 1.1.1.2 2011/06/18 22:18:03 bsiegert Exp $");
#include <string.h>
#include <errno.h>
-#include "make_malloc.h"
+#include "make.h"
#ifndef USE_EMALLOC
+static void enomem(void) MAKE_ATTR_DEAD;
+
/*
* enomem --
* die when out of memory.
@@ -46,8 +48,6 @@ __RCSID("$NetBSD: make_malloc.c,v 1.1.1.2 2011/06/18 22:18:03 bsiegert Exp $");
static void
enomem(void)
{
- extern char *progname;
-
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(ENOMEM));
exit(2);
}
diff --git a/devel/bmake/files/makefile.in b/devel/bmake/files/makefile.in
new file mode 100644
index 00000000000..b1c79cc2e82
--- /dev/null
+++ b/devel/bmake/files/makefile.in
@@ -0,0 +1,14 @@
+# $Id: makefile.in,v 1.1.1.1 2015/05/19 21:36:44 joerg Exp $
+
+# a simple makefile for those who don't like anything beyond:
+# ./configure; make; make install
+
+prefix= @prefix@
+srcdir= @srcdir@
+
+all: build
+
+build clean install test:
+ ${srcdir}/boot-strap --prefix=${prefix} -o . op=$@
+
+
diff --git a/devel/bmake/files/meta.c b/devel/bmake/files/meta.c
index cacb9a40626..7a7816f4105 100644
--- a/devel/bmake/files/meta.c
+++ b/devel/bmake/files/meta.c
@@ -1,4 +1,4 @@
-/* $NetBSD: meta.c,v 1.1.1.1 2011/06/18 22:18:04 bsiegert Exp $ */
+/* $NetBSD: meta.c,v 1.1.1.2 2015/05/19 21:36:44 joerg Exp $ */
/*
* Implement 'meta' mode.
@@ -55,7 +55,12 @@
#endif
static BuildMon Mybm; /* for compat */
-static Lst metaBailiwick; /* our scope of control */
+static Lst metaBailiwick; /* our scope of control */
+static Lst metaIgnorePaths; /* paths we deliberately ignore */
+
+#ifndef MAKE_META_IGNORE_PATHS
+#define MAKE_META_IGNORE_PATHS ".MAKE.META.IGNORE_PATHS"
+#endif
Boolean useMeta = FALSE;
static Boolean useFilemon = FALSE;
@@ -64,9 +69,11 @@ static Boolean metaEnv = FALSE; /* don't save env unless asked */
static Boolean metaVerbose = FALSE;
static Boolean metaIgnoreCMDs = FALSE; /* ignore CMDs in .meta files */
static Boolean metaCurdirOk = FALSE; /* write .meta in .CURDIR Ok? */
+static Boolean metaSilent = FALSE; /* if we have a .meta be SILENT */
extern Boolean forceJobs;
extern Boolean comatMake;
+extern char **environ;
#define MAKE_META_PREFIX ".MAKE.META.PREFIX"
@@ -148,8 +155,8 @@ filemon_open(BuildMon *pbm)
static void
filemon_read(FILE *mfp, int fd)
{
- FILE *fp;
char buf[BUFSIZ];
+ int n;
/* Check if we're not writing to a meta data file.*/
if (mfp == NULL) {
@@ -158,18 +165,15 @@ filemon_read(FILE *mfp, int fd)
return;
}
/* rewind */
- lseek(fd, SEEK_SET, 0);
- if ((fp = fdopen(fd, "r")) == NULL)
- err(1, "Could not read build monitor file '%d'", fd);
+ (void)lseek(fd, (off_t)0, SEEK_SET);
- fprintf(mfp, "-- filemon acquired metadata --\n");
+ fprintf(mfp, "\n-- filemon acquired metadata --\n");
- while (fgets(buf, sizeof(buf), fp)) {
- fprintf(mfp, "%s", buf);
+ while ((n = read(fd, buf, sizeof(buf))) > 0) {
+ fwrite(buf, 1, n, mfp);
}
fflush(mfp);
- clearerr(fp);
- fclose(fp);
+ close(fd);
}
#endif
@@ -387,7 +391,6 @@ printCMD(void *cmdp, void *mfpp)
static FILE *
meta_create(BuildMon *pbm, GNode *gn)
{
- extern char **environ;
meta_file_t mf;
char buf[MAXPATHLEN];
char objdir[MAXPATHLEN];
@@ -510,7 +513,11 @@ meta_create(BuildMon *pbm, GNode *gn)
Var_Append(".MAKE.META.FILES", fname, VAR_GLOBAL);
Var_Append(".MAKE.META.CREATED", fname, VAR_GLOBAL);
-
+
+ gn->type |= OP_META; /* in case anyone wants to know */
+ if (metaSilent) {
+ gn->type |= OP_SILENT;
+ }
out:
for (i--; i >= 0; i--) {
if (p[i])
@@ -534,8 +541,24 @@ boolValue(char *s)
return TRUE;
}
+/*
+ * Initialization we need before reading makefiles.
+ */
+void
+meta_init(void)
+{
+#ifdef USE_FILEMON
+ /* this allows makefiles to test if we have filemon support */
+ Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0);
+#endif
+}
+
+
+/*
+ * Initialization we need after reading makefiles.
+ */
void
-meta_init(const char *make_mode)
+meta_mode_init(const char *make_mode)
{
static int once = 0;
char *cp;
@@ -556,6 +579,9 @@ meta_init(const char *make_mode)
if ((cp = strstr(make_mode, "curdirok="))) {
metaCurdirOk = boolValue(&cp[9]);
}
+ if ((cp = strstr(make_mode, "silent="))) {
+ metaSilent = boolValue(&cp[7]);
+ }
if (strstr(make_mode, "ignore-cmd"))
metaIgnoreCMDs = TRUE;
/* for backwards compatability */
@@ -583,6 +609,17 @@ meta_init(const char *make_mode)
if (cp) {
str2Lst_Append(metaBailiwick, cp, NULL);
}
+ /*
+ * We ignore any paths that start with ${.MAKE.META.IGNORE_PATHS}
+ */
+ metaIgnorePaths = Lst_Init(FALSE);
+ Var_Append(MAKE_META_IGNORE_PATHS,
+ "/dev /etc /proc /tmp /var/run /var/tmp ${TMPDIR}", VAR_GLOBAL);
+ cp = Var_Subst(NULL,
+ "${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL, 0);
+ if (cp) {
+ str2Lst_Append(metaIgnorePaths, cp, NULL);
+ }
}
/*
@@ -622,17 +659,21 @@ meta_job_child(Job *job)
{
#ifdef USE_FILEMON
BuildMon *pbm;
- pid_t pid;
if (job != NULL) {
pbm = &job->bm;
} else {
pbm = &Mybm;
}
- pid = getpid();
- if (pbm->mfp != NULL && useFilemon) {
- if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) {
- err(1, "Could not set filemon pid!");
+ if (pbm->mfp != NULL) {
+ close(fileno(pbm->mfp));
+ if (useFilemon) {
+ pid_t pid;
+
+ pid = getpid();
+ if (ioctl(pbm->filemon_fd, FILEMON_SET_PID, &pid) < 0) {
+ err(1, "Could not set filemon pid!");
+ }
}
}
#endif
@@ -767,7 +808,7 @@ fgetLine(char **bufp, size_t *szp, int o, FILE *fp)
newsz = ROUNDUP(fs.st_size, BUFSIZ);
if (DEBUG(META))
fprintf(debug_file, "growing buffer %u -> %u\n",
- bufsz, newsz);
+ (unsigned)bufsz, (unsigned)newsz);
p = bmake_realloc(buf, newsz);
if (p) {
*bufp = buf = p;
@@ -804,27 +845,51 @@ string_match(const void *p, const void *q)
/*
* When running with 'meta' functionality, a target can be out-of-date
- * if any of the references in it's meta data file is more recent.
+ * if any of the references in its meta data file is more recent.
* We have to track the latestdir on a per-process basis.
*/
+#define LCWD_VNAME_FMT ".meta.%d.lcwd"
#define LDIR_VNAME_FMT ".meta.%d.ldir"
+/*
+ * It is possible that a .meta file is corrupted,
+ * if we detect this we want to reproduce it.
+ * Setting oodate TRUE will have that effect.
+ */
+#define CHECK_VALID_META(p) if (!(p && *p)) { \
+ warnx("%s: %d: malformed", fname, lineno); \
+ oodate = TRUE; \
+ continue; \
+ }
+
+#define DEQUOTE(p) if (*p == '\'') { \
+ char *ep; \
+ p++; \
+ if ((ep = strchr(p, '\''))) \
+ *ep = '\0'; \
+ }
+
Boolean
meta_oodate(GNode *gn, Boolean oodate)
{
static char *tmpdir = NULL;
static char cwd[MAXPATHLEN];
+ char lcwd_vname[64];
char ldir_vname[64];
+ char lcwd[MAXPATHLEN];
char latestdir[MAXPATHLEN];
char fname[MAXPATHLEN];
char fname1[MAXPATHLEN];
char fname2[MAXPATHLEN];
+ char fname3[MAXPATHLEN];
char *p;
char *cp;
+ char *link_src;
+ char *move_target;
static size_t cwdlen = 0;
static size_t tmplen = 0;
FILE *fp;
- Boolean ignoreOODATE = FALSE;
+ Boolean needOODATE = FALSE;
Lst missingFiles;
if (oodate)
@@ -868,6 +933,8 @@ meta_oodate(GNode *gn, Boolean oodate)
err(1, "Could not get current working directory");
cwdlen = strlen(cwd);
}
+ strlcpy(lcwd, cwd, sizeof(lcwd));
+ strlcpy(latestdir, cwd, sizeof(latestdir));
if (!tmpdir) {
tmpdir = getTmpdir();
@@ -882,9 +949,13 @@ meta_oodate(GNode *gn, Boolean oodate)
lineno++;
if (buf[x - 1] == '\n')
buf[x - 1] = '\0';
- else
+ else {
warnx("%s: %d: line truncated at %u", fname, lineno, x);
-
+ oodate = TRUE;
+ break;
+ }
+ link_src = NULL;
+ move_target = NULL;
/* Find the start of the build monitor section. */
if (!f) {
if (strncmp(buf, "-- filemon", 10) == 0) {
@@ -940,15 +1011,18 @@ meta_oodate(GNode *gn, Boolean oodate)
* re-initialize 'latestdir' to any pre-saved
* value for the current 'pid' and 'CWD' if none.
*/
+ CHECK_VALID_META(p);
pid = atoi(p);
if (pid > 0 && pid != lastpid) {
char *ldir;
char *tp;
if (lastpid > 0) {
- /* We need to remember this. */
+ /* We need to remember these. */
+ Var_Set(lcwd_vname, lcwd, VAR_GLOBAL, 0);
Var_Set(ldir_vname, latestdir, VAR_GLOBAL, 0);
}
+ snprintf(lcwd_vname, sizeof(lcwd_vname), LCWD_VNAME_FMT, pid);
snprintf(ldir_vname, sizeof(ldir_vname), LDIR_VNAME_FMT, pid);
lastpid = pid;
ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp);
@@ -956,22 +1030,32 @@ meta_oodate(GNode *gn, Boolean oodate)
strlcpy(latestdir, ldir, sizeof(latestdir));
if (tp)
free(tp);
- } else
- strlcpy(latestdir, cwd, sizeof(latestdir));
+ }
+ ldir = Var_Value(lcwd_vname, VAR_GLOBAL, &tp);
+ if (ldir) {
+ strlcpy(lcwd, ldir, sizeof(lcwd));
+ if (tp)
+ free(tp);
+ }
}
/* Skip past the pid. */
if (strsep(&p, " ") == NULL)
continue;
#ifdef DEBUG_META_MODE
if (DEBUG(META))
- fprintf(debug_file, "%s: %d: cwd=%s ldir=%s\n", fname, lineno, cwd, latestdir);
+ fprintf(debug_file, "%s: %d: %d: %c: cwd=%s lcwd=%s ldir=%s\n",
+ fname, lineno,
+ pid, buf[0], cwd, lcwd, latestdir);
#endif
break;
}
+ CHECK_VALID_META(p);
+
/* Process according to record type. */
switch (buf[0]) {
case 'X': /* eXit */
+ Var_Delete(lcwd_vname, VAR_GLOBAL);
Var_Delete(ldir_vname, VAR_GLOBAL);
lastpid = 0; /* no need to save ldir_vname */
break;
@@ -983,28 +1067,48 @@ meta_oodate(GNode *gn, Boolean oodate)
child = atoi(p);
if (child > 0) {
+ snprintf(cldir, sizeof(cldir), LCWD_VNAME_FMT, child);
+ Var_Set(cldir, lcwd, VAR_GLOBAL, 0);
snprintf(cldir, sizeof(cldir), LDIR_VNAME_FMT, child);
Var_Set(cldir, latestdir, VAR_GLOBAL, 0);
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: %d: cwd=%s lcwd=%s ldir=%s\n",
+ fname, lineno,
+ child, cwd, lcwd, latestdir);
+#endif
}
}
break;
case 'C': /* Chdir */
- /* Update the latest directory. */
- strlcpy(latestdir, p, sizeof(latestdir));
+ /* Update lcwd and latest directory. */
+ strlcpy(latestdir, p, sizeof(latestdir));
+ strlcpy(lcwd, p, sizeof(lcwd));
+ Var_Set(lcwd_vname, lcwd, VAR_GLOBAL, 0);
+ Var_Set(ldir_vname, lcwd, VAR_GLOBAL, 0);
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: cwd=%s ldir=%s\n", fname, lineno, cwd, lcwd);
+#endif
break;
case 'M': /* renaMe */
- if (Lst_IsEmpty(missingFiles))
- break;
+ /*
+ * For 'M'oves we want to check
+ * the src as for 'R'ead
+ * and the target as for 'W'rite.
+ */
+ cp = p; /* save this for a second */
+ /* now get target */
+ if (strsep(&p, " ") == NULL)
+ continue;
+ CHECK_VALID_META(p);
+ move_target = p;
+ p = cp;
/* 'L' and 'M' put single quotes around the args */
- if (*p == '\'') {
- char *ep;
-
- p++;
- if ((ep = strchr(p, '\'')))
- *ep = '\0';
- }
+ DEQUOTE(p);
+ DEQUOTE(move_target);
/* FALLTHROUGH */
case 'D': /* unlink */
if (*p == '/' && !Lst_IsEmpty(missingFiles)) {
@@ -1013,23 +1117,42 @@ meta_oodate(GNode *gn, Boolean oodate)
char *tp = Lst_Datum(ln);
Lst_Remove(missingFiles, ln);
free(tp);
+ ln = NULL; /* we're done with it */
}
}
+ if (buf[0] == 'M') {
+ /* the target of the mv is a file 'W'ritten */
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "meta_oodate: M %s -> %s\n",
+ p, move_target);
+#endif
+ p = move_target;
+ goto check_write;
+ }
break;
case 'L': /* Link */
- /* we want the target */
+ /*
+ * For 'L'inks check
+ * the src as for 'R'ead
+ * and the target as for 'W'rite.
+ */
+ link_src = p;
+ /* now get target */
if (strsep(&p, " ") == NULL)
continue;
+ CHECK_VALID_META(p);
/* 'L' and 'M' put single quotes around the args */
- if (*p == '\'') {
- char *ep;
-
- p++;
- if ((ep = strchr(p, '\'')))
- *ep = '\0';
- }
+ DEQUOTE(p);
+ DEQUOTE(link_src);
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "meta_oodate: L %s -> %s\n",
+ link_src, p);
+#endif
/* FALLTHROUGH */
case 'W': /* Write */
+ check_write:
/*
* If a file we generated within our bailiwick
* but outside of .OBJDIR is missing,
@@ -1061,6 +1184,14 @@ meta_oodate(GNode *gn, Boolean oodate)
Lst_AtEnd(missingFiles, bmake_strdup(p));
}
break;
+ check_link_src:
+ p = link_src;
+ link_src = NULL;
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "meta_oodate: L src %s\n", p);
+#endif
+ /* FALLTHROUGH */
case 'R': /* Read */
case 'E': /* Exec */
/*
@@ -1068,20 +1199,25 @@ meta_oodate(GNode *gn, Boolean oodate)
* be part of the dependencies because
* they are _expected_ to change.
*/
- if (strncmp(p, "/tmp/", 5) == 0 ||
- (tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0))
- break;
-
- if (strncmp(p, "/var/", 5) == 0)
- break;
-
- /* Ignore device files. */
- if (strncmp(p, "/dev/", 5) == 0)
+ if (*p == '/' &&
+ Lst_ForEach(metaIgnorePaths, prefix_match, p)) {
+#ifdef DEBUG_META_MODE
+ if (DEBUG(META))
+ fprintf(debug_file, "meta_oodate: ignoring: %s\n",
+ p);
+#endif
break;
+ }
- /* Ignore /etc/ files. */
- if (strncmp(p, "/etc/", 5) == 0)
- break;
+ if ((cp = strrchr(p, '/'))) {
+ cp++;
+ /*
+ * We don't normally expect to see this,
+ * but we do expect it to change.
+ */
+ if (strcmp(cp, makeDependfile) == 0)
+ break;
+ }
/*
* The rest of the record is the file name.
@@ -1103,11 +1239,16 @@ meta_oodate(GNode *gn, Boolean oodate)
snprintf(fname1, sizeof(fname1), "%s/%s", latestdir, p);
sdirs[sdx++] = fname1;
- if (strcmp(latestdir, cwd) != 0) {
- /* Check vs cwd */
- snprintf(fname2, sizeof(fname2), "%s/%s", cwd, p);
+ if (strcmp(latestdir, lcwd) != 0) {
+ /* Check vs lcwd */
+ snprintf(fname2, sizeof(fname2), "%s/%s", lcwd, p);
sdirs[sdx++] = fname2;
}
+ if (strcmp(lcwd, cwd) != 0) {
+ /* Check vs cwd */
+ snprintf(fname3, sizeof(fname3), "%s/%s", cwd, p);
+ sdirs[sdx++] = fname3;
+ }
}
sdirs[sdx++] = NULL;
@@ -1146,10 +1287,16 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
}
}
+ if (buf[0] == 'E') {
+ /* previous latestdir is no longer relevant */
+ strlcpy(latestdir, lcwd, sizeof(latestdir));
+ }
break;
default:
break;
}
+ if (!oodate && buf[0] == 'L' && link_src != NULL)
+ goto check_link_src;
} else if (strcmp(buf, "CMD") == 0) {
/*
* Compare the current command with the one in the
@@ -1161,17 +1308,19 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
} else {
char *cmd = (char *)Lst_Datum(ln);
-
- if (!ignoreOODATE) {
- if (strstr(cmd, "$?"))
- ignoreOODATE = TRUE;
- else if ((cp = strstr(cmd, ".OODATE"))) {
- /* check for $[{(].OODATE[)}] */
- if (cp > cmd + 2 && cp[-2] == '$')
- ignoreOODATE = TRUE;
- }
- if (ignoreOODATE && DEBUG(META))
- fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno);
+ Boolean hasOODATE = FALSE;
+
+ if (strstr(cmd, "$?"))
+ hasOODATE = TRUE;
+ else if ((cp = strstr(cmd, ".OODATE"))) {
+ /* check for $[{(].OODATE[:)}] */
+ if (cp > cmd + 2 && cp[-2] == '$')
+ hasOODATE = TRUE;
+ }
+ if (hasOODATE) {
+ needOODATE = TRUE;
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
}
cmd = Var_Subst(NULL, cmd, gn, TRUE);
@@ -1200,7 +1349,7 @@ meta_oodate(GNode *gn, Boolean oodate)
if (buf[x - 1] == '\n')
buf[x - 1] = '\0';
}
- if (!ignoreOODATE &&
+ if (!hasOODATE &&
!(gn->type & OP_NOMETA_CMP) &&
strcmp(p, cmd) != 0) {
if (DEBUG(META))
@@ -1237,15 +1386,23 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
Lst_Destroy(missingFiles, (FreeProc *)free);
}
+ } else {
+ if ((gn->type & OP_META)) {
+ if (DEBUG(META))
+ fprintf(debug_file, "%s: required but missing\n", fname);
+ oodate = TRUE;
+ }
}
- if (oodate && ignoreOODATE) {
+ if (oodate && needOODATE) {
/*
- * Target uses .OODATE, so we need to re-compute it.
- * We need to clean up what Make_DoAllVar() did.
+ * Target uses .OODATE which is empty; or we wouldn't be here.
+ * We have decided it is oodate, so .OODATE needs to be set.
+ * All we can sanely do is set it to .ALLSRC.
*/
- Var_Delete(ALLSRC, gn);
Var_Delete(OODATE, gn);
- gn->flags &= ~DONE_ALLSRC;
+ Var_Set(OODATE, Var_Value(ALLSRC, gn, &cp), gn, 0);
+ if (cp)
+ free(cp);
}
return oodate;
}
diff --git a/devel/bmake/files/meta.h b/devel/bmake/files/meta.h
index e47ad89b677..1d522efb1a5 100644
--- a/devel/bmake/files/meta.h
+++ b/devel/bmake/files/meta.h
@@ -1,4 +1,4 @@
-/* $NetBSD: meta.h,v 1.1.1.1 2011/06/18 22:18:04 bsiegert Exp $ */
+/* $NetBSD: meta.h,v 1.1.1.2 2015/05/19 21:36:44 joerg Exp $ */
/*
* Things needed for 'meta' mode.
@@ -41,7 +41,8 @@ typedef struct BuildMon {
extern Boolean useMeta;
struct Job; /* not defined yet */
-void meta_init(const char *);
+void meta_init(void);
+void meta_mode_init(const char *);
void meta_job_start(struct Job *, GNode *);
void meta_job_child(struct Job *);
void meta_job_error(struct Job *, GNode *, int, int);
diff --git a/devel/bmake/files/nonints.h b/devel/bmake/files/nonints.h
index ebc91b46664..8511af43876 100644
--- a/devel/bmake/files/nonints.h
+++ b/devel/bmake/files/nonints.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.1.1.8 2011/06/18 22:18:04 bsiegert Exp $ */
+/* $NetBSD: nonints.h,v 1.1.1.9 2015/05/19 21:36:44 joerg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -72,11 +72,6 @@
* from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
*/
-#ifndef MAKE_NATIVE
-#undef __attribute__
-#define __attribute__(x)
-#endif
-
/* arch.c */
ReturnStatus Arch_ParseArchive(char **, Lst, GNode *);
void Arch_Touch(GNode *);
@@ -96,7 +91,7 @@ int Compat_Make(void *, void *);
/* cond.c */
struct If;
-int Cond_EvalExpression(const struct If *, char *, Boolean *, int);
+int Cond_EvalExpression(const struct If *, char *, Boolean *, int, Boolean);
int Cond_Eval(char *);
void Cond_restore_depth(unsigned int);
unsigned int Cond_save_depth(void);
@@ -116,21 +111,19 @@ void Main_ParseArgLine(const char *);
void MakeMode(const char *);
int main(int, char **);
char *Cmd_Exec(const char *, const char **);
-void Error(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
-void Fatal(const char *, ...)
- __attribute__((__format__(__printf__, 1, 2),__noreturn__));
-void Punt(const char *, ...)
- __attribute__((__format__(__printf__, 1, 2),__noreturn__));
-void DieHorribly(void) __attribute__((__noreturn__));
+void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
+void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
+void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
+void DieHorribly(void) MAKE_ATTR_DEAD;
int PrintAddr(void *, void *);
-void Finish(int);
+void Finish(int) MAKE_ATTR_DEAD;
int eunlink(const char *);
void execError(const char *, const char *);
char *getTmpdir(void);
+Boolean getBoolean(const char *, Boolean);
/* parse.c */
-void Parse_Error(int, const char *, ...)
- __attribute__((__format__(__printf__, 2, 3)));
+void Parse_Error(int, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
Boolean Parse_AnyExport(void);
Boolean Parse_IsVar(char *);
void Parse_DoVar(char *, GNode *);
diff --git a/devel/bmake/files/os.sh b/devel/bmake/files/os.sh
index 487ebfb943e..1aeabdd8381 100644
--- a/devel/bmake/files/os.sh
+++ b/devel/bmake/files/os.sh
@@ -17,7 +17,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: os.sh,v 1.1.1.6 2010/09/07 14:11:15 joerg Exp $
+# $Id: os.sh,v 1.1.1.7 2015/05/19 21:36:44 joerg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@@ -128,11 +128,13 @@ SunOS)
K=-k
MAILER=/usr/bin/Mail
LOCAL_FS=local
- case "$-" in
- *i*) ;;
+ : $-,$ENV
+ case "$-,$ENV" in
+ *i*,*) ;;
+ *,|*ENVFILE*) ;;
*) ENV=;;
esac
- # NetBSD at least has good backward compatability
+ # NetBSD at least has good backward compatibility
# so NetBSD/i386 is good enough
case $OS in
NetBSD) SHARE_ARCH=$OS/${MACHINE_ARCH:-$MACHINE};;
diff --git a/devel/bmake/files/parse.c b/devel/bmake/files/parse.c
index 40a14cba1a6..a7c3b44af00 100644
--- a/devel/bmake/files/parse.c
+++ b/devel/bmake/files/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.1.1.9 2011/06/18 22:18:06 bsiegert Exp $ */
+/* $NetBSD: parse.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.1.1.9 2011/06/18 22:18:06 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: parse.c,v 1.1.1.9 2011/06/18 22:18:06 bsiegert Exp $");
+__RCSID("$NetBSD: parse.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -132,13 +132,6 @@ __RCSID("$NetBSD: parse.c,v 1.1.1.9 2011/06/18 22:18:06 bsiegert Exp $");
#include <stdarg.h>
#include <stdio.h>
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif
-#ifndef MAP_COPY
-#define MAP_COPY MAP_PRIVATE
-#endif
-
#include "make.h"
#include "hash.h"
#include "dir.h"
@@ -164,7 +157,7 @@ __RCSID("$NetBSD: parse.c,v 1.1.1.9 2011/06/18 22:18:06 bsiegert Exp $");
* Structure for a file being read ("included file")
*/
typedef struct IFile {
- const char *fname; /* name of file */
+ char *fname; /* name of file */
int lineno; /* current line number in file */
int first_lineno; /* line number of start of text */
int cond_depth; /* 'if' nesting when file opened */
@@ -220,6 +213,7 @@ typedef enum {
ExShell, /* .SHELL */
Silent, /* .SILENT */
SingleShell, /* .SINGLESHELL */
+ Stale, /* .STALE */
Suffixes, /* .SUFFIXES */
Wait, /* .WAIT */
Attribute /* Generic attribute */
@@ -343,6 +337,7 @@ static const struct {
{ ".SHELL", ExShell, 0 },
{ ".SILENT", Silent, OP_SILENT },
{ ".SINGLESHELL", SingleShell, 0 },
+{ ".STALE", Stale, 0 },
{ ".SUFFIXES", Suffixes, 0 },
{ ".USE", Attribute, OP_USE },
{ ".USEBEFORE", Attribute, OP_USEBEFORE },
@@ -354,9 +349,9 @@ static const struct {
static int ParseIsEscaped(const char *, const char *);
static void ParseErrorInternal(const char *, size_t, int, const char *, ...)
- __attribute__((__format__(__printf__, 4, 5)));
+ MAKE_ATTR_PRINTFLIKE(4,5);
static void ParseVErrorInternal(FILE *, const char *, size_t, int, const char *, va_list)
- __attribute__((__format__(__printf__, 5, 0)));
+ MAKE_ATTR_PRINTFLIKE(5, 0);
static int ParseFindKeyword(const char *);
static int ParseLinkSrc(void *, void *);
static int ParseDoOp(void *, void *);
@@ -369,9 +364,13 @@ static int ParseAddCmd(void *, void *);
static void ParseHasCommands(void *);
static void ParseDoInclude(char *);
static void ParseSetParseFile(const char *);
+static void ParseSetIncludedFile(void);
#ifdef SYSVINCLUDE
static void ParseTraditionalInclude(char *);
#endif
+#ifdef GMAKEEXPORT
+static void ParseGmakeExport(char *);
+#endif
static int ParseEOF(void);
static char *ParseReadLine(void);
static void ParseFinishLine(void);
@@ -857,7 +856,8 @@ ParseLinkSrc(void *pgnp, void *cgnp)
(void)Lst_AtEnd(cgn->parents, pgn);
pgn->unmade += 1;
if (DEBUG(PARSE)) {
- fprintf(debug_file, "# ParseLinkSrc: added child %s - %s\n", pgn->name, cgn->name);
+ fprintf(debug_file, "# %s: added child %s - %s\n", __func__,
+ pgn->name, cgn->name);
Targ_PrintNode(pgn, 0);
Targ_PrintNode(cgn, 0);
}
@@ -919,6 +919,8 @@ ParseDoOp(void *gnp, void *opp)
gn->type |= op & ~OP_OPMASK;
cohort = Targ_FindNode(gn->name, TARG_NOHASH);
+ if (doing_depend)
+ ParseMark(cohort);
/*
* Make the cohort invisible as well to avoid duplicating it into
* other variables. True, parents of this target won't tend to do
@@ -991,6 +993,8 @@ ParseDoSrc(int tOp, const char *src)
*/
snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
gn = Targ_FindNode(wait_src, TARG_NOHASH);
+ if (doing_depend)
+ ParseMark(gn);
gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
Lst_ForEach(targets, ParseLinkSrc, gn);
return;
@@ -1022,12 +1026,14 @@ ParseDoSrc(int tOp, const char *src)
* source and the current one.
*/
gn = Targ_FindNode(src, TARG_CREATE);
+ if (doing_depend)
+ ParseMark(gn);
if (predecessor != NULL) {
(void)Lst_AtEnd(predecessor->order_succ, gn);
(void)Lst_AtEnd(gn->order_pred, predecessor);
if (DEBUG(PARSE)) {
- fprintf(debug_file, "# ParseDoSrc: added Order dependency %s - %s\n",
- predecessor->name, gn->name);
+ fprintf(debug_file, "# %s: added Order dependency %s - %s\n",
+ __func__, predecessor->name, gn->name);
Targ_PrintNode(predecessor, 0);
Targ_PrintNode(gn, 0);
}
@@ -1053,6 +1059,8 @@ ParseDoSrc(int tOp, const char *src)
/* Find/create the 'src' node and attach to all targets */
gn = Targ_FindNode(src, TARG_CREATE);
+ if (doing_depend)
+ ParseMark(gn);
if (tOp) {
gn->type |= tOp;
} else {
@@ -1191,11 +1199,21 @@ ParseDoDependency(char *line)
tOp = 0;
specType = Not;
- paths = (Lst)NULL;
+ paths = NULL;
curTargs = Lst_Init(FALSE);
+ /*
+ * First, grind through the targets.
+ */
+
do {
+ /*
+ * Here LINE points to the beginning of the next word, and
+ * LSTART points to the actual beginning of the line.
+ */
+
+ /* Find the end of the next word. */
for (cp = line; *cp && (ParseIsEscaped(lstart, cp) ||
!(isspace((unsigned char)*cp) ||
*cp == '!' || *cp == ':' || *cp == LPAREN));
@@ -1210,15 +1228,18 @@ ParseDoDependency(char *line)
*/
int length;
void *freeIt;
- char *result;
- result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
+ (void)Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
if (freeIt)
free(freeIt);
cp += length-1;
}
}
+ /*
+ * If the word is followed by a left parenthesis, it's the
+ * name of an object file inside an archive (ar file).
+ */
if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) {
/*
* Archives must be handled specially to make sure the OP_ARCHV
@@ -1235,13 +1256,16 @@ ParseDoDependency(char *line)
"Error in archive specification: \"%s\"", line);
goto out;
} else {
+ /* Done with this word; on to the next. */
continue;
}
}
- savec = *cp;
if (!*cp) {
/*
+ * We got to the end of the line while we were still
+ * looking at targets.
+ *
* Ending a dependency line without an operator is a Bozo
* no-no. As a heuristic, this is also often triggered by
* undetected conflicts from cvs/rcs merges.
@@ -1256,10 +1280,13 @@ ParseDoDependency(char *line)
: "Need an operator");
goto out;
}
+
+ /* Insert a null terminator. */
+ savec = *cp;
*cp = '\0';
/*
- * Have a word in line. See if it's a special target and set
+ * Got the word. See if it's a special target and if so set
* specType to match it.
*/
if (*line == '.' && isupper ((unsigned char)line[1])) {
@@ -1298,6 +1325,7 @@ ParseDoDependency(char *line)
* apply the .DEFAULT commands.
* .PHONY The list of targets
* .NOPATH Don't search for file in the path
+ * .STALE
* .BEGIN
* .END
* .ERROR
@@ -1308,42 +1336,45 @@ ParseDoDependency(char *line)
* .ORDER Must set initial predecessor to NULL
*/
switch (specType) {
- case ExPath:
- if (paths == NULL) {
- paths = Lst_Init(FALSE);
- }
- (void)Lst_AtEnd(paths, dirSearchPath);
- break;
- case Main:
- if (!Lst_IsEmpty(create)) {
- specType = Not;
- }
- break;
- case Begin:
- case End:
- case dotError:
- case Interrupt:
- gn = Targ_FindNode(line, TARG_CREATE);
- gn->type |= OP_NOTMAIN|OP_SPECIAL;
- (void)Lst_AtEnd(targets, gn);
- break;
- case Default:
- gn = Targ_NewGN(".DEFAULT");
- gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
- (void)Lst_AtEnd(targets, gn);
- DEFAULT = gn;
- break;
- case NotParallel:
- maxJobs = 1;
- break;
- case SingleShell:
- compatMake = TRUE;
- break;
- case Order:
- predecessor = NULL;
- break;
- default:
- break;
+ case ExPath:
+ if (paths == NULL) {
+ paths = Lst_Init(FALSE);
+ }
+ (void)Lst_AtEnd(paths, dirSearchPath);
+ break;
+ case Main:
+ if (!Lst_IsEmpty(create)) {
+ specType = Not;
+ }
+ break;
+ case Begin:
+ case End:
+ case Stale:
+ case dotError:
+ case Interrupt:
+ gn = Targ_FindNode(line, TARG_CREATE);
+ if (doing_depend)
+ ParseMark(gn);
+ gn->type |= OP_NOTMAIN|OP_SPECIAL;
+ (void)Lst_AtEnd(targets, gn);
+ break;
+ case Default:
+ gn = Targ_NewGN(".DEFAULT");
+ gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
+ (void)Lst_AtEnd(targets, gn);
+ DEFAULT = gn;
+ break;
+ case NotParallel:
+ maxJobs = 1;
+ break;
+ case SingleShell:
+ compatMake = TRUE;
+ break;
+ case Order:
+ predecessor = NULL;
+ break;
+ default:
+ break;
}
} else if (strncmp(line, ".PATH", 5) == 0) {
/*
@@ -1361,7 +1392,7 @@ ParseDoDependency(char *line)
&line[5]);
goto out;
} else {
- if (paths == (Lst)NULL) {
+ if (paths == NULL) {
paths = Lst_Init(FALSE);
}
(void)Lst_AtEnd(paths, path);
@@ -1394,6 +1425,8 @@ ParseDoDependency(char *line)
(void)Lst_AtEnd(curTargs, line);
}
+ /* Apply the targets. */
+
while(!Lst_IsEmpty(curTargs)) {
char *targName = (char *)Lst_DeQueue(curTargs);
@@ -1402,6 +1435,8 @@ ParseDoDependency(char *line)
} else {
gn = Suff_AddTransform(targName);
}
+ if (doing_depend)
+ ParseMark(gn);
(void)Lst_AtEnd(targets, gn);
}
@@ -1409,7 +1444,9 @@ ParseDoDependency(char *line)
Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
}
+ /* Don't need the inserted null terminator any more. */
*cp = savec;
+
/*
* If it is a special type and not .PATH, it's the only target we
* allow on this line...
@@ -1449,6 +1486,7 @@ ParseDoDependency(char *line)
Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
break;
case Default:
+ case Stale:
case Begin:
case End:
case dotError:
@@ -1484,12 +1522,21 @@ ParseDoDependency(char *line)
goto out;
}
- cp++; /* Advance beyond operator */
+ /* Advance beyond the operator */
+ cp++;
+ /*
+ * Apply the operator to the target. This is how we remember which
+ * operator a target was defined with. It fails if the operator
+ * used isn't consistent across all references.
+ */
Lst_ForEach(targets, ParseDoOp, &op);
/*
- * Get to the first source
+ * Onward to the sources.
+ *
+ * LINE will now point to the first source word, if any, or the
+ * end of the string if not.
*/
while (*cp && isspace ((unsigned char)*cp)) {
cp++;
@@ -1738,6 +1785,12 @@ Parse_IsVar(char *line)
ch = *line++;
wasSpace = TRUE;
}
+#ifdef SUNSHCMD
+ if (ch == ':' && strncmp(line, "sh", 2) == 0) {
+ line += 2;
+ continue;
+ }
+#endif
if (ch == '=')
return TRUE;
if (*line == '=' && ISEQOPERATOR(ch))
@@ -1942,6 +1995,40 @@ Parse_DoVar(char *line, GNode *ctxt)
}
+/*
+ * ParseMaybeSubMake --
+ * Scan the command string to see if it a possible submake node
+ * Input:
+ * cmd the command to scan
+ * Results:
+ * TRUE if the command is possibly a submake, FALSE if not.
+ */
+static Boolean
+ParseMaybeSubMake(const char *cmd)
+{
+ size_t i;
+ static struct {
+ const char *name;
+ size_t len;
+ } vals[] = {
+#define MKV(A) { A, sizeof(A) - 1 }
+ MKV("${MAKE}"),
+ MKV("${.MAKE}"),
+ MKV("$(MAKE)"),
+ MKV("$(.MAKE)"),
+ MKV("make"),
+ };
+ for (i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) {
+ char *ptr;
+ if ((ptr = strstr(cmd, vals[i].name)) == NULL)
+ continue;
+ if ((ptr == cmd || !isalnum((unsigned char)ptr[-1]))
+ && !isalnum((unsigned char)ptr[vals[i].len]))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/*-
* ParseAddCmd --
* Lst_ForEach function to add a command line to all targets
@@ -1954,7 +2041,9 @@ Parse_DoVar(char *line, GNode *ctxt)
* Always 0
*
* Side Effects:
- * A new element is added to the commands list of the node.
+ * A new element is added to the commands list of the node,
+ * and the node can be marked as a submake node if the command is
+ * determined to be that.
*/
static int
ParseAddCmd(void *gnp, void *cmd)
@@ -1968,6 +2057,8 @@ ParseAddCmd(void *gnp, void *cmd)
/* if target already supplied, ignore commands */
if (!(gn->type & OP_HAS_COMMANDS)) {
(void)Lst_AtEnd(gn->commands, cmd);
+ if (ParseMaybeSubMake(cmd))
+ gn->type |= OP_SUBMAKE;
ParseMark(gn);
} else {
#ifdef notyet
@@ -2156,6 +2247,7 @@ Parse_include_file(char *file, Boolean isSystem, int silent)
/* load it */
lf = loadfile(fullname, fd);
+ ParseSetIncludedFile();
/* Start reading from this file next */
Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf);
curFile->lf = lf;
@@ -2215,6 +2307,41 @@ ParseDoInclude(char *line)
/*-
*---------------------------------------------------------------------
+ * ParseSetIncludedFile --
+ * Set the .INCLUDEDFROMFILE variable to the contents of .PARSEFILE
+ * and the .INCLUDEDFROMDIR variable to the contents of .PARSEDIR
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * The .INCLUDEDFROMFILE variable is overwritten by the contents
+ * of .PARSEFILE and the .INCLUDEDFROMDIR variable is overwriten
+ * by the contents of .PARSEDIR
+ *---------------------------------------------------------------------
+ */
+static void
+ParseSetIncludedFile(void)
+{
+ char *pf, *fp = NULL;
+ char *pd, *dp = NULL;
+
+ pf = Var_Value(".PARSEFILE", VAR_GLOBAL, &fp);
+ Var_Set(".INCLUDEDFROMFILE", pf, VAR_GLOBAL, 0);
+ pd = Var_Value(".PARSEDIR", VAR_GLOBAL, &dp);
+ Var_Set(".INCLUDEDFROMDIR", pd, VAR_GLOBAL, 0);
+
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "%s: ${.INCLUDEDFROMDIR} = `%s' "
+ "${.INCLUDEDFROMFILE} = `%s'\n", __func__, pd, pf);
+
+ if (fp)
+ free(fp);
+ if (dp)
+ free(dp);
+}
+/*-
+ *---------------------------------------------------------------------
* ParseSetParseFile --
* Set the .PARSEDIR and .PARSEFILE variables to the dirname and
* basename of the given filename
@@ -2230,23 +2357,27 @@ ParseDoInclude(char *line)
static void
ParseSetParseFile(const char *filename)
{
- char *slash;
- char *dirname;
+ char *slash, *dirname;
+ const char *pd, *pf;
int len;
slash = strrchr(filename, '/');
if (slash == NULL) {
- Var_Set(".PARSEDIR", curdir, VAR_GLOBAL, 0);
- Var_Set(".PARSEFILE", filename, VAR_GLOBAL, 0);
+ Var_Set(".PARSEDIR", pd = curdir, VAR_GLOBAL, 0);
+ Var_Set(".PARSEFILE", pf = filename, VAR_GLOBAL, 0);
+ dirname= NULL;
} else {
len = slash - filename;
dirname = bmake_malloc(len + 1);
memcpy(dirname, filename, len);
- dirname[len] = 0;
- Var_Set(".PARSEDIR", dirname, VAR_GLOBAL, 0);
- Var_Set(".PARSEFILE", slash+1, VAR_GLOBAL, 0);
- free(dirname);
+ dirname[len] = '\0';
+ Var_Set(".PARSEDIR", pd = dirname, VAR_GLOBAL, 0);
+ Var_Set(".PARSEFILE", pf = slash + 1, VAR_GLOBAL, 0);
}
+ if (DEBUG(PARSE))
+ fprintf(debug_file, "%s: ${.PARSEDIR} = `%s' ${.PARSEFILE} = `%s'\n",
+ __func__, pd, pf);
+ free(dirname);
}
/*
@@ -2307,8 +2438,8 @@ Parse_SetInput(const char *name, int line, int fd,
ParseTrackInput(name);
if (DEBUG(PARSE))
- fprintf(debug_file, "Parse_SetInput: file %s, line %d, fd %d, nextbuf %p, arg %p\n",
- name, line, fd, nextbuf, arg);
+ fprintf(debug_file, "%s: file %s, line %d, fd %d, nextbuf %p, arg %p\n",
+ __func__, name, line, fd, nextbuf, arg);
if (fd == -1 && nextbuf == NULL)
/* sanity */
@@ -2327,7 +2458,7 @@ Parse_SetInput(const char *name, int line, int fd,
* name of the include file so error messages refer to the right
* place.
*/
- curFile->fname = name;
+ curFile->fname = bmake_strdup(name);
curFile->lineno = line;
curFile->first_lineno = line;
curFile->nextbuf = nextbuf;
@@ -2340,6 +2471,8 @@ Parse_SetInput(const char *name, int line, int fd,
buf = curFile->nextbuf(curFile->nextbuf_arg, &len);
if (buf == NULL) {
/* Was all a waste of time ... */
+ if (curFile->fname)
+ free(curFile->fname);
free(curFile);
return;
}
@@ -2378,7 +2511,7 @@ ParseTraditionalInclude(char *line)
char *all_files;
if (DEBUG(PARSE)) {
- fprintf(debug_file, "ParseTraditionalInclude: %s\n", file);
+ fprintf(debug_file, "%s: %s\n", __func__, file);
}
/*
@@ -2415,6 +2548,55 @@ ParseTraditionalInclude(char *line)
}
#endif
+#ifdef GMAKEEXPORT
+/*-
+ *---------------------------------------------------------------------
+ * ParseGmakeExport --
+ * Parse export <variable>=<value>
+ *
+ * And set the environment with it.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ * None
+ *---------------------------------------------------------------------
+ */
+static void
+ParseGmakeExport(char *line)
+{
+ char *variable = &line[6];
+ char *value;
+
+ if (DEBUG(PARSE)) {
+ fprintf(debug_file, "%s: %s\n", __func__, variable);
+ }
+
+ /*
+ * Skip over whitespace
+ */
+ while (isspace((unsigned char)*variable))
+ variable++;
+
+ for (value = variable; *value && *value != '='; value++)
+ continue;
+
+ if (*value != '=') {
+ Parse_Error(PARSE_FATAL,
+ "Variable/Value missing from \"export\"");
+ return;
+ }
+ *value++ = '\0'; /* terminate variable */
+
+ /*
+ * Expand the value before putting it in the environment.
+ */
+ value = Var_Subst(NULL, value, VAR_CMD, FALSE);
+ setenv(variable, value, 1);
+}
+#endif
+
/*-
*---------------------------------------------------------------------
* ParseEOF --
@@ -2468,6 +2650,8 @@ ParseEOF(void)
/* We've run out of input */
Var_Delete(".PARSEDIR", VAR_GLOBAL);
Var_Delete(".PARSEFILE", VAR_GLOBAL);
+ Var_Delete(".INCLUDEDFROMDIR", VAR_GLOBAL);
+ Var_Delete(".INCLUDEDFROMFILE", VAR_GLOBAL);
return DONE;
}
@@ -2514,6 +2698,16 @@ ParseGetLine(int flags, int *length)
if (cf->P_end == NULL)
/* End of string (aka for loop) data */
break;
+ /* see if there is more we can parse */
+ while (ptr++ < cf->P_end) {
+ if ((ch = *ptr) == '\n') {
+ if (ptr > line && ptr[-1] == '\\')
+ continue;
+ Parse_Error(PARSE_WARNING,
+ "Zero byte read from file, skipping rest of line.");
+ break;
+ }
+ }
if (cf->nextbuf != NULL) {
/*
* End of this buffer; return EOF and outer logic
@@ -2537,7 +2731,9 @@ ParseGetLine(int flags, int *length)
}
if (ch == '#' && comment == NULL) {
/* Remember first '#' for comment stripping */
- comment = line_end;
+ /* Unless previous char was '[', as in modifier :[#] */
+ if (!(ptr > line && ptr[-1] == '['))
+ comment = line_end;
}
ptr++;
if (ch == '\n')
@@ -2862,6 +3058,17 @@ Parse_File(const char *name, int fd)
continue;
}
#endif
+#ifdef GMAKEEXPORT
+ if (strncmp(line, "export", 6) == 0 &&
+ isspace((unsigned char) line[6]) &&
+ strchr(line, ':') == NULL) {
+ /*
+ * It's a Gmake "export".
+ */
+ ParseGmakeExport(line);
+ continue;
+ }
+#endif
if (Parse_IsVar(line)) {
ParseFinishLine();
Parse_DoVar(line, VAR_GLOBAL);
diff --git a/devel/bmake/files/realpath.c b/devel/bmake/files/realpath.c
index a8dc83bd914..c43faf82db9 100644
--- a/devel/bmake/files/realpath.c
+++ b/devel/bmake/files/realpath.c
@@ -1,5 +1,5 @@
-/* $Id: realpath.c,v 1.1.1.2 2010/04/24 20:33:57 joerg Exp $ */
-/* from: $NetBSD: realpath.c,v 1.1.1.2 2010/04/24 20:33:57 joerg Exp $ */
+/* $Id: realpath.c,v 1.1.1.3 2015/05/19 21:36:44 joerg Exp $ */
+/* from: $NetBSD: realpath.c,v 1.1.1.3 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1995
@@ -52,24 +52,40 @@
# include <unistd.h>
#endif
+#ifndef __restrict
+# define __restrict /* restrict */
+#endif
+
/*
- * char *realpath(const char *path, char resolved[MAXPATHLEN]);
+ * char *realpath(const char *path, char *resolved);
*
* Find the real name of path, by removing all ".", ".." and symlink
* components. Returns (resolved) on success, or (NULL) on failure,
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(const char *path, char *resolved)
+realpath(const char * __restrict path, char * __restrict resolved)
{
struct stat sb;
- int idx = 0, n, nlnk = 0;
+ int idx = 0, nlnk = 0;
const char *q;
- char *p, wbuf[2][MAXPATHLEN];
+ char *p, wbuf[2][MAXPATHLEN], *fres;
size_t len;
+ ssize_t n;
+
+ /* POSIX sez we must test for this */
+ if (path == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (resolved == NULL) {
+ fres = resolved = malloc(MAXPATHLEN);
+ if (resolved == NULL)
+ return NULL;
+ } else
+ fres = NULL;
- if (!path || !resolved || path == resolved)
- return (NULL);
/*
* Build real path one by one with paying an attention to .,
@@ -82,10 +98,10 @@ realpath(const char *path, char *resolved)
*/
p = resolved;
- if (*path == 0) {
- *p = 0;
+ if (*path == '\0') {
+ *p = '\0';
errno = ENOENT;
- return (NULL);
+ goto out;
}
/* If relative path, start from current working directory. */
@@ -93,8 +109,8 @@ realpath(const char *path, char *resolved)
/* check for resolved pointer to appease coverity */
if (resolved && getcwd(resolved, MAXPATHLEN) == NULL) {
p[0] = '.';
- p[1] = 0;
- return (NULL);
+ p[1] = '\0';
+ goto out;
}
len = strlen(resolved);
if (len > 1)
@@ -106,18 +122,18 @@ loop:
while (*path == '/')
path++;
- if (*path == 0) {
+ if (*path == '\0') {
if (p == resolved)
*p++ = '/';
- *p = 0;
- return (resolved);
+ *p = '\0';
+ return resolved;
}
/* Find the end of this component. */
q = path;
do
q++;
- while (*q != '/' && *q != 0);
+ while (*q != '/' && *q != '\0');
/* Test . or .. */
if (path[0] == '.') {
@@ -129,7 +145,7 @@ loop:
/* Trim the last component. */
if (p != resolved)
while (*--p != '/')
- ;
+ continue;
path = q;
goto loop;
}
@@ -140,39 +156,39 @@ loop:
errno = ENAMETOOLONG;
if (p == resolved)
*p++ = '/';
- *p = 0;
- return (NULL);
+ *p = '\0';
+ goto out;
}
p[0] = '/';
memcpy(&p[1], path,
/* LINTED We know q > path. */
q - path);
- p[1 + q - path] = 0;
+ p[1 + q - path] = '\0';
/*
* If this component is a symlink, toss it and prepend link
* target to unresolved path.
*/
- if (lstat(resolved, &sb) == -1) {
- return (NULL);
- }
+ if (lstat(resolved, &sb) == -1)
+ goto out;
+
if (S_ISLNK(sb.st_mode)) {
if (nlnk++ >= MAXSYMLINKS) {
errno = ELOOP;
- return (NULL);
+ goto out;
}
n = readlink(resolved, wbuf[idx], sizeof(wbuf[0]) - 1);
if (n < 0)
- return (NULL);
+ goto out;
if (n == 0) {
errno = ENOENT;
- return (NULL);
+ goto out;
}
/* Append unresolved path to link target and switch to it. */
if (n + (len = strlen(q)) + 1 > sizeof(wbuf[0])) {
errno = ENAMETOOLONG;
- return (NULL);
+ goto out;
}
memcpy(&wbuf[idx][n], q, len + 1);
path = wbuf[idx];
@@ -185,12 +201,15 @@ loop:
}
if (*q == '/' && !S_ISDIR(sb.st_mode)) {
errno = ENOTDIR;
- return (NULL);
+ goto out;
}
/* Advance both resolved and unresolved path. */
p += 1 + q - path;
path = q;
goto loop;
+out:
+ free(fres);
+ return NULL;
}
#endif
diff --git a/devel/bmake/files/str.c b/devel/bmake/files/str.c
index 0991dc838d8..2f521979e8c 100644
--- a/devel/bmake/files/str.c
+++ b/devel/bmake/files/str.c
@@ -1,4 +1,4 @@
-/* $NetBSD: str.c,v 1.1.1.5 2009/09/18 20:55:31 joerg Exp $ */
+/* $NetBSD: str.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: str.c,v 1.1.1.5 2009/09/18 20:55:31 joerg Exp $";
+static char rcsid[] = "$NetBSD: str.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
#else
-__RCSID("$NetBSD: str.c,v 1.1.1.5 2009/09/18 20:55:31 joerg Exp $");
+__RCSID("$NetBSD: str.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -145,7 +145,7 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
const char *p;
int len;
int argmax = 50, curlen = 0;
- char **argv = bmake_malloc((argmax + 1) * sizeof(char *));
+ char **argv;
/* skip leading space chars. */
for (; *str == ' ' || *str == '\t'; ++str)
@@ -156,6 +156,12 @@ brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
*buffer = bmake_malloc(curlen = len);
/*
+ * initial argmax based on len
+ */
+ argmax = MAX((len / 5), 50);
+ argv = bmake_malloc((argmax + 1) * sizeof(char *));
+
+ /*
* copy the string; at the same time, parse backslashes,
* quotes and build the argument list.
*/
@@ -319,6 +325,8 @@ Str_FindSubstring(const char *string, const char *substring)
* matching operation permits the following special characters in the
* pattern: *?\[] (see the man page for details on what these mean).
*
+ * XXX this function does not detect or report malformed patterns.
+ *
* Side effects: None.
*/
int
diff --git a/devel/bmake/files/suff.c b/devel/bmake/files/suff.c
index 32b3b4c0554..9cb14875509 100644
--- a/devel/bmake/files/suff.c
+++ b/devel/bmake/files/suff.c
@@ -1,4 +1,4 @@
-/* $NetBSD: suff.c,v 1.1.1.5 2009/09/18 20:55:31 joerg Exp $ */
+/* $NetBSD: suff.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: suff.c,v 1.1.1.5 2009/09/18 20:55:31 joerg Exp $";
+static char rcsid[] = "$NetBSD: suff.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
#else
-__RCSID("$NetBSD: suff.c,v 1.1.1.5 2009/09/18 20:55:31 joerg Exp $");
+__RCSID("$NetBSD: suff.c,v 1.1.1.6 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -1434,7 +1434,7 @@ SuffFindCmds(Src *targ, Lst slst)
* We haven't looked to see if .OPTIONAL files exist yet, so
* don't use one as the implicit source.
* This allows us to use .OPTIONAL in .depend files so make won't
- * complain "don't know how to make xxx.h' when a dependant file
+ * complain "don't know how to make xxx.h' when a dependent file
* has been moved/deleted.
*/
continue;
@@ -2058,118 +2058,124 @@ SuffFindNormalDeps(GNode *gn, Lst slst)
* children, then look for any overriding transformations they imply.
* Should we find one, we discard the one we found before.
*/
+ bottom = NULL;
+ targ = NULL;
- while (ln != NULL) {
- /*
- * Look for next possible suffix...
- */
- ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
-
- if (ln != NULL) {
- int prefLen; /* Length of the prefix */
+ if (!(gn->type & OP_PHONY)) {
+ while (ln != NULL) {
/*
- * Allocate a Src structure to which things can be transformed
+ * Look for next possible suffix...
*/
+ ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
+
+ if (ln != NULL) {
+ int prefLen; /* Length of the prefix */
+
+ /*
+ * Allocate a Src structure to which things can be transformed
+ */
+ targ = bmake_malloc(sizeof(Src));
+ targ->file = bmake_strdup(gn->name);
+ targ->suff = (Suff *)Lst_Datum(ln);
+ targ->suff->refCount++;
+ targ->node = gn;
+ targ->parent = NULL;
+ targ->children = 0;
+#ifdef DEBUG_SRC
+ targ->cp = Lst_Init(FALSE);
+#endif
+
+ /*
+ * Allocate room for the prefix, whose end is found by
+ * subtracting the length of the suffix from
+ * the end of the name.
+ */
+ prefLen = (eoname - targ->suff->nameLen) - sopref;
+ targ->pref = bmake_malloc(prefLen + 1);
+ memcpy(targ->pref, sopref, prefLen);
+ targ->pref[prefLen] = '\0';
+
+ /*
+ * Add nodes from which the target can be made
+ */
+ SuffAddLevel(srcs, targ);
+
+ /*
+ * Record the target so we can nuke it
+ */
+ (void)Lst_AtEnd(targs, targ);
+
+ /*
+ * Search from this suffix's successor...
+ */
+ ln = Lst_Succ(ln);
+ }
+ }
+
+ /*
+ * Handle target of unknown suffix...
+ */
+ if (Lst_IsEmpty(targs) && suffNull != NULL) {
+ if (DEBUG(SUFF)) {
+ fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
+ }
+
targ = bmake_malloc(sizeof(Src));
targ->file = bmake_strdup(gn->name);
- targ->suff = (Suff *)Lst_Datum(ln);
+ targ->suff = suffNull;
targ->suff->refCount++;
targ->node = gn;
targ->parent = NULL;
targ->children = 0;
+ targ->pref = bmake_strdup(sopref);
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
/*
- * Allocate room for the prefix, whose end is found by subtracting
- * the length of the suffix from the end of the name.
+ * Only use the default suffix rules if we don't have commands
+ * defined for this gnode; traditional make programs used to
+ * not define suffix rules if the gnode had children but we
+ * don't do this anymore.
*/
- prefLen = (eoname - targ->suff->nameLen) - sopref;
- targ->pref = bmake_malloc(prefLen + 1);
- memcpy(targ->pref, sopref, prefLen);
- targ->pref[prefLen] = '\0';
+ if (Lst_IsEmpty(gn->commands))
+ SuffAddLevel(srcs, targ);
+ else {
+ if (DEBUG(SUFF))
+ fprintf(debug_file, "not ");
+ }
- /*
- * Add nodes from which the target can be made
- */
- SuffAddLevel(srcs, targ);
+ if (DEBUG(SUFF))
+ fprintf(debug_file, "adding suffix rules\n");
- /*
- * Record the target so we can nuke it
- */
(void)Lst_AtEnd(targs, targ);
-
- /*
- * Search from this suffix's successor...
- */
- ln = Lst_Succ(ln);
- }
- }
-
- /*
- * Handle target of unknown suffix...
- */
- if (Lst_IsEmpty(targs) && suffNull != NULL) {
- if (DEBUG(SUFF)) {
- fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
}
- targ = bmake_malloc(sizeof(Src));
- targ->file = bmake_strdup(gn->name);
- targ->suff = suffNull;
- targ->suff->refCount++;
- targ->node = gn;
- targ->parent = NULL;
- targ->children = 0;
- targ->pref = bmake_strdup(sopref);
-#ifdef DEBUG_SRC
- targ->cp = Lst_Init(FALSE);
-#endif
-
/*
- * Only use the default suffix rules if we don't have commands
- * defined for this gnode; traditional make programs used to
- * not define suffix rules if the gnode had children but we
- * don't do this anymore.
+ * Using the list of possible sources built up from the target
+ * suffix(es), try and find an existing file/target that matches.
*/
- if (Lst_IsEmpty(gn->commands))
- SuffAddLevel(srcs, targ);
- else {
- if (DEBUG(SUFF))
- fprintf(debug_file, "not ");
- }
+ bottom = SuffFindThem(srcs, slst);
- if (DEBUG(SUFF))
- fprintf(debug_file, "adding suffix rules\n");
-
- (void)Lst_AtEnd(targs, targ);
- }
-
- /*
- * Using the list of possible sources built up from the target suffix(es),
- * try and find an existing file/target that matches.
- */
- bottom = SuffFindThem(srcs, slst);
-
- if (bottom == NULL) {
- /*
- * No known transformations -- use the first suffix found for setting
- * the local variables.
- */
- if (!Lst_IsEmpty(targs)) {
- targ = (Src *)Lst_Datum(Lst_First(targs));
+ if (bottom == NULL) {
+ /*
+ * No known transformations -- use the first suffix found
+ * for setting the local variables.
+ */
+ if (!Lst_IsEmpty(targs)) {
+ targ = (Src *)Lst_Datum(Lst_First(targs));
+ } else {
+ targ = NULL;
+ }
} else {
- targ = NULL;
+ /*
+ * Work up the transformation path to find the suffix of the
+ * target to which the transformation was made.
+ */
+ for (targ = bottom; targ->parent != NULL; targ = targ->parent)
+ continue;
}
- } else {
- /*
- * Work up the transformation path to find the suffix of the
- * target to which the transformation was made.
- */
- for (targ = bottom; targ->parent != NULL; targ = targ->parent)
- continue;
}
Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
@@ -2406,15 +2412,19 @@ Suff_FindDeps(GNode *gn)
static void
SuffFindDeps(GNode *gn, Lst slst)
{
- if (gn->type & (OP_DEPS_FOUND|OP_PHONY)) {
+ if (gn->type & OP_DEPS_FOUND) {
/*
* If dependencies already found, no need to do it again...
- * If this is a .PHONY target, we do not apply suffix rules.
*/
return;
} else {
gn->type |= OP_DEPS_FOUND;
}
+ /*
+ * Make sure we have these set, may get revised below.
+ */
+ Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
+ Var_Set(PREFIX, gn->name, gn, 0);
if (DEBUG(SUFF)) {
fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name);
diff --git a/devel/bmake/files/targ.c b/devel/bmake/files/targ.c
index 7a45320331f..e08ce1607bf 100644
--- a/devel/bmake/files/targ.c
+++ b/devel/bmake/files/targ.c
@@ -1,4 +1,4 @@
-/* $NetBSD: targ.c,v 1.1.1.6 2011/06/18 22:18:10 bsiegert Exp $ */
+/* $NetBSD: targ.c,v 1.1.1.7 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: targ.c,v 1.1.1.6 2011/06/18 22:18:10 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: targ.c,v 1.1.1.7 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: targ.c,v 1.1.1.6 2011/06/18 22:18:10 bsiegert Exp $");
+__RCSID("$NetBSD: targ.c,v 1.1.1.7 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -512,7 +512,7 @@ Targ_SetMain(GNode *gn)
}
static int
-TargPrintName(void *gnp, void *pflags __unused)
+TargPrintName(void *gnp, void *pflags MAKE_ATTR_UNUSED)
{
GNode *gn = (GNode *)gnp;
@@ -717,7 +717,7 @@ Targ_PrintNode(void *gnp, void *passp)
*-----------------------------------------------------------------------
*/
static int
-TargPrintOnlySrc(void *gnp, void *dummy __unused)
+TargPrintOnlySrc(void *gnp, void *dummy MAKE_ATTR_UNUSED)
{
GNode *gn = (GNode *)gnp;
if (!OP_NOP(gn->type))
@@ -790,7 +790,7 @@ Targ_PrintGraph(int pass)
*-----------------------------------------------------------------------
*/
static int
-TargPropagateNode(void *gnp, void *junk __unused)
+TargPropagateNode(void *gnp, void *junk MAKE_ATTR_UNUSED)
{
GNode *gn = (GNode *)gnp;
diff --git a/devel/bmake/files/unit-tests/Makefile.in b/devel/bmake/files/unit-tests/Makefile.in
index e5a11d643b5..4b1adc37312 100644
--- a/devel/bmake/files/unit-tests/Makefile.in
+++ b/devel/bmake/files/unit-tests/Makefile.in
@@ -1,17 +1,18 @@
-# $Id: Makefile.in,v 1.1.1.9 2011/06/18 22:18:21 bsiegert Exp $
+# $Id: Makefile.in,v 1.1.1.10 2015/05/19 21:36:45 joerg Exp $
#
-# $NetBSD: Makefile.in,v 1.1.1.9 2011/06/18 22:18:21 bsiegert Exp $
+# $NetBSD: Makefile.in,v 1.1.1.10 2015/05/19 21:36:45 joerg Exp $
#
# Unit tests for make(1)
# The main targets are:
#
# all: run all the tests
-# test: run 'all', capture output and compare to expected results
+# test: run 'all', and compare to expected results
# accept: move generated output to expected results
#
# Adding a test case.
# Each feature should get its own set of tests in its own suitably
-# named makefile which should be added to SUBFILES to hook it in.
+# named makefile (*.mk), with its own set of expected results (*.exp),
+# and it should be added to the TESTNAMES list.
#
srcdir= @srcdir@
@@ -19,17 +20,21 @@ srcdir= @srcdir@
.MAIN: all
UNIT_TESTS:= ${srcdir}
+.PATH: ${UNIT_TESTS}
-# Simple sub-makefiles - we run them as a black box
-# keep the list sorted.
-SUBFILES= \
+# Each test is in a sub-makefile.
+# Keep the list sorted.
+TESTNAMES= \
comment \
cond1 \
+ cond2 \
error \
export \
export-all \
+ export-env \
doterror \
dotwait \
+ forloop \
forsubst \
hash \
misc \
@@ -39,28 +44,44 @@ SUBFILES= \
modorder \
modts \
modword \
+ order \
posix \
qequals \
+ sunshcmd \
sysv \
ternary \
unexport \
unexport-env \
- varcmd
+ varcmd \
+ varmisc \
+ varshell
-all: ${SUBFILES}
+# these tests were broken by referting POSIX chanegs
+STRICT_POSIX_TESTS = \
+ escape \
+ impsrc \
+ phony-end \
+ posix1 \
+ suffixes
+# Override make flags for certain tests
flags.doterror=
+flags.order=-j1
-# the tests are actually done with sub-makes.
-.PHONY: ${SUBFILES}
-.PRECIOUS: ${SUBFILES}
-${SUBFILES}:
- -@${.MAKE} ${flags.$@:U-k} -f ${UNIT_TESTS}/$@
+OUTFILES= ${TESTNAMES:S/$/.out/}
-clean:
- rm -f *.out *.fail *.core
+all: ${OUTFILES}
-.-include <bsd.obj.mk>
+CLEANFILES += *.rawout *.out *.status *.tmp *.core *.tmp
+CLEANFILES += obj*.[och] lib*.a # posix1.mk
+CLEANFILES += issue* .[ab]* # suffixes.mk
+CLEANRECURSIVE += dir dummy # posix1.mk
+
+clean:
+ rm -f ${CLEANFILES}
+.if !empty(CLEANRECURSIVE)
+ rm -rf ${CLEANRECURSIVE}
+.endif
TEST_MAKE?= ${.MAKE}
TOOL_SED?= sed
@@ -68,27 +89,63 @@ TOOL_TR?= tr
TOOL_DIFF?= diff
DIFF_FLAGS?= @diff_u@
+.if defined(.PARSEDIR)
# ensure consistent results from sort(1)
LC_ALL= C
LANG= C
.export LANG LC_ALL
+.endif
+
+# some tests need extra post-processing
+SED_CMDS.varshell = -e 's,^[a-z]*sh: ,,' \
+ -e '/command/s,No such.*,not found,'
+
+# the tests are actually done with sub-makes.
+.SUFFIXES: .mk .rawout .out
+.mk.rawout:
+ @echo ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC}
+ -@cd ${.OBJDIR} && \
+ { ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC} \
+ 2>&1 ; echo $$? >${.TARGET:R}.status ; } > ${.TARGET}.tmp
+ @mv ${.TARGET}.tmp ${.TARGET}
-# The driver.
# We always pretend .MAKE was called 'make'
# and strip ${.CURDIR}/ from the output
# and replace anything after 'stopped in' with unit-tests
# so the results can be compared.
-test:
- @echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
- @cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
- ${TOOL_TR} -d '\015' | \
- ${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \
- -e '/stopped/s, /.*, unit-tests,' \
- -e 's,${.CURDIR:C/\./\\\./g}/,,g' \
- -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \
- tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; }
- ${TOOL_DIFF} ${DIFF_FLAGS} ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out
+.rawout.out:
+ @echo postprocess ${.TARGET}
+ @${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[][0-9]*:,make:,' \
+ -e 's,${TEST_MAKE:C/\./\\\./g},make,' \
+ -e '/stopped/s, /.*, unit-tests,' \
+ -e 's,${.CURDIR:C/\./\\\./g}/,,g' \
+ -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' ${SED_CMDS.${.TARGET:T:R}} \
+ < ${.IMPSRC} > ${.TARGET}.tmp
+ @echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp
+ @mv ${.TARGET}.tmp ${.TARGET}
+
+# Compare all output files
+test: ${OUTFILES} .PHONY
+ @failed= ; \
+ for test in ${TESTNAMES}; do \
+ ${TOOL_DIFF} -u ${UNIT_TESTS}/$${test}.exp $${test}.out \
+ || failed="$${failed}$${failed:+ }$${test}" ; \
+ done ; \
+ if [ -n "$${failed}" ]; then \
+ echo "Failed tests: $${failed}" ; false ; \
+ else \
+ echo "All tests passed" ; \
+ fi
accept:
- mv test.out ${srcdir}/test.exp
+ @for test in ${TESTNAMES}; do \
+ cmp -s ${UNIT_TESTS}/$${test}.exp $${test}.out \
+ || { echo "Replacing $${test}.exp" ; \
+ cp $${test}.out ${UNIT_TESTS}/$${test}.exp ; } \
+ done
+
+.if exists(${TEST_MAKE})
+${TESTNAMES:S/$/.rawout/}: ${TEST_MAKE}
+.endif
+.-include <obj.mk>
diff --git a/devel/bmake/files/unit-tests/comment.exp b/devel/bmake/files/unit-tests/comment.exp
new file mode 100644
index 00000000000..9a97df0b732
--- /dev/null
+++ b/devel/bmake/files/unit-tests/comment.exp
@@ -0,0 +1,5 @@
+comment testing start
+this is foo
+This is how a comment looks: # comment
+comment testing done
+exit status 0
diff --git a/devel/bmake/files/unit-tests/comment.mk b/devel/bmake/files/unit-tests/comment.mk
new file mode 100644
index 00000000000..7dd7dbbe28b
--- /dev/null
+++ b/devel/bmake/files/unit-tests/comment.mk
@@ -0,0 +1,31 @@
+# This is a comment
+.if ${MACHINE_ARCH} == something
+FOO=bar
+.endif
+
+#\
+ Multiline comment
+
+BAR=# defined
+FOOBAR= # defined
+
+# This is an escaped comment \
+that keeps going until the end of this line
+
+# Another escaped comment \
+that \
+goes \
+on
+
+# This is NOT an escaped comment due to the double backslashes \\
+all: hi foo bar
+ @echo comment testing done
+
+hi:
+ @echo comment testing start
+
+foo:
+ @echo this is $@
+
+bar:
+ @echo This is how a comment looks: '# comment'
diff --git a/devel/bmake/files/unit-tests/cond1.exp b/devel/bmake/files/unit-tests/cond1.exp
new file mode 100644
index 00000000000..701d504fcc6
--- /dev/null
+++ b/devel/bmake/files/unit-tests/cond1.exp
@@ -0,0 +1,23 @@
+make: "cond1.mk" line 75: warning: extra else
+make: "cond1.mk" line 85: warning: extra else
+2 is prime
+A='other' B='unknown' C='clever' o='no,no'
+Passed:
+ var
+ ("var")
+ (var != var)
+ var != var
+ !((var != var) && defined(name))
+ var == quoted
+
+1 is not prime
+2 is prime
+3 is prime
+4 is not prime
+5 is prime
+
+make: warning: String comparison operator should be either == or !=
+make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No
+
+OK
+exit status 0
diff --git a/devel/bmake/files/unit-tests/cond1.mk b/devel/bmake/files/unit-tests/cond1.mk
new file mode 100644
index 00000000000..f398b369abd
--- /dev/null
+++ b/devel/bmake/files/unit-tests/cond1.mk
@@ -0,0 +1,109 @@
+# $Id: cond1.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# hard code these!
+TEST_UNAME_S= NetBSD
+TEST_UNAME_M= sparc
+TEST_MACHINE= i386
+
+.if ${TEST_UNAME_S}
+Ok=var,
+.endif
+.if ("${TEST_UNAME_S}")
+Ok+=(\"var\"),
+.endif
+.if (${TEST_UNAME_M} != ${TEST_MACHINE})
+Ok+=(var != var),
+.endif
+.if ${TEST_UNAME_M} != ${TEST_MACHINE}
+Ok+= var != var,
+.endif
+.if !((${TEST_UNAME_M} != ${TEST_MACHINE}) && defined(X))
+Ok+= !((var != var) && defined(name)),
+.endif
+# from bsd.obj.mk
+MKOBJ?=no
+.if ${MKOBJ} == "no"
+o= no
+Ok+= var == "quoted",
+.else
+.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
+.if defined(notMAKEOBJDIRPREFIX)
+o=${MAKEOBJDIRPREFIX}${__curdir}
+.else
+o= ${MAKEOBJDIR}
+.endif
+.endif
+o= o
+.endif
+
+# repeat the above to check we get the same result
+.if ${MKOBJ} == "no"
+o2= no
+.else
+.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
+.if defined(notMAKEOBJDIRPREFIX)
+o2=${MAKEOBJDIRPREFIX}${__curdir}
+.else
+o2= ${MAKEOBJDIR}
+.endif
+.endif
+o2= o
+.endif
+
+PRIMES=2 3 5 7 11
+NUMBERS=1 2 3 4 5
+
+n=2
+.if ${PRIMES:M$n} == ""
+X=not
+.else
+X=
+.endif
+
+.if ${MACHINE_ARCH} == no-such
+A=one
+.else
+.if ${MACHINE_ARCH} == not-this
+.if ${MACHINE_ARCH} == something-else
+A=unlikely
+.else
+A=no
+.endif
+.endif
+A=other
+# We expect an extra else warning - we're not skipping here
+.else
+A=this should be an error
+.endif
+
+.if $X != ""
+.if $X == not
+B=one
+.else
+B=other
+# We expect an extra else warning - we are skipping here
+.else
+B=this should be an error
+.endif
+.else
+B=unknown
+.endif
+
+.if "quoted" == quoted
+C=clever
+.else
+C=dim
+.endif
+
+.if defined(nosuch) && ${nosuch:Mx} != ""
+# this should not happen
+.info nosuch is x
+.endif
+
+all:
+ @echo "$n is $X prime"
+ @echo "A='$A' B='$B' C='$C' o='$o,${o2}'"
+ @echo "Passed:${.newline} ${Ok:S/,/${.newline}/}"
+ @echo "${NUMBERS:@n@$n is ${("${PRIMES:M$n}" == ""):?not:} prime${.newline}@}"
+ @echo "${"${DoNotQuoteHere:U0}" > 0:?OK:No}"
+ @echo "${${NoSuchNumber:U42} > 0:?OK:No}"
diff --git a/devel/bmake/files/unit-tests/cond2.exp b/devel/bmake/files/unit-tests/cond2.exp
new file mode 100644
index 00000000000..22e76a5b2c9
--- /dev/null
+++ b/devel/bmake/files/unit-tests/cond2.exp
@@ -0,0 +1,7 @@
+make: Bad conditional expression ` == "empty"' in == "empty"?oops:ok
+make: "cond2.mk" line 13: Malformed conditional ({TEST_TYPO} == "Ok")
+TEST_NOT_SET is empty or not defined
+make: "cond2.mk" line 20: Malformed conditional (${TEST_NOT_SET} == "empty")
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+exit status 1
diff --git a/devel/bmake/files/unit-tests/cond2.mk b/devel/bmake/files/unit-tests/cond2.mk
new file mode 100644
index 00000000000..e396fc308e7
--- /dev/null
+++ b/devel/bmake/files/unit-tests/cond2.mk
@@ -0,0 +1,25 @@
+# $Id: cond2.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+TEST_UNAME_S= NetBSD
+
+# this should be ok
+X:= ${${TEST_UNAME_S} == "NetBSD":?Ok:fail}
+.if $X == "Ok"
+Y= good
+.endif
+# expect: Bad conditional expression ` == "empty"' in == "empty"?oops:ok
+X:= ${${TEST_NOT_SET} == "empty":?oops:ok}
+# expect: Malformed conditional ({TEST_TYPO} == "Ok")
+.if {TEST_TYPO} == "Ok"
+Y= oops
+.endif
+.if empty(TEST_NOT_SET)
+Y!= echo TEST_NOT_SET is empty or not defined >&2; echo
+.endif
+# expect: Malformed conditional (${TEST_NOT_SET} == "empty")
+.if ${TEST_NOT_SET} == "empty"
+Y= oops
+.endif
+
+all:
+ @echo $@
diff --git a/devel/bmake/files/unit-tests/doterror.exp b/devel/bmake/files/unit-tests/doterror.exp
new file mode 100644
index 00000000000..0447a519344
--- /dev/null
+++ b/devel/bmake/files/unit-tests/doterror.exp
@@ -0,0 +1,9 @@
+At first, I am
+happy
+and now: sad
+.ERROR: Looks like 'sad' is upset.
+*** Error code 1
+
+Stop.
+make: stopped in unit-tests
+exit status 1
diff --git a/devel/bmake/files/unit-tests/doterror.mk b/devel/bmake/files/unit-tests/doterror.mk
new file mode 100644
index 00000000000..24983c0db6b
--- /dev/null
+++ b/devel/bmake/files/unit-tests/doterror.mk
@@ -0,0 +1,20 @@
+# $Id: doterror.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+
+.BEGIN:
+ @echo At first, I am
+
+.END:
+ @echo not reached
+
+.ERROR:
+ @echo "$@: Looks like '${.ERROR_TARGET}' is upset."
+
+all: happy sad
+
+happy:
+ @echo $@
+
+sad:
+ @echo and now: $@; exit 1
+
diff --git a/devel/bmake/files/unit-tests/dotwait.exp b/devel/bmake/files/unit-tests/dotwait.exp
new file mode 100644
index 00000000000..6bf96e301c1
--- /dev/null
+++ b/devel/bmake/files/unit-tests/dotwait.exp
@@ -0,0 +1,30 @@
+simple.1
+simple.1
+simple.2
+simple.2
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.1.*
+recursive.1.99
+recursive.1.99
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.1.*
+recursive.2.99
+recursive.2.99
+shared.0
+shared.0
+shared.1.99
+shared.1.99
+shared.2.1
+shared.2.1
+shared.2.99
+shared.2.99
+make: Graph cycles through `cycle.2.99'
+make: Graph cycles through `cycle.2.98'
+make: Graph cycles through `cycle.2.97'
+cycle.1.99
+cycle.1.99
+exit status 0
diff --git a/devel/bmake/files/unit-tests/dotwait.mk b/devel/bmake/files/unit-tests/dotwait.mk
new file mode 100644
index 00000000000..b6cde7d31de
--- /dev/null
+++ b/devel/bmake/files/unit-tests/dotwait.mk
@@ -0,0 +1,61 @@
+# $NetBSD: dotwait.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE}
+
+TESTS= simple recursive shared cycle
+PAUSE= sleep 1
+
+# Use a .for loop rather than dependencies here, to ensure
+# that the tests are run one by one, with parallelism
+# only within tests.
+# Ignore "--- target ---" lines printed by parallel make.
+all:
+.for t in ${TESTS}
+ @${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- "
+.endfor
+
+#
+# Within each test, the names of the sub-targets follow these
+# conventions:
+# * If it's expected that two or more targets may be made in parallel,
+# then the target names will differ only in an alphabetic component
+# such as ".a" or ".b".
+# * If it's expected that two or more targets should be made in sequence
+# then the target names will differ in numeric components, such that
+# lexical ordering of the target names matches the expected order
+# in which the targets should be made.
+#
+# Targets may echo ${PARALLEL_TARG} to print a modified version
+# of their own name, in which alphabetic components like ".a" or ".b"
+# are converted to ".*". Two targets that are expected to
+# be made in parallel will thus print the same strings, so that the
+# output is independent of the order in which these targets are made.
+#
+PARALLEL_TARG= ${.TARGET:C/\.[a-z]/.*/g:Q}
+.DEFAULT:
+ @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
+_ECHOUSE: .USE
+ @echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
+
+# simple: no recursion, no cycles
+simple: simple.1 .WAIT simple.2
+
+# recursive: all children of the left hand side of the .WAIT
+# must be made before any child of the right hand side.
+recursive: recursive.1.99 .WAIT recursive.2.99
+recursive.1.99: recursive.1.1.a recursive.1.1.b _ECHOUSE
+recursive.2.99: recursive.2.1.a recursive.2.1.b _ECHOUSE
+
+# shared: both shared.1.99 and shared.2.99 depend on shared.0.
+# shared.0 must be made first, even though it is a child of
+# the right hand side of the .WAIT.
+shared: shared.1.99 .WAIT shared.2.99
+shared.1.99: shared.0 _ECHOUSE
+shared.2.99: shared.2.1 shared.0 _ECHOUSE
+
+# cycle: the cyclic dependency must not cause infinite recursion
+# leading to stack overflow and a crash.
+cycle: cycle.1.99 .WAIT cycle.2.99
+cycle.2.99: cycle.2.98 _ECHOUSE
+cycle.2.98: cycle.2.97 _ECHOUSE
+cycle.2.97: cycle.2.99 _ECHOUSE
diff --git a/devel/bmake/files/unit-tests/error.exp b/devel/bmake/files/unit-tests/error.exp
new file mode 100644
index 00000000000..a2bf71b7127
--- /dev/null
+++ b/devel/bmake/files/unit-tests/error.exp
@@ -0,0 +1,4 @@
+make: "error.mk" line 3: just FYI
+make: "error.mk" line 4: warning: this could be serious
+make: "error.mk" line 5: this is fatal
+exit status 1
diff --git a/devel/bmake/files/unit-tests/error.mk b/devel/bmake/files/unit-tests/error.mk
new file mode 100644
index 00000000000..5bda812b604
--- /dev/null
+++ b/devel/bmake/files/unit-tests/error.mk
@@ -0,0 +1,10 @@
+# $Id: error.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+.info just FYI
+.warning this could be serious
+.error this is fatal
+
+all:
+
+.info.html:
+ @echo this should be ignored
diff --git a/devel/bmake/files/unit-tests/escape.exp b/devel/bmake/files/unit-tests/escape.exp
new file mode 100644
index 00000000000..6238e27b019
--- /dev/null
+++ b/devel/bmake/files/unit-tests/escape.exp
@@ -0,0 +1,104 @@
+var-1bs
+printf "%s=:%s:\n" VAR1BS 111\\111; printf "%s=:%s:\n" VAR1BSa 111\\aaa; printf "%s=:%s:\n" VAR1BSA 111\\aaa; printf "%s=:%s:\n" VAR1BSda 111\\\$\{a\}; printf "%s=:%s:\n" VAR1BSdA 111\\\$\{A\}; printf "%s=:%s:\n" VAR1BSc 111\#\ backslash\ escapes\ comment\ char,\ so\ this\ is\ part\ of\ the\ value; printf "%s=:%s:\n" VAR1BSsc 111\\\ ;
+VAR1BS=:111\111:
+VAR1BSa=:111\aaa:
+VAR1BSA=:111\aaa:
+VAR1BSda=:111\${a}:
+VAR1BSdA=:111\${A}:
+VAR1BSc=:111# backslash escapes comment char, so this is part of the value:
+VAR1BSsc=:111\ :
+var-2bs
+printf "%s=:%s:\n" VAR2BS 222\\\\222; printf "%s=:%s:\n" VAR2BSa 222\\\\aaa; printf "%s=:%s:\n" VAR2BSA 222\\\\aaa; printf "%s=:%s:\n" VAR2BSda 222\\\\\$\{a\}; printf "%s=:%s:\n" VAR2BSdA 222\\\\\$\{A\}; printf "%s=:%s:\n" VAR2BSc 222\\\\; printf "%s=:%s:\n" VAR2BSsc 222\\\\;
+VAR2BS=:222\\222:
+VAR2BSa=:222\\aaa:
+VAR2BSA=:222\\aaa:
+VAR2BSda=:222\\${a}:
+VAR2BSdA=:222\\${A}:
+VAR2BSc=:222\\:
+VAR2BSsc=:222\\:
+var-1bsnl
+printf "%s=:%s:\n" VAR1BSNL 111\ 111; printf "%s=:%s:\n" VAR1BSNLa 111\ aaa; printf "%s=:%s:\n" VAR1BSNLA 111\ aaa; printf "%s=:%s:\n" VAR1BSNLda 111\ \$\{a\}; printf "%s=:%s:\n" VAR1BSNLdA 111\ \$\{A\}; printf "%s=:%s:\n" VAR1BSNLc 111; printf "%s=:%s:\n" VAR1BSNLsc 111;
+VAR1BSNL=:111 111:
+VAR1BSNLa=:111 aaa:
+VAR1BSNLA=:111 aaa:
+VAR1BSNLda=:111 ${a}:
+VAR1BSNLdA=:111 ${A}:
+VAR1BSNLc=:111:
+VAR1BSNLsc=:111:
+var-2bsnl
+printf "%s=:%s:\n" VAR2BSNL 222\\\\; printf "%s=:%s:\n" VAR2BSNLa 222\\\\; printf "%s=:%s:\n" VAR2BSNLA 222\\\\; printf "%s=:%s:\n" VAR2BSNLda 222\\\\; printf "%s=:%s:\n" VAR2BSNLdA 222\\\\; printf "%s=:%s:\n" VAR2BSNLc 222\\\\; printf "%s=:%s:\n" VAR2BSNLsc 222\\\\;
+VAR2BSNL=:222\\:
+VAR2BSNLa=:222\\:
+VAR2BSNLA=:222\\:
+VAR2BSNLda=:222\\:
+VAR2BSNLdA=:222\\:
+VAR2BSNLc=:222\\:
+VAR2BSNLsc=:222\\:
+var-3bsnl
+printf "%s=:%s:\n" VAR3BSNL 333\\\\\ 333=; printf "%s=:%s:\n" VAR3BSNLa 333\\\\\ aaa=; printf "%s=:%s:\n" VAR3BSNLA 333\\\\\ aaa=; printf "%s=:%s:\n" VAR3BSNLda 333\\\\\ \$\{a\}=; printf "%s=:%s:\n" VAR3BSNLdA 333\\\\\ \$\{A\}=; printf "%s=:%s:\n" VAR3BSNLc 333\\\\; printf "%s=:%s:\n" VAR3BSNLsc 333\\\\;
+VAR3BSNL=:333\\ 333=:
+VAR3BSNLa=:333\\ aaa=:
+VAR3BSNLA=:333\\ aaa=:
+VAR3BSNLda=:333\\ ${a}=:
+VAR3BSNLdA=:333\\ ${A}=:
+VAR3BSNLc=:333\\:
+VAR3BSNLsc=:333\\:
+var-1bsnl-space
+printf "%s=:%s:\n" VAR1BSNL00 first\ line; printf "%s=:%s:\n" VAR1BSNL0 first\ line\ no\ space\ on\ second\ line; printf "%s=:%s:\n" VAR1BSNLs first\ line\ one\ space\ on\ second\ line; printf "%s=:%s:\n" VAR1BSNLss first\ line\ two\ spaces\ on\ second\ line; printf "%s=:%s:\n" VAR1BSNLt first\ line\ one\ tab\ on\ second\ line; printf "%s=:%s:\n" VAR1BSNLtt first\ line\ two\ tabs\ on\ second\ line; printf "%s=:%s:\n" VAR1BSNLxx first\ line\ many\ spaces\ and\ tabs\ \[\ \ \ \ \]\ on\ second\ line;
+VAR1BSNL00=:first line:
+VAR1BSNL0=:first line no space on second line:
+VAR1BSNLs=:first line one space on second line:
+VAR1BSNLss=:first line two spaces on second line:
+VAR1BSNLt=:first line one tab on second line:
+VAR1BSNLtt=:first line two tabs on second line:
+VAR1BSNLxx=:first line many spaces and tabs [ ] on second line:
+cmd-1bsnl
+echo :'first line\
+#second line without space\
+third line':
+:first line\
+#second line without space\
+third line:
+echo :'first line\
+ second line spaces should be retained':
+:first line\
+ second line spaces should be retained:
+echo :'first line\
+second line tab should be elided':
+:first line\
+second line tab should be elided:
+echo :'first line\
+ only one tab should be elided, second tab remains'
+:first line\
+ only one tab should be elided, second tab remains
+cmd-1bsnl-eof
+echo :'command ending with backslash-newline'; \
+
+:command ending with backslash-newline
+cmd-2bsnl
+echo take one\\
+take one\
+echo take two\\
+take two\
+echo take three\\
+take three\
+cmd-3bsnl
+echo :'first line\\\
+#second line without space\\\
+third line':
+:first line\\\
+#second line without space\\\
+third line:
+echo :'first line\\\
+ second line spaces should be retained':
+:first line\\\
+ second line spaces should be retained:
+echo :'first line\\\
+second line tab should be elided':
+:first line\\\
+second line tab should be elided:
+echo :'first line\\\
+ only one tab should be elided, second tab remains'
+:first line\\\
+ only one tab should be elided, second tab remains
+exit status 0
diff --git a/devel/bmake/files/unit-tests/escape.mk b/devel/bmake/files/unit-tests/escape.mk
new file mode 100644
index 00000000000..ede9d9e7254
--- /dev/null
+++ b/devel/bmake/files/unit-tests/escape.mk
@@ -0,0 +1,246 @@
+# $Id: escape.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# Test backslash escaping.
+
+# Extracts from the POSIX 2008 specification
+# <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html>:
+#
+# Comments start with a <number-sign> ( '#' ) and continue until an
+# unescaped <newline> is reached.
+#
+# When an escaped <newline> (one preceded by a <backslash>) is found
+# anywhere in the makefile except in a command line, an include
+# line, or a line immediately preceding an include line, it shall
+# be replaced, along with any leading white space on the following
+# line, with a single <space>.
+#
+# When an escaped <newline> is found in a command line in a
+# makefile, the command line shall contain the <backslash>, the
+# <newline>, and the next line, except that the first character of
+# the next line shall not be included if it is a <tab>.
+#
+# When an escaped <newline> is found in an include line or in a
+# line immediately preceding an include line, the behavior is
+# unspecified.
+#
+# Notice that the behaviour of <backslash><backslash> or
+# <backslash><anything other than newline> is not mentioned. I think
+# this implies that <backslash> should be taken literally everywhere
+# except before <newline>.
+#
+# Our practice, despite what POSIX might say, is that "\#"
+# in a variable assignment stores "#" as part of the value.
+# The "\" is not taken literally, and the "#" does not begin a comment.
+#
+# Also, our practice is that an even number of backslashes before a
+# newline in a variable assignment simply stores the backslashes as part
+# of the value, and treats the newline as though it was not escaped.
+# Similarly, ann even number of backslashes before a newline in a
+# command simply uses the backslashes as part of the command test, but
+# does not escape the newline. This is compatible with GNU make.
+
+all: .PHONY
+# We will add dependencies like "all: yet-another-test" later.
+
+# Some variables to be expanded in tests
+#
+a = aaa
+A = ${a}
+
+# Backslash at end of line in a comment\
+should continue the comment. \
+# This is also tested in comment.mk.
+
+__printvars: .USE .MADE
+ @echo ${.TARGET}
+ ${.ALLSRC:@v@ printf "%s=:%s:\n" ${v:Q} ${${v}:Q}; @}
+
+# Embedded backslash in variable should be taken literally.
+#
+VAR1BS = 111\111
+VAR1BSa = 111\${a}
+VAR1BSA = 111\${A}
+VAR1BSda = 111\$${a}
+VAR1BSdA = 111\$${A}
+VAR1BSc = 111\# backslash escapes comment char, so this is part of the value
+VAR1BSsc = 111\ # This is a comment. Value ends with <backslash><space>
+
+all: var-1bs
+var-1bs: .PHONY __printvars VAR1BS VAR1BSa VAR1BSA VAR1BSda VAR1BSdA \
+ VAR1BSc VAR1BSsc
+
+# Double backslash in variable should be taken as two literal backslashes.
+#
+VAR2BS = 222\\222
+VAR2BSa = 222\\${a}
+VAR2BSA = 222\\${A}
+VAR2BSda = 222\\$${a}
+VAR2BSdA = 222\\$${A}
+VAR2BSc = 222\\# backslash does not escape comment char, so this is a comment
+VAR2BSsc = 222\\ # This is a comment. Value ends with <backslash><backslash>
+
+all: var-2bs
+var-2bs: .PHONY __printvars VAR2BS VAR2BSa VAR2BSA VAR2BSda VAR2BSdA \
+ VAR2BSc VAR2BSsc
+
+# Backslash-newline in a variable setting is replaced by a single space.
+#
+VAR1BSNL = 111\
+111
+VAR1BSNLa = 111\
+${a}
+VAR1BSNLA = 111\
+${A}
+VAR1BSNLda = 111\
+$${a}
+VAR1BSNLdA = 111\
+$${A}
+VAR1BSNLc = 111\
+# this should be processed as a comment
+VAR1BSNLsc = 111\
+ # this should be processed as a comment
+
+all: var-1bsnl
+var-1bsnl: .PHONY
+var-1bsnl: .PHONY __printvars \
+ VAR1BSNL VAR1BSNLa VAR1BSNLA VAR1BSNLda VAR1BSNLdA \
+ VAR1BSNLc VAR1BSNLsc
+
+# Double-backslash-newline in a variable setting.
+# Both backslashes should be taken literally, and the newline is NOT escaped.
+#
+# The second lines below each end with '=' so that they will not
+# generate syntax errors regardless of whether or not they are
+# treated as part of the value.
+#
+VAR2BSNL = 222\\
+222=
+VAR2BSNLa = 222\\
+${a}=
+VAR2BSNLA = 222\\
+${A}=
+VAR2BSNLda = 222\\
+$${a}=
+VAR2BSNLdA = 222\\
+$${A}=
+VAR2BSNLc = 222\\
+# this should be processed as a comment
+VAR2BSNLsc = 222\\
+ # this should be processed as a comment
+
+all: var-2bsnl
+var-2bsnl: .PHONY __printvars \
+ VAR2BSNL VAR2BSNLa VAR2BSNLA VAR2BSNLda VAR2BSNLdA \
+ VAR2BSNLc VAR2BSNLsc
+
+# Triple-backslash-newline in a variable setting.
+# First two should be taken literally, and last should escape the newline.
+#
+# The second lines below each end with '=' so that they will not
+# generate syntax errors regardless of whether or not they are
+# treated as part of the value.
+#
+VAR3BSNL = 333\\\
+333=
+VAR3BSNLa = 333\\\
+${a}=
+VAR3BSNLA = 333\\\
+${A}=
+VAR3BSNLda = 333\\\
+$${a}=
+VAR3BSNLdA = 333\\\
+$${A}=
+VAR3BSNLc = 333\\\
+# this should be processed as a comment
+VAR3BSNLsc = 333\\\
+ # this should be processed as a comment
+
+all: var-3bsnl
+var-3bsnl: .PHONY __printvars \
+ VAR3BSNL VAR3BSNLa VAR3BSNLA VAR3BSNLda VAR3BSNLdA \
+ VAR3BSNLc VAR3BSNLsc
+
+# Backslash-newline in a variable setting, plus any amount of white space
+# on the next line, is replaced by a single space.
+#
+VAR1BSNL00= first line\
+
+# above line is entirely empty, and this is a comment
+VAR1BSNL0= first line\
+no space on second line
+VAR1BSNLs= first line\
+ one space on second line
+VAR1BSNLss= first line\
+ two spaces on second line
+VAR1BSNLt= first line\
+ one tab on second line
+VAR1BSNLtt= first line\
+ two tabs on second line
+VAR1BSNLxx= first line\
+ many spaces and tabs [ ] on second line
+
+all: var-1bsnl-space
+var-1bsnl-space: .PHONY __printvars \
+ VAR1BSNL00 VAR1BSNL0 VAR1BSNLs VAR1BSNLss VAR1BSNLt VAR1BSNLtt \
+ VAR1BSNLxx
+
+# Backslash-newline in a command is retained.
+#
+# The "#" in "# second line without space" makes it a comment instead
+# of a syntax error if the preceding line is parsed incorretly.
+# The ":" in "third line':" makes it look like the start of a
+# target instead of a syntax error if the first line is parsed incorrectly.
+#
+all: cmd-1bsnl
+cmd-1bsnl: .PHONY
+ @echo ${.TARGET}
+ echo :'first line\
+#second line without space\
+third line':
+ echo :'first line\
+ second line spaces should be retained':
+ echo :'first line\
+ second line tab should be elided':
+ echo :'first line\
+ only one tab should be elided, second tab remains'
+
+# When backslash-newline appears at the end of a command script,
+# both the backslash and the newline should be passed to the shell.
+# The shell should elide the backslash-newline.
+#
+all: cmd-1bsnl-eof
+cmd-1bsnl-eof:
+ @echo ${.TARGET}
+ echo :'command ending with backslash-newline'; \
+
+# above line must be blank
+
+# Double-backslash-newline in a command.
+# Both backslashes are retained, but the newline is not escaped.
+# XXX: This may differ from POSIX, but matches gmake.
+#
+# When make passes two backslashes to the shell, the shell will pass one
+# backslash to the echo commant.
+#
+all: cmd-2bsnl
+cmd-2bsnl: .PHONY
+ @echo ${.TARGET}
+ echo take one\\
+# this should be a comment
+ echo take two\\
+ echo take three\\
+
+# Triple-backslash-newline in a command is retained.
+#
+all: cmd-3bsnl
+cmd-3bsnl: .PHONY
+ @echo ${.TARGET}
+ echo :'first line\\\
+#second line without space\\\
+third line':
+ echo :'first line\\\
+ second line spaces should be retained':
+ echo :'first line\\\
+ second line tab should be elided':
+ echo :'first line\\\
+ only one tab should be elided, second tab remains'
diff --git a/devel/bmake/files/unit-tests/export-all.exp b/devel/bmake/files/unit-tests/export-all.exp
new file mode 100644
index 00000000000..e3aefd4f9e7
--- /dev/null
+++ b/devel/bmake/files/unit-tests/export-all.exp
@@ -0,0 +1,12 @@
+UT_ALL=even this gets exported
+UT_BADDIR=unit-tests
+UT_DOLLAR=This is $UT_FU
+UT_F=fine
+UT_FOO=foobar is fubar
+UT_FU=fubar
+UT_NO=all
+UT_OK=good
+UT_OKDIR=unit-tests
+UT_TEST=export-all
+UT_ZOO=hoopie
+exit status 0
diff --git a/devel/bmake/files/unit-tests/export-all.mk b/devel/bmake/files/unit-tests/export-all.mk
new file mode 100644
index 00000000000..98e861ded72
--- /dev/null
+++ b/devel/bmake/files/unit-tests/export-all.mk
@@ -0,0 +1,23 @@
+# $Id: export-all.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+UT_OK=good
+UT_F=fine
+
+# the old way to do :tA
+M_tAbad = C,.*,cd & \&\& 'pwd',:sh
+# the new
+M_tA = tA
+
+here := ${.PARSEDIR}
+
+# this will cause trouble (recursing if we let it)
+UT_BADDIR = ${${here}/../${here:T}:L:${M_tAbad}:T}
+# this will be ok
+UT_OKDIR = ${${here}/../${here:T}:L:${M_tA}:T}
+
+.export
+
+.include "export.mk"
+
+UT_TEST=export-all
+UT_ALL=even this gets exported
diff --git a/devel/bmake/files/unit-tests/export-env.exp b/devel/bmake/files/unit-tests/export-env.exp
new file mode 100644
index 00000000000..6221232a2a1
--- /dev/null
+++ b/devel/bmake/files/unit-tests/export-env.exp
@@ -0,0 +1,9 @@
+make:
+UT_TEST=export-env.mk
+UT_ENV=not-exported
+UT_EXP=not-exported
+env:
+UT_TEST=export-env.mk
+UT_ENV=exported
+UT_EXP=exported
+exit status 0
diff --git a/devel/bmake/files/unit-tests/export-env.mk b/devel/bmake/files/unit-tests/export-env.mk
new file mode 100644
index 00000000000..3832e2a2e27
--- /dev/null
+++ b/devel/bmake/files/unit-tests/export-env.mk
@@ -0,0 +1,24 @@
+# $Id: export-env.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# our normal .export, subsequent changes affect the environment
+UT_TEST=this
+.export UT_TEST
+UT_TEST:= ${.PARSEFILE}
+
+# not so with .export-env
+UT_ENV=exported
+.export-env UT_ENV
+UT_ENV=not-exported
+
+# gmake style export goes further; affects nothing but the environment
+UT_EXP=before-export
+export UT_EXP=exported
+UT_EXP=not-exported
+
+all:
+ @echo make:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=${$v};@}
+ @echo env:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=$${$v};@}
+
+
+
+
diff --git a/devel/bmake/files/unit-tests/export.exp b/devel/bmake/files/unit-tests/export.exp
new file mode 100644
index 00000000000..143771ce90a
--- /dev/null
+++ b/devel/bmake/files/unit-tests/export.exp
@@ -0,0 +1,6 @@
+UT_DOLLAR=This is $UT_FU
+UT_FOO=foobar is fubar
+UT_FU=fubar
+UT_TEST=export
+UT_ZOO=hoopie
+exit status 0
diff --git a/devel/bmake/files/unit-tests/export.mk b/devel/bmake/files/unit-tests/export.mk
new file mode 100644
index 00000000000..3c67a03a9a0
--- /dev/null
+++ b/devel/bmake/files/unit-tests/export.mk
@@ -0,0 +1,22 @@
+# $Id: export.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+UT_TEST=export
+UT_FOO=foo${BAR}
+UT_FU=fubar
+UT_ZOO=hoopie
+UT_NO=all
+# belive it or not, we expect this one to come out with $UT_FU unexpanded.
+UT_DOLLAR= This is $$UT_FU
+
+.export UT_FU UT_FOO
+.export UT_DOLLAR
+# this one will be ignored
+.export .MAKE.PID
+
+BAR=bar is ${UT_FU}
+
+.MAKE.EXPORTED+= UT_ZOO UT_TEST
+
+all:
+ @env | grep '^UT_' | sort
+
diff --git a/devel/bmake/files/unit-tests/forloop.exp b/devel/bmake/files/unit-tests/forloop.exp
new file mode 100644
index 00000000000..df14b751224
--- /dev/null
+++ b/devel/bmake/files/unit-tests/forloop.exp
@@ -0,0 +1,19 @@
+x=one
+x="two and three"
+x=four
+x="five"
+x=-I/this
+x=-I"This or that"
+x=-Ithat
+x="-DTHIS=\"this and that\""
+cfl=-I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
+a=one b="two and three"
+a=four b="five"
+a=ONE b="TWO AND THREE"
+a=FOUR b="FIVE"
+We expect an error next:
+make: "forloop.mk" line 38: Wrong number of words (9) in .for substitution list with 2 vars
+make: Fatal errors encountered -- cannot continue
+make: stopped in unit-tests
+OK
+exit status 0
diff --git a/devel/bmake/files/unit-tests/forloop.mk b/devel/bmake/files/unit-tests/forloop.mk
new file mode 100644
index 00000000000..ae693438b94
--- /dev/null
+++ b/devel/bmake/files/unit-tests/forloop.mk
@@ -0,0 +1,45 @@
+# $Id: forloop.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+all: for-loop
+
+LIST = one "two and three" four "five"
+
+.if make(for-fail)
+for-fail:
+
+XTRA_LIST = xtra
+.else
+
+.for x in ${LIST}
+X!= echo 'x=$x' >&2; echo
+.endfor
+
+CFL = -I/this -I"This or that" -Ithat "-DTHIS=\"this and that\""
+cfl=
+.for x in ${CFL}
+X!= echo 'x=$x' >&2; echo
+.if empty(cfl)
+cfl= $x
+.else
+cfl+= $x
+.endif
+.endfor
+X!= echo 'cfl=${cfl}' >&2; echo
+
+.if ${cfl} != ${CFL}
+.error ${.newline}'${cfl}' != ${.newline}'${CFL}'
+.endif
+
+.for a b in ${EMPTY}
+X!= echo 'a=$a b=$b' >&2; echo
+.endfor
+.endif
+
+.for a b in ${LIST} ${LIST:tu} ${XTRA_LIST}
+X!= echo 'a=$a b=$b' >&2; echo
+.endfor
+
+for-loop:
+ @echo We expect an error next:
+ @(cd ${.CURDIR} && ${.MAKE} -f ${MAKEFILE} for-fail) && \
+ { echo "Oops that should have failed!"; exit 1; } || echo OK
diff --git a/devel/bmake/files/unit-tests/forsubst.exp b/devel/bmake/files/unit-tests/forsubst.exp
new file mode 100644
index 00000000000..0a98c00aff3
--- /dev/null
+++ b/devel/bmake/files/unit-tests/forsubst.exp
@@ -0,0 +1,2 @@
+.for with :S;... OK
+exit status 0
diff --git a/devel/bmake/files/unit-tests/forsubst.mk b/devel/bmake/files/unit-tests/forsubst.mk
new file mode 100644
index 00000000000..4b41727e675
--- /dev/null
+++ b/devel/bmake/files/unit-tests/forsubst.mk
@@ -0,0 +1,10 @@
+# $Id: forsubst.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+all: for-subst
+
+here := ${.PARSEDIR}
+# this should not run foul of the parser
+.for file in ${.PARSEFILE}
+for-subst: ${file:S;^;${here}/;g}
+ @echo ".for with :S;... OK"
+.endfor
diff --git a/devel/bmake/files/unit-tests/hash.exp b/devel/bmake/files/unit-tests/hash.exp
new file mode 100644
index 00000000000..0a2423436e7
--- /dev/null
+++ b/devel/bmake/files/unit-tests/hash.exp
@@ -0,0 +1,9 @@
+b2af338b
+3360ac65
+7747f046
+9ca87054
+880fe816
+208fcbd3
+d5d376eb
+de41416c
+exit status 0
diff --git a/devel/bmake/files/unit-tests/hash.mk b/devel/bmake/files/unit-tests/hash.mk
new file mode 100644
index 00000000000..1ed84e776d0
--- /dev/null
+++ b/devel/bmake/files/unit-tests/hash.mk
@@ -0,0 +1,18 @@
+STR1=
+STR2= a
+STR3= ab
+STR4= abc
+STR5= abcd
+STR6= abcde
+STR7= abcdef
+STR8= abcdefghijklmnopqrstuvwxyz
+
+all:
+ @echo ${STR1:hash}
+ @echo ${STR2:hash}
+ @echo ${STR3:hash}
+ @echo ${STR4:hash}
+ @echo ${STR5:hash}
+ @echo ${STR6:hash}
+ @echo ${STR7:hash}
+ @echo ${STR8:hash}
diff --git a/devel/bmake/files/unit-tests/impsrc.exp b/devel/bmake/files/unit-tests/impsrc.exp
new file mode 100644
index 00000000000..23e8347d205
--- /dev/null
+++ b/devel/bmake/files/unit-tests/impsrc.exp
@@ -0,0 +1,13 @@
+expected: source4
+actual: source4
+expected: target1.x
+actual: target1.x
+expected: target1.y
+actual: target1.y
+expected: source1
+actual: source1
+expected: source2
+actual: source2
+expected: source1
+actual: source1
+exit status 0
diff --git a/devel/bmake/files/unit-tests/impsrc.mk b/devel/bmake/files/unit-tests/impsrc.mk
new file mode 100644
index 00000000000..d46e5c4ae5b
--- /dev/null
+++ b/devel/bmake/files/unit-tests/impsrc.mk
@@ -0,0 +1,43 @@
+# $NetBSD: impsrc.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# Does ${.IMPSRC} work properly?
+# It should be set, in order of precedence, to ${.TARGET} of:
+# 1) the implied source of a transformation rule,
+# 2) the first prerequisite from the dependency line of an explicit rule, or
+# 3) the first prerequisite of an explicit rule.
+#
+
+all: target1.z target2 target3 target4
+
+.SUFFIXES: .x .y .z
+
+.x.y: source1
+ @echo 'expected: target1.x'
+ @echo 'actual: $<'
+
+.y.z: source2
+ @echo 'expected: target1.y'
+ @echo 'actual: $<'
+
+target1.y: source3
+
+target1.x: source4
+ @echo 'expected: source4'
+ @echo 'actual: $<'
+
+target2: source1 source2
+ @echo 'expected: source1'
+ @echo 'actual: $<'
+
+target3: source1
+target3: source2 source3
+ @echo 'expected: source2'
+ @echo 'actual: $<'
+
+target4: source1
+target4:
+ @echo 'expected: source1'
+ @echo 'actual: $<'
+
+source1 source2 source3 source4:
+
diff --git a/devel/bmake/files/unit-tests/misc.exp b/devel/bmake/files/unit-tests/misc.exp
new file mode 100644
index 00000000000..39a9383953d
--- /dev/null
+++ b/devel/bmake/files/unit-tests/misc.exp
@@ -0,0 +1 @@
+exit status 0
diff --git a/devel/bmake/files/unit-tests/misc.mk b/devel/bmake/files/unit-tests/misc.mk
new file mode 100644
index 00000000000..14e087a8e47
--- /dev/null
+++ b/devel/bmake/files/unit-tests/misc.mk
@@ -0,0 +1,16 @@
+# $Id: misc.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+.if !exists(${.CURDIR}/)
+.warning ${.CURDIR}/ doesn't exist ?
+.endif
+
+.if !exists(${.CURDIR}/.)
+.warning ${.CURDIR}/. doesn't exist ?
+.endif
+
+.if !exists(${.CURDIR}/..)
+.warning ${.CURDIR}/.. doesn't exist ?
+.endif
+
+all:
+ @: all is well
diff --git a/devel/bmake/files/unit-tests/moderrs.exp b/devel/bmake/files/unit-tests/moderrs.exp
new file mode 100644
index 00000000000..cb51aa09d90
--- /dev/null
+++ b/devel/bmake/files/unit-tests/moderrs.exp
@@ -0,0 +1,16 @@
+Expect: Unknown modifier 'Z'
+make: Unknown modifier 'Z'
+VAR:Z=
+Expect: Unknown modifier 'Z'
+make: Unknown modifier 'Z'
+VAR:Z=
+Expect: Unclosed variable specification for VAR
+make: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S
+VAR:S,V,v,=Thevariable
+Expect: Unclosed variable specification for VAR
+make: Unclosed variable specification after complex modifier (expecting '}') for VAR
+VAR:S,V,v,=Thevariable
+Expect: Unclosed substitution for VAR (, missing)
+make: Unclosed substitution for VAR (, missing)
+VAR:S,V,v=
+exit status 0
diff --git a/devel/bmake/files/unit-tests/moderrs.mk b/devel/bmake/files/unit-tests/moderrs.mk
new file mode 100644
index 00000000000..ebd106fc16c
--- /dev/null
+++ b/devel/bmake/files/unit-tests/moderrs.mk
@@ -0,0 +1,31 @@
+# $Id: moderrs.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# various modifier error tests
+
+VAR=TheVariable
+# incase we have to change it ;-)
+MOD_UNKN=Z
+MOD_TERM=S,V,v
+MOD_S:= ${MOD_TERM},
+
+all: modunkn modunknV varterm vartermV modtermV
+
+modunkn:
+ @echo "Expect: Unknown modifier 'Z'"
+ @echo "VAR:Z=${VAR:Z}"
+
+modunknV:
+ @echo "Expect: Unknown modifier 'Z'"
+ @echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}"
+
+varterm:
+ @echo "Expect: Unclosed variable specification for VAR"
+ @echo VAR:S,V,v,=${VAR:S,V,v,
+
+vartermV:
+ @echo "Expect: Unclosed variable specification for VAR"
+ @echo VAR:${MOD_TERM},=${VAR:${MOD_S}
+
+modtermV:
+ @echo "Expect: Unclosed substitution for VAR (, missing)"
+ -@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}"
diff --git a/devel/bmake/files/unit-tests/modmatch.exp b/devel/bmake/files/unit-tests/modmatch.exp
new file mode 100644
index 00000000000..fcaf6c02ed6
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modmatch.exp
@@ -0,0 +1,17 @@
+LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a"
+LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a"
+LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A"
+LIB=b X_LIBS:M${LIB${LIB:tu}} is ""
+LIB=b X_LIBS:M*/lib${LIB}.a is ""
+LIB=b X_LIBS:M*/lib${LIB}.a:tu is ""
+LIB=c X_LIBS:M${LIB${LIB:tu}} is ""
+LIB=c X_LIBS:M*/lib${LIB}.a is ""
+LIB=c X_LIBS:M*/lib${LIB}.a:tu is ""
+LIB=d X_LIBS:M${LIB${LIB:tu}} is "/tmp/libd.a"
+LIB=d X_LIBS:M*/lib${LIB}.a is "/tmp/libd.a"
+LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A"
+LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a"
+LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a"
+LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A"
+Mscanner=OK
+exit status 0
diff --git a/devel/bmake/files/unit-tests/modmatch.mk b/devel/bmake/files/unit-tests/modmatch.mk
new file mode 100644
index 00000000000..48a1befb58b
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modmatch.mk
@@ -0,0 +1,25 @@
+
+X=a b c d e
+
+.for x in $X
+LIB${x:tu}=/tmp/lib$x.a
+.endfor
+
+X_LIBS= ${LIBA} ${LIBD} ${LIBE}
+
+LIB?=a
+
+var = head
+res = no
+.if !empty(var:M${:Uhead\:tail:C/:.*//})
+res = OK
+.endif
+
+all:
+ @for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done
+ @echo "Mscanner=${res}"
+
+show:
+ @echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is "${X_LIBS:M${LIB${LIB:tu}}}"'
+ @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"'
+ @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"'
diff --git a/devel/bmake/files/unit-tests/modmisc.exp b/devel/bmake/files/unit-tests/modmisc.exp
new file mode 100644
index 00000000000..e406647bc41
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modmisc.exp
@@ -0,0 +1,10 @@
+path=':/bin:/tmp::/:.:/no/such/dir:.'
+path='/bin:/tmp:/:/no/such/dir'
+path='/bin:/tmp:/:/no/such/dir'
+path='/bin':'/tmp':'/':'/no/such/dir'
+path='/bin':'/tmp':'/':'/no/such/dir'
+path_/usr/xbin=/opt/xbin/
+paths=/bin /tmp / /no/such/dir /opt/xbin
+PATHS=/BIN /TMP / /NO/SUCH/DIR /OPT/XBIN
+The answer is 42
+exit status 0
diff --git a/devel/bmake/files/unit-tests/modmisc.mk b/devel/bmake/files/unit-tests/modmisc.mk
new file mode 100644
index 00000000000..97e4202ca09
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modmisc.mk
@@ -0,0 +1,38 @@
+# $Id: modmisc.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# miscellaneous modifier tests
+
+# do not put any dirs in this list which exist on some
+# but not all target systems - an exists() check is below.
+path=:/bin:/tmp::/:.:/no/such/dir:.
+# strip cwd from path.
+MOD_NODOT=S/:/ /g:N.:ts:
+# and decorate, note that $'s need to be doubled. Also note that
+# the modifier_variable can be used with other modifiers.
+MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@
+# another mod - pretend it is more interesting
+MOD_HOMES=S,/home/,/homes/,
+MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@
+MOD_SEP=S,:, ,g
+
+all: modvar modvarloop modsysv
+
+modsysv:
+ @echo "The answer is ${libfoo.a:L:libfoo.a=42}"
+
+modvar:
+ @echo "path='${path}'"
+ @echo "path='${path:${MOD_NODOT}}'"
+ @echo "path='${path:S,home,homes,:${MOD_NODOT}}'"
+ @echo "path=${path:${MOD_NODOTX}:ts:}"
+ @echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}"
+
+.for d in ${path:${MOD_SEP}:N.} /usr/xbin
+path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/
+paths+= ${d:${MOD_OPT}:${MOD_HOMES}}
+.endfor
+
+modvarloop:
+ @echo "path_/usr/xbin=${path_/usr/xbin}"
+ @echo "paths=${paths}"
+ @echo "PATHS=${paths:tu}"
diff --git a/devel/bmake/files/unit-tests/modorder.exp b/devel/bmake/files/unit-tests/modorder.exp
new file mode 100644
index 00000000000..411742738d6
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modorder.exp
@@ -0,0 +1,11 @@
+LIST = one two three four five six seven eight nine ten
+LIST:O = eight five four nine one seven six ten three two
+LIST:Ox = Ok
+LIST:O:Ox = Ok
+LISTX = Ok
+LISTSX = Ok
+make: Bad modifier `:OX' for LIST
+BADMOD 1 = }
+make: Bad modifier `:OxXX' for LIST
+BADMOD 2 = XX}
+exit status 0
diff --git a/devel/bmake/files/unit-tests/modorder.mk b/devel/bmake/files/unit-tests/modorder.mk
new file mode 100644
index 00000000000..441a3da5ad2
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modorder.mk
@@ -0,0 +1,22 @@
+# $NetBSD: modorder.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+LIST= one two three four five six seven eight nine ten
+LISTX= ${LIST:Ox}
+LISTSX:= ${LIST:Ox}
+TEST_RESULT= && echo Ok || echo Failed
+
+# unit-tests have to produce the same results on each run
+# so we cannot actually include :Ox output.
+all:
+ @echo "LIST = ${LIST}"
+ @echo "LIST:O = ${LIST:O}"
+ # Note that 1 in every 10! trials two independently generated
+ # randomized orderings will be the same. The test framework doesn't
+ # support checking probabilistic output, so we accept that the test
+ # will incorrectly fail with probability 2.8E-7.
+ @echo "LIST:Ox = `test '${LIST:Ox}' != '${LIST:Ox}' ${TEST_RESULT}`"
+ @echo "LIST:O:Ox = `test '${LIST:O:Ox}' != '${LIST:O:Ox}' ${TEST_RESULT}`"
+ @echo "LISTX = `test '${LISTX}' != '${LISTX}' ${TEST_RESULT}`"
+ @echo "LISTSX = `test '${LISTSX}' = '${LISTSX}' ${TEST_RESULT}`"
+ @echo "BADMOD 1 = ${LIST:OX}"
+ @echo "BADMOD 2 = ${LIST:OxXX}"
diff --git a/devel/bmake/files/unit-tests/modts.exp b/devel/bmake/files/unit-tests/modts.exp
new file mode 100644
index 00000000000..cf3c91d43c0
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modts.exp
@@ -0,0 +1,33 @@
+LIST="one two three four five six"
+LIST:ts,="one,two,three,four,five,six"
+LIST:ts/:tu="ONE/TWO/THREE/FOUR/FIVE/SIX"
+LIST:ts::tu="ONE:TWO:THREE:FOUR:FIVE:SIX"
+LIST:ts:tu="ONETWOTHREEFOURFIVESIX"
+LIST:tu:ts/="ONE/TWO/THREE/FOUR/FIVE/SIX"
+LIST:ts:="one:two:three:four:five:six"
+LIST:ts="onetwothreefourfivesix"
+LIST:ts:S/two/2/="one2threefourfivesix"
+LIST:S/two/2/:ts="one2threefourfivesix"
+LIST:ts/:S/two/2/="one/2/three/four/five/six"
+Pretend the '/' in '/n' etc. below are back-slashes.
+LIST:ts/n="one
+two
+three
+four
+five
+six"
+LIST:ts/t="one two three four five six"
+LIST:ts/012:tu="ONE
+TWO
+THREE
+FOUR
+FIVE
+SIX"
+make: Bad modifier `:tx' for LIST
+LIST:tx="}"
+make: Bad modifier `:ts\x' for LIST
+LIST:ts/x:tu="\x:tu}"
+FU_mod-ts="a/b/cool"
+FU_mod-ts:ts:T="cool" == cool?
+B.${AAA:ts}="Baaa" == Baaa?
+exit status 0
diff --git a/devel/bmake/files/unit-tests/modts.mk b/devel/bmake/files/unit-tests/modts.mk
new file mode 100644
index 00000000000..616bd8944f2
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modts.mk
@@ -0,0 +1,43 @@
+
+LIST= one two three
+LIST+= four five six
+
+FU_mod-ts = a / b / cool
+
+AAA= a a a
+B.aaa= Baaa
+
+all: mod-ts
+
+# Use print or printf iff they are builtin.
+# XXX note that this causes problems, when make decides
+# there is no need to use a shell, so avoid where possible.
+.if ${type print 2> /dev/null || echo:L:sh:Mbuiltin} != ""
+PRINT= print -r --
+.elif ${type printf 2> /dev/null || echo:L:sh:Mbuiltin} != ""
+PRINT= printf '%s\n'
+.else
+PRINT= echo
+.endif
+
+mod-ts:
+ @echo 'LIST="${LIST}"'
+ @echo 'LIST:ts,="${LIST:ts,}"'
+ @echo 'LIST:ts/:tu="${LIST:ts/:tu}"'
+ @echo 'LIST:ts::tu="${LIST:ts::tu}"'
+ @echo 'LIST:ts:tu="${LIST:ts:tu}"'
+ @echo 'LIST:tu:ts/="${LIST:tu:ts/}"'
+ @echo 'LIST:ts:="${LIST:ts:}"'
+ @echo 'LIST:ts="${LIST:ts}"'
+ @echo 'LIST:ts:S/two/2/="${LIST:ts:S/two/2/}"'
+ @echo 'LIST:S/two/2/:ts="${LIST:S/two/2/:ts}"'
+ @echo 'LIST:ts/:S/two/2/="${LIST:ts/:S/two/2/}"'
+ @echo "Pretend the '/' in '/n' etc. below are back-slashes."
+ @${PRINT} 'LIST:ts/n="${LIST:ts\n}"'
+ @${PRINT} 'LIST:ts/t="${LIST:ts\t}"'
+ @${PRINT} 'LIST:ts/012:tu="${LIST:ts\012:tu}"'
+ @${PRINT} 'LIST:tx="${LIST:tx}"'
+ @${PRINT} 'LIST:ts/x:tu="${LIST:ts\x:tu}"'
+ @${PRINT} 'FU_$@="${FU_${@:ts}:ts}"'
+ @${PRINT} 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?'
+ @${PRINT} 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?'
diff --git a/devel/bmake/files/unit-tests/modword.exp b/devel/bmake/files/unit-tests/modword.exp
new file mode 100644
index 00000000000..258d7eadd6c
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modword.exp
@@ -0,0 +1,122 @@
+make: Bad modifier `:[]' for LIST
+LIST:[]="" is an error
+LIST:[0]="one two three four five six"
+LIST:[0x0]="one two three four five six"
+LIST:[000]="one two three four five six"
+LIST:[*]="one two three four five six"
+LIST:[@]="one two three four five six"
+LIST:[0]:C/ /,/="one,two three four five six"
+LIST:[0]:C/ /,/g="one,two,three,four,five,six"
+LIST:[0]:C/ /,/1g="one,two,three,four,five,six"
+LIST:[*]:C/ /,/="one,two three four five six"
+LIST:[*]:C/ /,/g="one,two,three,four,five,six"
+LIST:[*]:C/ /,/1g="one,two,three,four,five,six"
+LIST:[@]:C/ /,/="one two three four five six"
+LIST:[@]:C/ /,/g="one two three four five six"
+LIST:[@]:C/ /,/1g="one two three four five six"
+LIST:[@]:[0]:C/ /,/="one,two three four five six"
+LIST:[0]:[@]:C/ /,/="one two three four five six"
+LIST:[@]:[*]:C/ /,/="one,two three four five six"
+LIST:[*]:[@]:C/ /,/="one two three four five six"
+EMPTY=""
+EMPTY:[#]="1" == 1 ?
+ESCAPEDSPACE="\ "
+ESCAPEDSPACE:[#]="1" == 1 ?
+REALLYSPACE=" "
+REALLYSPACE:[#]="1" == 1 ?
+LIST:[#]="6"
+LIST:[0]:[#]="1" == 1 ?
+LIST:[*]:[#]="1" == 1 ?
+LIST:[@]:[#]="6"
+LIST:[1]:[#]="1"
+LIST:[1..3]:[#]="3"
+EMPTY:[1]=""
+ESCAPEDSPACE="\ "
+ESCAPEDSPACE:[1]="\ "
+REALLYSPACE=" "
+REALLYSPACE:[1]="" == "" ?
+REALLYSPACE:[*]:[1]=" " == " " ?
+LIST:[1]="one"
+make: Bad modifier `:[1.]' for LIST
+LIST:[1.]="" is an error
+make: Bad modifier `:[1].' for LIST
+LIST:[1].="}" is an error
+LIST:[2]="two"
+LIST:[6]="six"
+LIST:[7]=""
+LIST:[999]=""
+make: Bad modifier `:[-]' for LIST
+LIST:[-]="" is an error
+make: Bad modifier `:[--]' for LIST
+LIST:[--]="" is an error
+LIST:[-1]="six"
+LIST:[-2]="five"
+LIST:[-6]="one"
+LIST:[-7]=""
+LIST:[-999]=""
+LONGLIST:[17]="17"
+LONGLIST:[0x11]="17"
+LONGLIST:[021]="17"
+LIST:[0]:[1]="one two three four five six"
+LIST:[*]:[1]="one two three four five six"
+LIST:[@]:[1]="one"
+LIST:[0]:[2]=""
+LIST:[*]:[2]=""
+LIST:[@]:[2]="two"
+LIST:[*]:C/ /,/:[2]=""
+LIST:[*]:C/ /,/:[*]:[2]=""
+LIST:[*]:C/ /,/:[@]:[2]="three"
+make: Bad modifier `:[1.]' for LIST
+LIST:[1.]="" is an error
+make: Bad modifier `:[1..]' for LIST
+LIST:[1..]="" is an error
+LIST:[1..1]="one"
+make: Bad modifier `:[1..1.]' for LIST
+LIST:[1..1.]="" is an error
+LIST:[1..2]="one two"
+LIST:[2..1]="two one"
+LIST:[3..-2]="three four five"
+LIST:[-4..4]="three four"
+make: Bad modifier `:[0..1]' for LIST
+LIST:[0..1]="" is an error
+make: Bad modifier `:[-1..0]' for LIST
+LIST:[-1..0]="" is an error
+LIST:[-1..1]="six five four three two one"
+LIST:[0..0]="one two three four five six"
+LIST:[3..99]="three four five six"
+LIST:[-3..-99]="four three two one"
+LIST:[-99..-3]="one two three four"
+HASH="#" == "#" ?
+LIST:[${HASH}]="6"
+LIST:[${ZERO}]="one two three four five six"
+LIST:[${ZERO}x${ONE}]="one"
+LIST:[${ONE}]="one"
+LIST:[${MINUSONE}]="six"
+LIST:[${STAR}]="one two three four five six"
+LIST:[${AT}]="one two three four five six"
+make: Bad modifier `:[${EMPTY' for LIST
+LIST:[${EMPTY}]="" is an error
+LIST:[${LONGLIST:[21]:S/2//}]="one"
+LIST:[${LIST:[#]}]="six"
+LIST:[${LIST:[${HASH}]}]="six"
+LIST:S/ /,/="one two three four five six"
+LIST:S/ /,/W="one,two three four five six"
+LIST:S/ /,/gW="one,two,three,four,five,six"
+EMPTY:S/^/,/=","
+EMPTY:S/^/,/W=","
+LIST:C/ /,/="one two three four five six"
+LIST:C/ /,/W="one,two three four five six"
+LIST:C/ /,/gW="one,two,three,four,five,six"
+EMPTY:C/^/,/=","
+EMPTY:C/^/,/W=","
+LIST:tW="one two three four five six"
+LIST:tw="one two three four five six"
+LIST:tW:C/ /,/="one,two three four five six"
+LIST:tW:C/ /,/g="one,two,three,four,five,six"
+LIST:tW:C/ /,/1g="one,two,three,four,five,six"
+LIST:tw:C/ /,/="one two three four five six"
+LIST:tw:C/ /,/g="one two three four five six"
+LIST:tw:C/ /,/1g="one two three four five six"
+LIST:tw:tW:C/ /,/="one,two three four five six"
+LIST:tW:tw:C/ /,/="one two three four five six"
+exit status 0
diff --git a/devel/bmake/files/unit-tests/modword.mk b/devel/bmake/files/unit-tests/modword.mk
new file mode 100644
index 00000000000..9801ebad261
--- /dev/null
+++ b/devel/bmake/files/unit-tests/modword.mk
@@ -0,0 +1,151 @@
+# $Id: modword.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# Test behaviour of new :[] modifier
+
+all: mod-squarebrackets mod-S-W mod-C-W mod-tW-tw
+
+LIST= one two three
+LIST+= four five six
+LONGLIST= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+
+EMPTY= # the space should be ignored
+ESCAPEDSPACE=\ # escaped space before the '#'
+REALLYSPACE:=${EMPTY:C/^/ /W}
+HASH= \#
+AT= @
+STAR= *
+ZERO= 0
+ONE= 1
+MINUSONE= -1
+
+mod-squarebrackets: mod-squarebrackets-0-star-at \
+ mod-squarebrackets-hash \
+ mod-squarebrackets-n \
+ mod-squarebrackets-start-end \
+ mod-squarebrackets-nested
+
+mod-squarebrackets-0-star-at:
+ @echo 'LIST:[]="${LIST:[]}" is an error'
+ @echo 'LIST:[0]="${LIST:[0]}"'
+ @echo 'LIST:[0x0]="${LIST:[0x0]}"'
+ @echo 'LIST:[000]="${LIST:[000]}"'
+ @echo 'LIST:[*]="${LIST:[*]}"'
+ @echo 'LIST:[@]="${LIST:[@]}"'
+ @echo 'LIST:[0]:C/ /,/="${LIST:[0]:C/ /,/}"'
+ @echo 'LIST:[0]:C/ /,/g="${LIST:[0]:C/ /,/g}"'
+ @echo 'LIST:[0]:C/ /,/1g="${LIST:[0]:C/ /,/1g}"'
+ @echo 'LIST:[*]:C/ /,/="${LIST:[*]:C/ /,/}"'
+ @echo 'LIST:[*]:C/ /,/g="${LIST:[*]:C/ /,/g}"'
+ @echo 'LIST:[*]:C/ /,/1g="${LIST:[*]:C/ /,/1g}"'
+ @echo 'LIST:[@]:C/ /,/="${LIST:[@]:C/ /,/}"'
+ @echo 'LIST:[@]:C/ /,/g="${LIST:[@]:C/ /,/g}"'
+ @echo 'LIST:[@]:C/ /,/1g="${LIST:[@]:C/ /,/1g}"'
+ @echo 'LIST:[@]:[0]:C/ /,/="${LIST:[@]:[0]:C/ /,/}"'
+ @echo 'LIST:[0]:[@]:C/ /,/="${LIST:[0]:[@]:C/ /,/}"'
+ @echo 'LIST:[@]:[*]:C/ /,/="${LIST:[@]:[*]:C/ /,/}"'
+ @echo 'LIST:[*]:[@]:C/ /,/="${LIST:[*]:[@]:C/ /,/}"'
+
+mod-squarebrackets-hash:
+ @echo 'EMPTY="${EMPTY}"'
+ @echo 'EMPTY:[#]="${EMPTY:[#]}" == 1 ?'
+ @echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
+ @echo 'ESCAPEDSPACE:[#]="${ESCAPEDSPACE:[#]}" == 1 ?'
+ @echo 'REALLYSPACE="${REALLYSPACE}"'
+ @echo 'REALLYSPACE:[#]="${REALLYSPACE:[#]}" == 1 ?'
+ @echo 'LIST:[#]="${LIST:[#]}"'
+ @echo 'LIST:[0]:[#]="${LIST:[0]:[#]}" == 1 ?'
+ @echo 'LIST:[*]:[#]="${LIST:[*]:[#]}" == 1 ?'
+ @echo 'LIST:[@]:[#]="${LIST:[@]:[#]}"'
+ @echo 'LIST:[1]:[#]="${LIST:[1]:[#]}"'
+ @echo 'LIST:[1..3]:[#]="${LIST:[1..3]:[#]}"'
+
+mod-squarebrackets-n:
+ @echo 'EMPTY:[1]="${EMPTY:[1]}"'
+ @echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
+ @echo 'ESCAPEDSPACE:[1]="${ESCAPEDSPACE:[1]}"'
+ @echo 'REALLYSPACE="${REALLYSPACE}"'
+ @echo 'REALLYSPACE:[1]="${REALLYSPACE:[1]}" == "" ?'
+ @echo 'REALLYSPACE:[*]:[1]="${REALLYSPACE:[*]:[1]}" == " " ?'
+ @echo 'LIST:[1]="${LIST:[1]}"'
+ @echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+ @echo 'LIST:[1].="${LIST:[1].}" is an error'
+ @echo 'LIST:[2]="${LIST:[2]}"'
+ @echo 'LIST:[6]="${LIST:[6]}"'
+ @echo 'LIST:[7]="${LIST:[7]}"'
+ @echo 'LIST:[999]="${LIST:[999]}"'
+ @echo 'LIST:[-]="${LIST:[-]}" is an error'
+ @echo 'LIST:[--]="${LIST:[--]}" is an error'
+ @echo 'LIST:[-1]="${LIST:[-1]}"'
+ @echo 'LIST:[-2]="${LIST:[-2]}"'
+ @echo 'LIST:[-6]="${LIST:[-6]}"'
+ @echo 'LIST:[-7]="${LIST:[-7]}"'
+ @echo 'LIST:[-999]="${LIST:[-999]}"'
+ @echo 'LONGLIST:[17]="${LONGLIST:[17]}"'
+ @echo 'LONGLIST:[0x11]="${LONGLIST:[0x11]}"'
+ @echo 'LONGLIST:[021]="${LONGLIST:[021]}"'
+ @echo 'LIST:[0]:[1]="${LIST:[0]:[1]}"'
+ @echo 'LIST:[*]:[1]="${LIST:[*]:[1]}"'
+ @echo 'LIST:[@]:[1]="${LIST:[@]:[1]}"'
+ @echo 'LIST:[0]:[2]="${LIST:[0]:[2]}"'
+ @echo 'LIST:[*]:[2]="${LIST:[*]:[2]}"'
+ @echo 'LIST:[@]:[2]="${LIST:[@]:[2]}"'
+ @echo 'LIST:[*]:C/ /,/:[2]="${LIST:[*]:C/ /,/:[2]}"'
+ @echo 'LIST:[*]:C/ /,/:[*]:[2]="${LIST:[*]:C/ /,/:[*]:[2]}"'
+ @echo 'LIST:[*]:C/ /,/:[@]:[2]="${LIST:[*]:C/ /,/:[@]:[2]}"'
+
+mod-squarebrackets-start-end:
+ @echo 'LIST:[1.]="${LIST:[1.]}" is an error'
+ @echo 'LIST:[1..]="${LIST:[1..]}" is an error'
+ @echo 'LIST:[1..1]="${LIST:[1..1]}"'
+ @echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'
+ @echo 'LIST:[1..2]="${LIST:[1..2]}"'
+ @echo 'LIST:[2..1]="${LIST:[2..1]}"'
+ @echo 'LIST:[3..-2]="${LIST:[3..-2]}"'
+ @echo 'LIST:[-4..4]="${LIST:[-4..4]}"'
+ @echo 'LIST:[0..1]="${LIST:[0..1]}" is an error'
+ @echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error'
+ @echo 'LIST:[-1..1]="${LIST:[-1..1]}"'
+ @echo 'LIST:[0..0]="${LIST:[0..0]}"'
+ @echo 'LIST:[3..99]="${LIST:[3..99]}"'
+ @echo 'LIST:[-3..-99]="${LIST:[-3..-99]}"'
+ @echo 'LIST:[-99..-3]="${LIST:[-99..-3]}"'
+
+mod-squarebrackets-nested:
+ @echo 'HASH="${HASH}" == "#" ?'
+ @echo 'LIST:[$${HASH}]="${LIST:[${HASH}]}"'
+ @echo 'LIST:[$${ZERO}]="${LIST:[${ZERO}]}"'
+ @echo 'LIST:[$${ZERO}x$${ONE}]="${LIST:[${ZERO}x${ONE}]}"'
+ @echo 'LIST:[$${ONE}]="${LIST:[${ONE}]}"'
+ @echo 'LIST:[$${MINUSONE}]="${LIST:[${MINUSONE}]}"'
+ @echo 'LIST:[$${STAR}]="${LIST:[${STAR}]}"'
+ @echo 'LIST:[$${AT}]="${LIST:[${AT}]}"'
+ @echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error'
+ @echo 'LIST:[$${LONGLIST:[21]:S/2//}]="${LIST:[${LONGLIST:[21]:S/2//}]}"'
+ @echo 'LIST:[$${LIST:[#]}]="${LIST:[${LIST:[#]}]}"'
+ @echo 'LIST:[$${LIST:[$${HASH}]}]="${LIST:[${LIST:[${HASH}]}]}"'
+
+mod-C-W:
+ @echo 'LIST:C/ /,/="${LIST:C/ /,/}"'
+ @echo 'LIST:C/ /,/W="${LIST:C/ /,/W}"'
+ @echo 'LIST:C/ /,/gW="${LIST:C/ /,/gW}"'
+ @echo 'EMPTY:C/^/,/="${EMPTY:C/^/,/}"'
+ @echo 'EMPTY:C/^/,/W="${EMPTY:C/^/,/W}"'
+
+mod-S-W:
+ @echo 'LIST:S/ /,/="${LIST:S/ /,/}"'
+ @echo 'LIST:S/ /,/W="${LIST:S/ /,/W}"'
+ @echo 'LIST:S/ /,/gW="${LIST:S/ /,/gW}"'
+ @echo 'EMPTY:S/^/,/="${EMPTY:S/^/,/}"'
+ @echo 'EMPTY:S/^/,/W="${EMPTY:S/^/,/W}"'
+
+mod-tW-tw:
+ @echo 'LIST:tW="${LIST:tW}"'
+ @echo 'LIST:tw="${LIST:tw}"'
+ @echo 'LIST:tW:C/ /,/="${LIST:tW:C/ /,/}"'
+ @echo 'LIST:tW:C/ /,/g="${LIST:tW:C/ /,/g}"'
+ @echo 'LIST:tW:C/ /,/1g="${LIST:tW:C/ /,/1g}"'
+ @echo 'LIST:tw:C/ /,/="${LIST:tw:C/ /,/}"'
+ @echo 'LIST:tw:C/ /,/g="${LIST:tw:C/ /,/g}"'
+ @echo 'LIST:tw:C/ /,/1g="${LIST:tw:C/ /,/1g}"'
+ @echo 'LIST:tw:tW:C/ /,/="${LIST:tw:tW:C/ /,/}"'
+ @echo 'LIST:tW:tw:C/ /,/="${LIST:tW:tw:C/ /,/}"'
diff --git a/devel/bmake/files/unit-tests/order.exp b/devel/bmake/files/unit-tests/order.exp
new file mode 100644
index 00000000000..d876914ffc9
--- /dev/null
+++ b/devel/bmake/files/unit-tests/order.exp
@@ -0,0 +1,4 @@
+Making the.c
+Making the.h
+Making the.o from the.h the.c
+exit status 0
diff --git a/devel/bmake/files/unit-tests/order.mk b/devel/bmake/files/unit-tests/order.mk
new file mode 100644
index 00000000000..90688730c24
--- /dev/null
+++ b/devel/bmake/files/unit-tests/order.mk
@@ -0,0 +1,20 @@
+# $NetBSD: order.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# Test that .ORDER is handled correctly.
+# The explicit dependency the.o: the.h will make us examine the.h
+# the .ORDER will prevent us building it immediately,
+# we should then examine the.c rather than stop.
+
+all: the.o
+
+.ORDER: the.c the.h
+
+the.c the.h:
+ @echo Making $@
+
+.SUFFIXES: .o .c
+
+.c.o:
+ @echo Making $@ from $?
+
+the.o: the.h
diff --git a/devel/bmake/files/unit-tests/phony-end.exp b/devel/bmake/files/unit-tests/phony-end.exp
new file mode 100644
index 00000000000..c3c517ccc25
--- /dev/null
+++ b/devel/bmake/files/unit-tests/phony-end.exp
@@ -0,0 +1,6 @@
+.TARGET="phony" .PREFIX="phony" .IMPSRC=""
+.TARGET="all" .PREFIX="all" .IMPSRC="phony"
+.TARGET="ok" .PREFIX="ok" .IMPSRC=""
+.TARGET="also.ok" .PREFIX="also.ok" .IMPSRC=""
+.TARGET="bug" .PREFIX="bug" .IMPSRC=""
+exit status 0
diff --git a/devel/bmake/files/unit-tests/phony-end.mk b/devel/bmake/files/unit-tests/phony-end.mk
new file mode 100644
index 00000000000..ff730e6289f
--- /dev/null
+++ b/devel/bmake/files/unit-tests/phony-end.mk
@@ -0,0 +1,9 @@
+# $Id: phony-end.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+all ok also.ok bug phony:
+ @echo '${.TARGET .PREFIX .IMPSRC:L:@v@$v="${$v}"@}'
+
+.END: ok also.ok bug
+
+phony bug: .PHONY
+all: phony
diff --git a/devel/bmake/files/unit-tests/posix.exp b/devel/bmake/files/unit-tests/posix.exp
new file mode 100644
index 00000000000..7e74cabadfb
--- /dev/null
+++ b/devel/bmake/files/unit-tests/posix.exp
@@ -0,0 +1,23 @@
+Posix says we should execute the command as if run by system(3)
+Expect 'Hello,' and 'World!'
+Hello,
+World!
+a command
+a command prefixed by '+' executes even with -n
+another command
+make -n
+echo a command
+echo "a command prefixed by '+' executes even with -n"
+a command prefixed by '+' executes even with -n
+echo another command
+make -n -j1
+{ echo a command
+} || exit $?
+echo "a command prefixed by '+' executes even with -n"
+a command prefixed by '+' executes even with -n
+{ echo another command
+} || exit $?
+Now we expect an error...
+*** Error code 1 (continuing)
+`all' not remade because of errors.
+exit status 0
diff --git a/devel/bmake/files/unit-tests/posix.mk b/devel/bmake/files/unit-tests/posix.mk
new file mode 100644
index 00000000000..28786bea704
--- /dev/null
+++ b/devel/bmake/files/unit-tests/posix.mk
@@ -0,0 +1,24 @@
+# $Id: posix.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+all: x plus subs err
+
+x:
+ @echo "Posix says we should execute the command as if run by system(3)"
+ @echo "Expect 'Hello,' and 'World!'"
+ @echo Hello,; false; echo "World!"
+
+plus:
+ @echo a command
+ +@echo "a command prefixed by '+' executes even with -n"
+ @echo another command
+
+subs:
+ @echo make -n
+ @${.MAKE} -f ${MAKEFILE} -n plus
+ @echo make -n -j1
+ @${.MAKE} -f ${MAKEFILE} -n -j1 plus
+
+err:
+ @(echo Now we expect an error...; exit 1)
+ @echo "Oops! you shouldn't see this!"
+
diff --git a/devel/bmake/files/unit-tests/posix1.exp b/devel/bmake/files/unit-tests/posix1.exp
new file mode 100644
index 00000000000..92809e61c69
--- /dev/null
+++ b/devel/bmake/files/unit-tests/posix1.exp
@@ -0,0 +1,185 @@
+${VAR} = "foo bar baz"
+a
+b
+c
+foo baR baz, bar baz, foo bar baz, fooadd baradd bazadd
+mkdir -p 'dir'
+touch 'dir/obj_1.h'
+mkdir -p 'dir'
+printf '#include "obj_1.h"\nconst char* obj_1 = "dir/obj_1.c";\n' \
+ >'dir/obj_1.c'
+Local variables
+ ${@}="dir/obj_1.o" ${<}="dir/obj_1.c"
+ ${*}="dir/obj_1" ${?}="dir/obj_1.h dir/obj_1.c"
+ ${%}=""
+
+Directory and filename parts of local variables
+ ${@D}="dir" ${@F}="obj_1.o"
+ ${<D}="dir" ${<F}="obj_1.c"
+ ${*D}="dir" ${*F}="obj_1"
+ ${?D}="dir dir" ${?F}="obj_1.h obj_1.c"
+ ${%D}="" ${%F}=""
+
+Local variable substitutions
+ ${@:.o=}="dir/obj_1" ${<:.c=.C}="dir/obj_1.C"
+ ${*:=.h}="dir/obj_1.h" ${?:.h=.H}="dir/obj_1.H dir/obj_1.c"
+ ${%:=}=""
+
+Target with suffix transformations
+ ${@D:=append}="dirappend"
+ ${@F:.o=.O}="obj_1.O"
+
+ Implied source with suffix transformations
+ ${<D:r=rr}="dirr"
+ ${<F:.c=.C}="obj_1.C"
+
+ Suffixless target with suffix transformations
+ ${*D:.=dot}="dir"
+ ${*F:.a=}="obj_1"
+
+ Out-of-date dependencies with suffix transformations
+ ${?D:ir=}="d d"
+ ${?F:.h=.H}="obj_1.H obj_1.c"
+
+ Member with suffix transformations
+ ${%D:.=}=""
+ ${%F:${VAR2}=${VAR}}=""
+
+cc -c -o 'dir/obj_1.o' 'dir/obj_1.c'
+mkdir -p '.'
+touch 'dummy'
+Local variables
+ ${@}="lib.a" ${<}="dir/obj_1.o"
+ ${*}="obj1" ${?}="dir/obj_1.o dummy"
+ ${%}="obj1.o"
+
+Directory and filename parts of local variables
+ ${@D}="." ${@F}="lib.a"
+ ${<D}="dir" ${<F}="obj_1.o"
+ ${*D}="." ${*F}="obj1"
+ ${?D}="dir ." ${?F}="obj_1.o dummy"
+ ${%D}="." ${%F}="obj1.o"
+
+Local variable substitutions
+ ${@:.o=}="lib.a" ${<:.c=.C}="dir/obj_1.o"
+ ${*:=.h}="obj1.h" ${?:.h=.H}="dir/obj_1.o dummy"
+ ${%:=}="obj1.o"
+
+Target with suffix transformations
+ ${@D:=append}=".append"
+ ${@F:.o=.O}="lib.a"
+
+ Implied source with suffix transformations
+ ${<D:r=rr}="dirr"
+ ${<F:.c=.C}="obj_1.o"
+
+ Suffixless target with suffix transformations
+ ${*D:.=dot}="dot"
+ ${*F:.a=}="obj1"
+
+ Out-of-date dependencies with suffix transformations
+ ${?D:ir=}="d ."
+ ${?F:.h=.H}="obj_1.o dummy"
+
+ Member with suffix transformations
+ ${%D:.=}=""
+ ${%F:${VAR2}=${VAR}}="obj1foo bar baz"
+
+cp 'dir/obj_1.o' 'obj1.o'
+ar -rcv 'lib.a' 'obj1.o'
+a - obj1.o
+rm -f 'obj1.o'
+mkdir -p '.'
+printf '#include "obj_2.h"\nconst char* obj_2 = "obj_2.c";\n' \
+ >'obj_2.c'
+mkdir -p '.'
+touch 'obj_2.h'
+Local variables
+ ${@}="obj2.o" ${<}="obj_2.c"
+ ${*}="obj2" ${?}="obj_2.c obj_2.h dir/obj_1.h"
+ ${%}=""
+
+Directory and filename parts of local variables
+ ${@D}="." ${@F}="obj2.o"
+ ${<D}="." ${<F}="obj_2.c"
+ ${*D}="." ${*F}="obj2"
+ ${?D}=". . dir" ${?F}="obj_2.c obj_2.h obj_1.h"
+ ${%D}="" ${%F}=""
+
+Local variable substitutions
+ ${@:.o=}="obj2" ${<:.c=.C}="obj_2.C"
+ ${*:=.h}="obj2.h" ${?:.h=.H}="obj_2.c obj_2.H dir/obj_1.H"
+ ${%:=}=""
+
+Target with suffix transformations
+ ${@D:=append}=".append"
+ ${@F:.o=.O}="obj2.O"
+
+ Implied source with suffix transformations
+ ${<D:r=rr}="."
+ ${<F:.c=.C}="obj_2.C"
+
+ Suffixless target with suffix transformations
+ ${*D:.=dot}="dot"
+ ${*F:.a=}="obj2"
+
+ Out-of-date dependencies with suffix transformations
+ ${?D:ir=}=". . d"
+ ${?F:.h=.H}="obj_2.c obj_2.H obj_1.H"
+
+ Member with suffix transformations
+ ${%D:.=}=""
+ ${%F:${VAR2}=${VAR}}=""
+
+cc -c -o 'obj2.o' 'obj_2.c'
+ar -rcv 'lib.a' 'obj2.o'
+a - obj2.o
+mkdir -p '.'
+touch 'obj3.h'
+mkdir -p 'dir'
+touch 'dir/dummy'
+mkdir -p '.'
+printf '#include "obj3.h"\nconst char* obj3 = "obj3.c";\n' \
+ >'obj3.c'
+Local variables
+ ${@}="lib.a" ${<}="obj3.c"
+ ${*}="obj3" ${?}="obj3.h dir/dummy obj3.c"
+ ${%}="obj3.o"
+
+Directory and filename parts of local variables
+ ${@D}="." ${@F}="lib.a"
+ ${<D}="." ${<F}="obj3.c"
+ ${*D}="." ${*F}="obj3"
+ ${?D}=". dir ." ${?F}="obj3.h dummy obj3.c"
+ ${%D}="." ${%F}="obj3.o"
+
+Local variable substitutions
+ ${@:.o=}="lib.a" ${<:.c=.C}="obj3.C"
+ ${*:=.h}="obj3.h" ${?:.h=.H}="obj3.H dir/dummy obj3.c"
+ ${%:=}="obj3.o"
+
+Target with suffix transformations
+ ${@D:=append}=".append"
+ ${@F:.o=.O}="lib.a"
+
+ Implied source with suffix transformations
+ ${<D:r=rr}="."
+ ${<F:.c=.C}="obj3.C"
+
+ Suffixless target with suffix transformations
+ ${*D:.=dot}="dot"
+ ${*F:.a=}="obj3"
+
+ Out-of-date dependencies with suffix transformations
+ ${?D:ir=}=". d ."
+ ${?F:.h=.H}="obj3.H dummy obj3.c"
+
+ Member with suffix transformations
+ ${%D:.=}=""
+ ${%F:${VAR2}=${VAR}}="obj3foo bar baz"
+
+cc -c -o 'obj3.o' 'obj3.c'
+ar -rcv 'lib.a' 'obj3.o'
+a - obj3.o
+rm -f 'obj3.o'
+exit status 0
diff --git a/devel/bmake/files/unit-tests/posix1.mk b/devel/bmake/files/unit-tests/posix1.mk
new file mode 100644
index 00000000000..cb47db36494
--- /dev/null
+++ b/devel/bmake/files/unit-tests/posix1.mk
@@ -0,0 +1,184 @@
+# $NetBSD: posix1.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# Keep the default suffixes from interfering, just in case.
+.SUFFIXES:
+
+all: line-continuations suffix-substitution localvars
+
+# we need to clean for repeatable results
+.BEGIN: clean
+clean:
+ @rm -f lib.a dir/* dummy obj*
+
+#
+# Line continuations
+#
+
+# Escaped newlines and leading whitespace from the next line are replaced
+# with single space, except in commands, where the escape and the newline
+# are retained, but a single leading tab (if any) from the next line is
+# removed. (PR 49085)
+# Expect:
+# ${VAR} = "foo bar baz"
+# a
+# b
+# c
+VAR = foo\
+\
+ bar\
+ baz
+
+line-continuations:
+ @echo '$${VAR} = "${VAR}"'
+ @echo 'aXbXc' | sed -e 's/X/\
+ /g'
+
+
+#
+# Suffix substitution
+#
+
+# The only variable modifier accepted by POSIX.
+# ${VAR:s1=s2}: replace s1, if found, with s2 at end of each word in
+# ${VAR}. s1 and s2 may contain macro expansions.
+# Expect: foo baR baz, bar baz, foo bar baz, fooadd baradd bazadd
+suffix-substitution:
+ @echo '${VAR:r=R}, ${VAR:foo=}, ${VAR:not_there=wrong}, ${VAR:=add}'
+
+
+#
+# Local variables: regular forms, D/F forms and suffix substitution.
+#
+
+# In the past substitutions did not work with the D/F forms and those
+# forms were not available for $?. (PR 49085)
+
+ARFLAGS = -rcv
+
+localvars: lib.a
+
+# $@ = target or archive name $< = implied source
+# $* = target without suffix $? = sources newer than target
+# $% = archive member name
+LOCALS = \
+ "Local variables\n\
+ \$${@}=\"${@}\" \$${<}=\"${<}\"\n\
+ \$${*}=\"${*}\" \$${?}=\"${?}\"\n\
+ \$${%%}=\"${%}\"\n\n"
+
+# $XD = directory part of X $XF = file part of X
+# X is one of the local variables.
+LOCAL_ALTERNATIVES = \
+ "Directory and filename parts of local variables\n\
+ \$${@D}=\"${@D}\" \$${@F}=\"${@F}\"\n\
+ \$${<D}=\"${<D}\" \$${<F}=\"${<F}\"\n\
+ \$${*D}=\"${*D}\" \$${*F}=\"${*F}\"\n\
+ \$${?D}=\"${?D}\" \$${?F}=\"${?F}\"\n\
+ \$${%%D}=\"${%D}\" \$${%%F}=\"${%F}\"\n\n"
+
+# Do all kinds of meaningless substitutions on local variables to see
+# if they work. Add, remove and replace things.
+VAR2 = .o
+VAR3 = foo
+LOCAL_SUBSTITUTIONS = \
+ "Local variable substitutions\n\
+ \$${@:.o=}=\"${@:.o=}\" \$${<:.c=.C}=\"${<:.c=.C}\"\n\
+ \$${*:=.h}=\"${*:=.h}\" \$${?:.h=.H}=\"${?:.h=.H}\"\n\
+ \$${%%:=}=\"${%:=}\"\n\n"
+
+LOCAL_ALTERNATIVE_SUBSTITUTIONS = \
+ "Target with suffix transformations\n\
+ \$${@D:=append}=\"${@D:=append}\"\n\
+ \$${@F:.o=.O}=\"${@F:.o=.O}\"\n\
+ \n\
+ Implied source with suffix transformations\n\
+ \$${<D:r=rr}=\"${<D:r=rr}\"\n\
+ \$${<F:.c=.C}=\"${<F:.c=.C}\"\n\
+ \n\
+ Suffixless target with suffix transformations\n\
+ \$${*D:.=dot}=\"${*D:.=dot}\"\n\
+ \$${*F:.a=}=\"${*F:.a=}\"\n\
+ \n\
+ Out-of-date dependencies with suffix transformations\n\
+ \$${?D:ir=}=\"${?D:ir=}\"\n\
+ \$${?F:.h=.H}=\"${?F:.h=.H}\"\n\
+ \n\
+ Member with suffix transformations\n\
+ \$${%%D:.=}=\"${%D:.=}\"\n\
+ \$${%%F:\$${VAR2}=\$${VAR}}=\"${%F:${VAR2}=${VAR}}\"\n\n"
+
+.SUFFIXES: .c .o .a
+
+# The system makefiles make the .c.a rule .PRECIOUS with a special source,
+# but such a thing is not POSIX compatible. It's also somewhat useless
+# in a test makefile.
+.c.a:
+ @printf ${LOCALS}
+ @printf ${LOCAL_ALTERNATIVES}
+ @printf ${LOCAL_SUBSTITUTIONS}
+ @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
+ cc -c -o '${%}' '${<}'
+ ar ${ARFLAGS} '${@}' '${%}'
+ rm -f '${%}'
+
+.c.o:
+ @printf ${LOCALS}
+ @printf ${LOCAL_ALTERNATIVES}
+ @printf ${LOCAL_SUBSTITUTIONS}
+ @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
+ cc -c -o '${@}' '${<}'
+
+# Some of these rules are padded with useless extra dependencies just so
+# that ${?} has more than one file.
+
+lib.a: lib.a(obj1.o) lib.a(obj2.o) lib.a(obj3.o)
+ @ar -s '${@}'
+
+# Explicit rule where the dependency is an inferred file. The dependency
+# object's name differs from the member's because there was a bug which
+# forced a dependency on member even when no such dependency was specified
+# (PR 49086).
+lib.a(obj1.o): dir/obj_1.o dummy
+ @printf ${LOCALS}
+ @printf ${LOCAL_ALTERNATIVES}
+ @printf ${LOCAL_SUBSTITUTIONS}
+ @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
+ cp 'dir/obj_1.o' '$%'
+ ar ${ARFLAGS} '${@}' '$%'
+ rm -f '$%'
+
+# Excplicit rule where the dependency also has an explicit rule.
+lib.a(obj2.o): obj2.o
+ ar ${ARFLAGS} '${@}' '${%}'
+
+# Use .c.a inference with an extra dependency.
+lib.a(obj3.o): obj3.h dir/dummy
+
+# Use .c.o inference with an extra dependency.
+dir/obj_1.o: dir/obj_1.h
+
+# According to POSIX, $* is only required for inference rules and $<'s
+# value is unspecified outside of inference rules. Strictly speaking
+# we shouldn't be expanding them here but who cares. At least we get
+# to check that the program does nothing stupid (like crash) with them.
+# The C file is named differently from the object file because there
+# was a bug which forced dependencies based on inference rules on all
+# applicable targets (PR 49086).
+obj2.o: obj_2.c obj_2.h dir/obj_1.h
+ @printf ${LOCALS}
+ @printf ${LOCAL_ALTERNATIVES}
+ @printf ${LOCAL_SUBSTITUTIONS}
+ @printf ${LOCAL_ALTERNATIVE_SUBSTITUTIONS}
+ cc -c -o '${@}' 'obj_2.c'
+
+# Hey, this is make, we can make our own test data setup! obj1.c
+# and obj2.c are not used, so they should not get created. They're here
+# as a bait for a regression into the forced dependencies discussed earlier.
+obj1.c dir/obj_1.c obj2.c obj_2.c obj3.c:
+ mkdir -p '${@D}'
+ printf '#include "${@F:.c=.h}"\nconst char* ${@F:.c=} = "${@}";\n' \
+ >'${@}'
+
+dir/obj_1.h obj_2.h obj3.h dummy dir/dummy:
+ mkdir -p '${@D}'
+ touch '${@}'
diff --git a/devel/bmake/files/unit-tests/qequals.exp b/devel/bmake/files/unit-tests/qequals.exp
new file mode 100644
index 00000000000..6b2f4dce699
--- /dev/null
+++ b/devel/bmake/files/unit-tests/qequals.exp
@@ -0,0 +1,2 @@
+V.i386 ?= OK
+exit status 0
diff --git a/devel/bmake/files/unit-tests/qequals.mk b/devel/bmake/files/unit-tests/qequals.mk
new file mode 100644
index 00000000000..b8717cb3edd
--- /dev/null
+++ b/devel/bmake/files/unit-tests/qequals.mk
@@ -0,0 +1,8 @@
+# $Id: qequals.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+M= i386
+V.i386= OK
+V.$M ?= bug
+
+all:
+ @echo 'V.$M ?= ${V.$M}'
diff --git a/devel/bmake/files/unit-tests/suffixes.exp b/devel/bmake/files/unit-tests/suffixes.exp
new file mode 100644
index 00000000000..2a46e1cfa8e
--- /dev/null
+++ b/devel/bmake/files/unit-tests/suffixes.exp
@@ -0,0 +1,35 @@
+make: don't know how to make issue3 (continuing)
+There should be no text after the colon:
+touch .a
+There should be no text after the colon:
+touch .a.b
+There should be no text after the colon:
+touch .b.a
+touch issue5a.c
+first set
+cp issue5a.c issue5a.d
+touch issue5b.d
+first set
+cp issue5b.d issue5b.c
+touch issue5c.d
+first set
+cp issue5c.d issue5c
+touch issue5d.d
+first set
+cp issue5d.d issue5d.e
+touch issue5e.e
+first set
+cp issue5e.e issue5e.d
+make: don't know how to make issue6.f (continuing)
+touch issue10.d
+first set
+cp issue10.d issue10.e
+touch issue11.h
+touch issue11.first
+.ALLSRC: issue11.h issue11.first
+cp issue11.h issue11.i
+touch issue11.second
+.ALLSRC: issue11.i issue11.second
+cp issue11.i issue11.j
+`all' not remade because of errors.
+exit status 0
diff --git a/devel/bmake/files/unit-tests/suffixes.mk b/devel/bmake/files/unit-tests/suffixes.mk
new file mode 100644
index 00000000000..52e36cceb46
--- /dev/null
+++ b/devel/bmake/files/unit-tests/suffixes.mk
@@ -0,0 +1,89 @@
+# $NetBSD: suffixes.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# Issues from PR 49086
+
+# Issue 3: single suffix rules remain active after .SUFFIXES is cleared
+#
+# There's a rule for issue3.a, but .a is no longer a known suffix when
+# targets are being made, so issue3 should not get made.
+all: issue3
+
+# Issue 4: suffix rules do not become regular rules when .SUFFIXES is cleared
+#
+# When the rules were encountered, .a and .b were known suffices, but later
+# on they were forgotten. These should get created as regular targets.
+all: .a .a.b .b.a
+
+# Issue 5: adding more suffixes does not make existing rules into suffix rules
+#
+# When the targets .c.d, .d.c, .d, .d.e, and .e.d were encountered, only .a,
+# .b and .c were known suffixes, so all of them were regular rules. Later
+# rest of the suffixes were made known, so they should all be suffix
+# transformation rules.
+all: issue5a.d issue5b.c issue5c issue5d.e issue5e.d
+
+# Issue 6: transformation search can end up in an infinite loop
+#
+# There is no file or target from which issue6.f could be made from so
+# this should fail. The bug was that because rules .e.f, .d.e and .e.d
+# exist, make would try to make .f from .e and then infinitely try
+# to do .e from .d and vice versa.
+all: issue6.f
+
+# Issue 10: explicit dependencies affect transformation rule selection
+#
+# If issue10.e is wanted and both issue10.d and issue10.f are available,
+# make should choose the .d.e rule, because .d is before .f in .SUFFIXES.
+# The bug was that if issue10.d had an explicit dependency on issue10.f,
+# it would choose .f.e instead.
+all: issue10.e
+
+# Issue 11: sources from transformation rules are expanded incorrectly
+#
+# issue11.j should depend on issue11.i and issue11.second and issue11.i
+# should depend on issue11.h and issue11.first. The bug was that
+# the dynamic sources were expanded before ${.PREFIX} and ${.TARGET} were
+# available, so they would have expanded to a null string.
+all: issue11.j
+
+# we need to clean for repeatable results
+.BEGIN: clean
+clean:
+ @rm -f issue* .[ab]*
+
+.SUFFIXES: .a .b .c
+
+.a .a.b .b.a:
+ @echo 'There should be no text after the colon: ${.IMPSRC}'
+ touch ${.TARGET}
+
+.c.d .d.c .d .d.e .e.d:
+ @echo 'first set'
+ cp ${.IMPSRC} ${.TARGET}
+
+.SUFFIXES:
+.SUFFIXES: .c .d .e .f .g
+
+.e .e.f .f.e:
+ @echo 'second set'
+ cp ${.IMPSRC} ${.TARGET}
+
+issue3.a:
+ @echo 'There is a bug if you see this.'
+ touch ${.TARGET}
+
+issue5a.c issue5b.d issue5c.d issue5d.d issue5e.e issue10.d issue10.f:
+ touch ${.TARGET}
+
+.SUFFIXES: .h .i .j
+
+.h.i: ${.PREFIX}.first
+ @echo '.ALLSRC: ${.ALLSRC}'
+ cp ${.IMPSRC} ${.TARGET}
+
+.i.j: ${.PREFIX}.second
+ @echo '.ALLSRC: ${.ALLSRC}'
+ cp ${.IMPSRC} ${.TARGET}
+
+issue11.h issue11.first issue11.second:
+ touch ${.TARGET}
diff --git a/devel/bmake/files/unit-tests/sunshcmd.exp b/devel/bmake/files/unit-tests/sunshcmd.exp
new file mode 100644
index 00000000000..b14f6b68a41
--- /dev/null
+++ b/devel/bmake/files/unit-tests/sunshcmd.exp
@@ -0,0 +1,4 @@
+TEST1=hello
+TEST2=bye
+TEST3=later
+exit status 0
diff --git a/devel/bmake/files/unit-tests/sunshcmd.mk b/devel/bmake/files/unit-tests/sunshcmd.mk
new file mode 100644
index 00000000000..e3baf901e51
--- /dev/null
+++ b/devel/bmake/files/unit-tests/sunshcmd.mk
@@ -0,0 +1,10 @@
+BYECMD = echo bye
+LATERCMD = echo later
+TEST1 :sh = echo hello
+TEST2 :sh = ${BYECMD}
+TEST3 = ${LATERCMD:sh}
+
+all:
+ @echo "TEST1=${TEST1}"
+ @echo "TEST2=${TEST2}"
+ @echo "TEST3=${TEST3}"
diff --git a/devel/bmake/files/unit-tests/sysv.exp b/devel/bmake/files/unit-tests/sysv.exp
new file mode 100644
index 00000000000..4cce2de3191
--- /dev/null
+++ b/devel/bmake/files/unit-tests/sysv.exp
@@ -0,0 +1,7 @@
+FOOBAR =
+FOOBAR = foobar fubar
+fun
+fun
+fun
+In the Sun
+exit status 0
diff --git a/devel/bmake/files/unit-tests/sysv.mk b/devel/bmake/files/unit-tests/sysv.mk
new file mode 100644
index 00000000000..0eb780f91e9
--- /dev/null
+++ b/devel/bmake/files/unit-tests/sysv.mk
@@ -0,0 +1,26 @@
+# $Id: sysv.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+FOO ?=
+FOOBAR = ${FOO:=bar}
+
+_this := ${.PARSEDIR}/${.PARSEFILE}
+
+B = /b
+S = /
+FUN = ${B}${S}fun
+SUN = the Sun
+
+# we expect nothing when FOO is empty
+all: foo fun
+
+foo:
+ @echo FOOBAR = ${FOOBAR}
+.if empty(FOO)
+ @FOO="foo fu" ${.MAKE} -f ${_this} foo
+.endif
+
+fun:
+ @echo ${FUN:T}
+ @echo ${FUN:${B}${S}fun=fun}
+ @echo ${FUN:${B}${S}%=%}
+ @echo ${In:L:%=% ${SUN}}
diff --git a/devel/bmake/files/unit-tests/ternary.exp b/devel/bmake/files/unit-tests/ternary.exp
new file mode 100644
index 00000000000..ed9c1bd9200
--- /dev/null
+++ b/devel/bmake/files/unit-tests/ternary.exp
@@ -0,0 +1,10 @@
+The answer is unknown
+The answer is unknown
+The answer is empty
+The answer is known
+The answer is
+The answer is empty
+The answer is known
+The answer is 42
+The answer is 42
+exit status 0
diff --git a/devel/bmake/files/unit-tests/ternary.mk b/devel/bmake/files/unit-tests/ternary.mk
new file mode 100644
index 00000000000..77f834981c6
--- /dev/null
+++ b/devel/bmake/files/unit-tests/ternary.mk
@@ -0,0 +1,8 @@
+
+all:
+ @for x in "" A= A=42; do ${.MAKE} -f ${MAKEFILE} show $$x; done
+
+show:
+ @echo "The answer is ${A:?known:unknown}"
+ @echo "The answer is ${A:?$A:unknown}"
+ @echo "The answer is ${empty(A):?empty:$A}"
diff --git a/devel/bmake/files/unit-tests/unexport-env.exp b/devel/bmake/files/unit-tests/unexport-env.exp
new file mode 100644
index 00000000000..6d43cab48a5
--- /dev/null
+++ b/devel/bmake/files/unit-tests/unexport-env.exp
@@ -0,0 +1,2 @@
+UT_TEST=unexport-env
+exit status 0
diff --git a/devel/bmake/files/unit-tests/unexport-env.mk b/devel/bmake/files/unit-tests/unexport-env.mk
new file mode 100644
index 00000000000..b5cc537dee4
--- /dev/null
+++ b/devel/bmake/files/unit-tests/unexport-env.mk
@@ -0,0 +1,14 @@
+# $Id: unexport-env.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# pick up a bunch of exported vars
+.include "export.mk"
+
+# an example of setting up a minimal environment.
+PATH = /bin:/usr/bin:/sbin:/usr/sbin
+
+# now clobber the environment to just PATH and UT_TEST
+UT_TEST = unexport-env
+
+# this removes everything
+.unexport-env
+.export PATH UT_TEST
diff --git a/devel/bmake/files/unit-tests/unexport.exp b/devel/bmake/files/unit-tests/unexport.exp
new file mode 100644
index 00000000000..7b16ea3659a
--- /dev/null
+++ b/devel/bmake/files/unit-tests/unexport.exp
@@ -0,0 +1,4 @@
+UT_DOLLAR=This is $UT_FU
+UT_FU=fubar
+UT_TEST=unexport
+exit status 0
diff --git a/devel/bmake/files/unit-tests/unexport.mk b/devel/bmake/files/unit-tests/unexport.mk
new file mode 100644
index 00000000000..0d204a5d31e
--- /dev/null
+++ b/devel/bmake/files/unit-tests/unexport.mk
@@ -0,0 +1,8 @@
+# $Id: unexport.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+
+# pick up a bunch of exported vars
+.include "export.mk"
+
+.unexport UT_ZOO UT_FOO
+
+UT_TEST = unexport
diff --git a/devel/bmake/files/unit-tests/varcmd.exp b/devel/bmake/files/unit-tests/varcmd.exp
new file mode 100644
index 00000000000..34dd637f93e
--- /dev/null
+++ b/devel/bmake/files/unit-tests/varcmd.exp
@@ -0,0 +1,9 @@
+default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v>
+two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
+three FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
+four FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
+five FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
+five v=is x k=is x
+six v=is y k=is y
+show-v v=override k=override
+exit status 0
diff --git a/devel/bmake/files/unit-tests/varcmd.mk b/devel/bmake/files/unit-tests/varcmd.mk
new file mode 100644
index 00000000000..b107a7ccec8
--- /dev/null
+++ b/devel/bmake/files/unit-tests/varcmd.mk
@@ -0,0 +1,49 @@
+# $Id: varcmd.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# Test behaviour of recursive make and vars set on command line.
+
+FU=fu
+FOO?=foo
+.if !empty(.TARGETS)
+TAG=${.TARGETS}
+.endif
+TAG?=default
+
+all: one
+
+show:
+ @echo "${TAG} FU=<v>${FU}</v> FOO=<v>${FOO}</v> VAR=<v>${VAR}</v>"
+
+one: show
+ @${.MAKE} -f ${MAKEFILE} FU=bar FOO=goo two
+
+two: show
+ @${.MAKE} -f ${MAKEFILE} three
+
+three: show
+ @${.MAKE} -f ${MAKEFILE} four
+
+
+.ifmake four
+VAR=Internal
+.MAKEOVERRIDES+= VAR
+.endif
+
+four: show
+ @${.MAKE} -f ${MAKEFILE} five
+
+M = x
+V.y = is y
+V.x = is x
+V := ${V.$M}
+K := ${V}
+
+show-v:
+ @echo '${TAG} v=${V} k=${K}'
+
+five: show show-v
+ @${.MAKE} -f ${MAKEFILE} M=y six
+
+six: show-v
+ @${.MAKE} -f ${MAKEFILE} V=override show-v
+
diff --git a/devel/bmake/files/unit-tests/varmisc.exp b/devel/bmake/files/unit-tests/varmisc.exp
new file mode 100644
index 00000000000..1636aafc11e
--- /dev/null
+++ b/devel/bmake/files/unit-tests/varmisc.exp
@@ -0,0 +1,2 @@
+
+exit status 0
diff --git a/devel/bmake/files/unit-tests/varmisc.mk b/devel/bmake/files/unit-tests/varmisc.mk
new file mode 100644
index 00000000000..47da97329ad
--- /dev/null
+++ b/devel/bmake/files/unit-tests/varmisc.mk
@@ -0,0 +1,8 @@
+# $Id: varmisc.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# Miscellaneous variable tests.
+
+all: unmatched_var_paren
+
+unmatched_var_paren:
+ @echo ${foo::=foo-text}
diff --git a/devel/bmake/files/unit-tests/varshell.exp b/devel/bmake/files/unit-tests/varshell.exp
new file mode 100644
index 00000000000..dae2c6b9dff
--- /dev/null
+++ b/devel/bmake/files/unit-tests/varshell.exp
@@ -0,0 +1,10 @@
+make: "varshell.mk" line 5: warning: "/bin/no/such/command 2> /dev/null" returned non-zero status
+make: "varshell.mk" line 8: warning: "false" returned non-zero status
+make: "varshell.mk" line 9: warning: "echo "output before the error"; false" returned non-zero status
+EXEC_FAILED=''
+TERMINATED_BY_SIGNAL=''
+ERROR_NO_OUTPUT=''
+ERROR_WITH_OUTPUT='output before the error'
+NO_ERROR_NO_OUTPUT=''
+NO_ERROR_WITH_OUTPUT='this is good'
+exit status 0
diff --git a/devel/bmake/files/unit-tests/varshell.mk b/devel/bmake/files/unit-tests/varshell.mk
new file mode 100644
index 00000000000..c7934b6afd6
--- /dev/null
+++ b/devel/bmake/files/unit-tests/varshell.mk
@@ -0,0 +1,19 @@
+# $Id: varshell.mk,v 1.1.1.1 2015/05/19 21:36:45 joerg Exp $
+#
+# Test VAR != shell command
+
+EXEC_FAILED != /bin/no/such/command 2> /dev/null
+# SunOS cannot handle this one
+#TERMINATED_BY_SIGNAL != kill -14 $$$$
+ERROR_NO_OUTPUT != false
+ERROR_WITH_OUTPUT != echo "output before the error"; false
+NO_ERROR_NO_OUTPUT != true
+NO_ERROR_WITH_OUTPUT != echo "this is good"
+
+allvars= EXEC_FAILED TERMINATED_BY_SIGNAL ERROR_NO_OUTPUT ERROR_WITH_OUTPUT \
+ NO_ERROR_NO_OUTPUT NO_ERROR_WITH_OUTPUT
+
+all:
+.for v in ${allvars}
+ @echo ${v}=\'${${v}}\'
+.endfor
diff --git a/devel/bmake/files/util.c b/devel/bmake/files/util.c
index 89210546bf3..30b813ef084 100644
--- a/devel/bmake/files/util.c
+++ b/devel/bmake/files/util.c
@@ -1,18 +1,21 @@
-/* $NetBSD: util.c,v 1.1.1.9 2011/06/18 22:18:10 bsiegert Exp $ */
+/* $NetBSD: util.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $ */
/*
* Missing stuff from OS's
*
- * $Id: util.c,v 1.1.1.9 2011/06/18 22:18:10 bsiegert Exp $
+ * $Id: util.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $
*/
+#if defined(__MINT__) || defined(__linux__)
+#include <signal.h>
+#endif
#include "make.h"
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: util.c,v 1.1.1.9 2011/06/18 22:18:10 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: util.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $";
#else
#ifndef lint
-__RCSID("$NetBSD: util.c,v 1.1.1.9 2011/06/18 22:18:10 bsiegert Exp $");
+__RCSID("$NetBSD: util.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif
@@ -37,7 +40,7 @@ strerror(int e)
}
#endif
-#if !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
+#if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
extern char **environ;
static char *
@@ -46,11 +49,12 @@ findenv(const char *name, int *offset)
size_t i, len;
char *p, *q;
+ len = strlen(name);
for (i = 0; (q = environ[i]); i++) {
p = strchr(q, '=');
- if (p == NULL)
+ if (p == NULL || p - q != len)
continue;
- if (strncmp(name, q, len = p - q) == 0) {
+ if (strncmp(name, q, len) == 0) {
*offset = i;
return q + len + 1;
}
@@ -58,9 +62,15 @@ findenv(const char *name, int *offset)
*offset = i;
return NULL;
}
-#endif
-#if !defined(HAVE_UNSETENV)
+char *
+getenv(const char *name)
+{
+ int offset;
+
+ return(findenv(name, &offset));
+}
+
int
unsetenv(const char *name)
{
@@ -79,13 +89,10 @@ unsetenv(const char *name)
}
return 0;
}
-#endif
-#if !defined(HAVE_SETENV)
int
setenv(const char *name, const char *value, int rewrite)
{
- static char **saveenv; /* copy of previously allocated space */
char *c, **newenv;
const char *cc;
size_t l_value, size;
@@ -108,20 +115,20 @@ setenv(const char *name, const char *value, int rewrite)
goto copy;
} else { /* create new slot */
size = sizeof(char *) * (offset + 2);
- if (saveenv == environ) { /* just increase size */
- if ((newenv = realloc(saveenv, size)) == NULL)
+ if (savedEnv == environ) { /* just increase size */
+ if ((newenv = realloc(savedEnv, size)) == NULL)
return -1;
- saveenv = newenv;
+ savedEnv = newenv;
} else { /* get new space */
/*
* We don't free here because we don't know if
* the first allocation is valid on all OS's
*/
- if ((saveenv = malloc(size)) == NULL)
+ if ((savedEnv = malloc(size)) == NULL)
return -1;
- (void)memcpy(saveenv, environ, size - sizeof(char *));
+ (void)memcpy(savedEnv, environ, size - sizeof(char *));
}
- environ = saveenv;
+ environ = savedEnv;
environ[offset + 1] = NULL;
}
for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */
diff --git a/devel/bmake/files/var.c b/devel/bmake/files/var.c
index 28fa6c30e57..946a235f310 100644
--- a/devel/bmake/files/var.c
+++ b/devel/bmake/files/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.1.1.9 2011/06/18 22:18:13 bsiegert Exp $ */
+/* $NetBSD: var.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.1.1.9 2011/06/18 22:18:13 bsiegert Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.1.1.9 2011/06/18 22:18:13 bsiegert Exp $");
+__RCSID("$NetBSD: var.c,v 1.1.1.10 2015/05/19 21:36:44 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -139,6 +139,13 @@ __RCSID("$NetBSD: var.c,v 1.1.1.9 2011/06/18 22:18:13 bsiegert Exp $");
#include "dir.h"
#include "job.h"
+extern int makelevel;
+/*
+ * This lets us tell if we have replaced the original environ
+ * (which we cannot free).
+ */
+char **savedEnv = NULL;
+
/*
* This is a harmless return value for Var_Parse that can be used by Var_Subst
* to determine if there was an error in parsing -- easier than returning
@@ -169,6 +176,7 @@ static char varNoError[] = "";
* The four contexts are searched in the reverse order from which they are
* listed.
*/
+GNode *VAR_INTERNAL; /* variables from make itself */
GNode *VAR_GLOBAL; /* variables from the makefile */
GNode *VAR_CMD; /* variables defined on the command-line */
@@ -303,7 +311,6 @@ static char *VarGetPattern(GNode *, Var_Parse_State *,
int, const char **, int, int *, int *,
VarPattern *);
static char *VarQuote(char *);
-static char *VarChangeCase(char *, int);
static char *VarHash(char *);
static char *VarModify(GNode *, Var_Parse_State *,
const char *,
@@ -402,6 +409,10 @@ VarFind(const char *name, GNode *ctxt, int flags)
(ctxt != VAR_GLOBAL))
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+ if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
+ /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
+ var = Hash_FindEntry(&VAR_INTERNAL->context, name);
+ }
}
if ((var == NULL) && (flags & FIND_ENV)) {
char *env;
@@ -423,6 +434,9 @@ VarFind(const char *name, GNode *ctxt, int flags)
(ctxt != VAR_GLOBAL))
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+ if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
+ var = Hash_FindEntry(&VAR_INTERNAL->context, name);
+ }
if (var == NULL) {
return NULL;
} else {
@@ -524,11 +538,20 @@ void
Var_Delete(const char *name, GNode *ctxt)
{
Hash_Entry *ln;
-
- ln = Hash_FindEntry(&ctxt->context, name);
+ char *cp;
+
+ if (strchr(name, '$')) {
+ cp = Var_Subst(NULL, name, VAR_GLOBAL, 0);
+ } else {
+ cp = (char *)name;
+ }
+ ln = Hash_FindEntry(&ctxt->context, cp);
if (DEBUG(VAR)) {
fprintf(debug_file, "%s:delete %s%s\n",
- ctxt->name, name, ln ? "" : " (not found)");
+ ctxt->name, cp, ln ? "" : " (not found)");
+ }
+ if (cp != name) {
+ free(cp);
}
if (ln != NULL) {
Var *v;
@@ -643,6 +666,15 @@ Var_ExportVars(void)
char *val;
int n;
+ /*
+ * Several make's support this sort of mechanism for tracking
+ * recursion - but each uses a different name.
+ * We allow the makefiles to update MAKELEVEL and ensure
+ * children see a correctly incremented value.
+ */
+ snprintf(tmp, sizeof(tmp), "%d", makelevel + 1);
+ setenv(MAKE_LEVEL_ENV, tmp, 1);
+
if (VAR_EXPORTED_NONE == var_exportedVars)
return;
@@ -742,6 +774,8 @@ Var_Export(char *str, int isExport)
/*
* This is called when .unexport[-env] is seen.
*/
+extern char **environ;
+
void
Var_UnExport(char *str)
{
@@ -760,28 +794,26 @@ Var_UnExport(char *str)
str += 8;
unexport_env = (strncmp(str, "-env", 4) == 0);
if (unexport_env) {
- extern char **environ;
- static char **savenv;
char **newenv;
- cp = getenv(MAKE_LEVEL); /* we should preserve this */
- if (environ == savenv) {
+ cp = getenv(MAKE_LEVEL_ENV); /* we should preserve this */
+ if (environ == savedEnv) {
/* we have been here before! */
newenv = bmake_realloc(environ, 2 * sizeof(char *));
} else {
- if (savenv) {
- free(savenv);
- savenv = NULL;
+ if (savedEnv) {
+ free(savedEnv);
+ savedEnv = NULL;
}
newenv = bmake_malloc(2 * sizeof(char *));
}
if (!newenv)
return;
/* Note: we cannot safely free() the original environ. */
- environ = savenv = newenv;
+ environ = savedEnv = newenv;
newenv[0] = NULL;
newenv[1] = NULL;
- setenv(MAKE_LEVEL, cp, 1);
+ setenv(MAKE_LEVEL_ENV, cp, 1);
} else {
for (; *str != '\n' && isspace((unsigned char) *str); str++)
continue;
@@ -905,6 +937,14 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
}
v = VarFind(name, ctxt, 0);
if (v == NULL) {
+ if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
+ /*
+ * This var would normally prevent the same name being added
+ * to VAR_GLOBAL, so delete it from there if needed.
+ * Otherwise -V name may show the wrong value.
+ */
+ Var_Delete(name, VAR_GLOBAL);
+ }
VarAdd(name, val, ctxt);
} else {
Buf_Empty(&v->val);
@@ -939,22 +979,6 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
}
- /*
- * Another special case.
- * Several make's support this sort of mechanism for tracking
- * recursion - but each uses a different name.
- * We allow the makefiles to update .MAKE.LEVEL and ensure
- * children see a correctly incremented value.
- */
- if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) {
- char tmp[64];
- int level;
-
- level = atoi(val);
- snprintf(tmp, sizeof(tmp), "%u", level + 1);
- setenv(MAKE_LEVEL, tmp, 1);
- }
-
out:
if (expanded_name != NULL)
@@ -1133,7 +1157,7 @@ Var_Value(const char *name, GNode *ctxt, char **frp)
*-----------------------------------------------------------------------
*/
static Boolean
-VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarHead(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *dummy)
{
@@ -1181,7 +1205,7 @@ VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static Boolean
-VarTail(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarTail(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *dummy)
{
@@ -1223,7 +1247,7 @@ VarTail(GNode *ctx __unused, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static Boolean
-VarSuffix(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarSuffix(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *dummy)
{
@@ -1264,7 +1288,7 @@ VarSuffix(GNode *ctx __unused, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static Boolean
-VarRoot(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarRoot(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *dummy)
{
@@ -1308,7 +1332,7 @@ VarRoot(GNode *ctx __unused, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static Boolean
-VarMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *pattern)
{
@@ -1399,7 +1423,7 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static Boolean
-VarNoMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarNoMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *pattern)
{
@@ -1436,7 +1460,7 @@ VarNoMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static Boolean
-VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
void *patternp)
{
@@ -1632,7 +1656,8 @@ VarREError(int errnum, regex_t *pat, const char *str)
*-----------------------------------------------------------------------
*/
static Boolean
-VarRESubstitute(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
+VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED,
+ Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
char *word, Boolean addSpace, Buffer *buf,
void *patternp)
{
@@ -1772,7 +1797,8 @@ VarRESubstitute(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
*-----------------------------------------------------------------------
*/
static Boolean
-VarLoopExpand(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
+VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED,
+ Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
char *word, Boolean addSpace, Buffer *buf,
void *loopp)
{
@@ -1815,7 +1841,7 @@ VarLoopExpand(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
*-----------------------------------------------------------------------
*/
static char *
-VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
const char *str, VarSelectWords_t *seldata)
{
Buffer buf; /* Buffer for the new string */
@@ -1890,9 +1916,9 @@ VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
* if successful.
*/
static Boolean
-VarRealpath(GNode *ctx __unused, Var_Parse_State *vpstate,
+VarRealpath(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
char *word, Boolean addSpace, Buffer *buf,
- void *patternp __unused)
+ void *patternp MAKE_ATTR_UNUSED)
{
struct stat st;
char rbuf[MAXPATHLEN];
@@ -2115,7 +2141,7 @@ VarUniq(const char *str)
*-----------------------------------------------------------------------
*/
static char *
-VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate __unused,
+VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
int errnum, const char **tstr, int delim, int *flags,
int *length, VarPattern *pattern)
{
@@ -2288,9 +2314,7 @@ VarHash(char *str)
size_t len, len2;
unsigned char *ustr = (unsigned char *)str;
uint32_t h, k, c1, c2;
- int done;
- done = 1;
h = 0x971e137bU;
c1 = 0x95543787U;
c2 = 0x2ad7eb25U;
@@ -2320,7 +2344,7 @@ VarHash(char *str)
h = (h << 13) ^ (h >> 19);
h = h * 5 + 0x52dce729U;
h ^= k;
- } while (!done);
+ }
h ^= len2;
h *= 0x85ebca6b;
h ^= h >> 13;
@@ -2336,37 +2360,6 @@ VarHash(char *str)
return Buf_Destroy(&buf, FALSE);
}
-/*-
- *-----------------------------------------------------------------------
- * VarChangeCase --
- * Change the string to all uppercase or all lowercase
- *
- * Input:
- * str String to modify
- * upper TRUE -> uppercase, else lowercase
- *
- * Results:
- * The string with case changed
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-static char *
-VarChangeCase(char *str, int upper)
-{
- Buffer buf;
- int (*modProc)(int);
-
- modProc = (upper ? toupper : tolower);
- Buf_Init(&buf, 0);
- for (; *str ; str++) {
- Buf_AddByte(&buf, modProc(*str));
- }
- return Buf_Destroy(&buf, FALSE);
-}
-
static char *
VarStrftime(const char *fmt, int zulu)
{
@@ -2553,7 +2546,8 @@ ApplyModifiers(char *nstr, const char *tstr,
}
apply_mods:
if (DEBUG(VAR)) {
- fprintf(debug_file, "Applying :%c to \"%s\"\n", *tstr, nstr);
+ fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", v->name,
+ *tstr, nstr);
}
newStr = var_Error;
switch ((modifier = *tstr)) {
@@ -2642,7 +2636,7 @@ ApplyModifiers(char *nstr, const char *tstr,
break;
}
free(UNCONST(pattern.rhs));
- newStr = var_Error;
+ newStr = varNoError;
break;
}
goto default_case; /* "::<unrecognised>" */
@@ -3042,8 +3036,16 @@ ApplyModifiers(char *nstr, const char *tstr,
VarRealpath, NULL);
cp = tstr + 2;
termc = *cp;
- } else if (tstr[1] == 'u' || tstr[1] == 'l') {
- newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
+ } else if (tstr[1] == 'u') {
+ char *dp = bmake_strdup(nstr);
+ for (newStr = dp; *dp; dp++)
+ *dp = toupper((unsigned char)*dp);
+ cp = tstr + 2;
+ termc = *cp;
+ } else if (tstr[1] == 'l') {
+ char *dp = bmake_strdup(nstr);
+ for (newStr = dp; *dp; dp++)
+ *dp = tolower((unsigned char)*dp);
cp = tstr + 2;
termc = *cp;
} else if (tstr[1] == 'W' || tstr[1] == 'w') {
@@ -3153,8 +3155,8 @@ ApplyModifiers(char *nstr, const char *tstr,
free(cp2);
}
if (DEBUG(VAR))
- fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr,
- pattern);
+ fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
+ v->name, nstr, pattern);
if (*tstr == 'M') {
newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
pattern);
@@ -3258,7 +3260,7 @@ ApplyModifiers(char *nstr, const char *tstr,
termc = *--cp;
delim = '\0';
- if (Cond_EvalExpression(NULL, v->name, &value, 0)
+ if (Cond_EvalExpression(NULL, v->name, &value, 0, FALSE)
== COND_INVALID) {
Error("Bad conditional expression `%s' in %s?%s:%s",
v->name, v->name, pattern.lhs, pattern.rhs);
@@ -3509,7 +3511,8 @@ ApplyModifiers(char *nstr, const char *tstr,
}
}
if (DEBUG(VAR)) {
- fprintf(debug_file, "Result of :%c is \"%s\"\n", modifier, newStr);
+ fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
+ v->name, modifier, newStr);
}
if (newStr != nstr) {
@@ -3596,14 +3599,13 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
* expanding it in a non-local context. This
* is done to support dynamic sources. The
* result is just the invocation, unaltered */
- Var_Parse_State parsestate; /* Flags passed to helper functions */
+ const char *extramodifiers; /* extra modifiers to apply first */
char name[2];
*freePtr = NULL;
+ extramodifiers = NULL;
dynamic = FALSE;
start = str;
- parsestate.oneBigWord = FALSE;
- parsestate.varSpace = ' '; /* word separator */
startc = str[1];
if (startc != PROPEN && startc != BROPEN) {
@@ -3657,6 +3659,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
}
} else {
Buffer buf; /* Holds the variable name */
+ int depth = 1;
endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
Buf_Init(&buf, 0);
@@ -3664,11 +3667,22 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
/*
* Skip to the end character or a colon, whichever comes first.
*/
- for (tstr = str + 2;
- *tstr != '\0' && *tstr != endc && *tstr != ':';
- tstr++)
+ for (tstr = str + 2; *tstr != '\0'; tstr++)
{
/*
+ * Track depth so we can spot parse errors.
+ */
+ if (*tstr == startc) {
+ depth++;
+ }
+ if (*tstr == endc) {
+ if (--depth == 0)
+ break;
+ }
+ if (depth == 1 && *tstr == ':') {
+ break;
+ }
+ /*
* A variable inside a variable, expand
*/
if (*tstr == '$') {
@@ -3687,7 +3701,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
}
if (*tstr == ':') {
haveModifier = TRUE;
- } else if (*tstr != '\0') {
+ } else if (*tstr == endc) {
haveModifier = FALSE;
} else {
/*
@@ -3719,7 +3733,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
*/
if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
(vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
- strchr("@%*!<>", str[0]) != NULL) {
+ strchr("@%?*!<>", str[0]) != NULL) {
/*
* Well, it's local -- go look for it.
*/
@@ -3728,29 +3742,12 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
v = VarFind(name, ctxt, 0);
if (v != NULL) {
- /*
- * No need for nested expansion or anything, as we're
- * the only one who sets these things and we sure don't
- * but nested invocations in them...
- */
- nstr = Buf_GetAll(&v->val, NULL);
-
if (str[1] == 'D') {
- nstr = VarModify(ctxt, &parsestate, nstr, VarHead,
- NULL);
- } else {
- nstr = VarModify(ctxt, &parsestate, nstr, VarTail,
- NULL);
+ extramodifiers = "H:";
+ }
+ else { /* F */
+ extramodifiers = "T:";
}
- /*
- * Resulting string is dynamically allocated, so
- * tell caller to free it.
- */
- *freePtr = nstr;
- *lengthPtr = tstr-start+1;
- Buf_Destroy(&buf, TRUE);
- VarFreeEnv(v, TRUE);
- return nstr;
}
}
@@ -3845,16 +3842,29 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
v->flags &= ~VAR_IN_USE;
- if ((nstr != NULL) && haveModifier) {
+ if ((nstr != NULL) && (haveModifier || extramodifiers != NULL)) {
+ void *extraFree;
int used;
- /*
- * Skip initial colon.
- */
- tstr++;
- nstr = ApplyModifiers(nstr, tstr, startc, endc,
- v, ctxt, errnum, &used, freePtr);
- tstr += used;
+ extraFree = NULL;
+ if (extramodifiers != NULL) {
+ nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
+ v, ctxt, errnum, &used, &extraFree);
+ }
+
+ if (haveModifier) {
+ /* Skip initial colon. */
+ tstr++;
+
+ nstr = ApplyModifiers(nstr, tstr, startc, endc,
+ v, ctxt, errnum, &used, freePtr);
+ tstr += used;
+ if (extraFree) {
+ free(extraFree);
+ }
+ } else {
+ *freePtr = extraFree;
+ }
}
if (*tstr) {
*lengthPtr = tstr - start + 1;
@@ -4037,7 +4047,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
*/
if (oldVars) {
str += length;
- } else if (undefErr) {
+ } else if (undefErr || val == var_Error) {
/*
* If variable is undefined, complain and skip the
* variable. The complaint will stop us from doing anything
@@ -4075,7 +4085,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
}
}
- return Buf_Destroy(&buf, FALSE);
+ return Buf_DestroyCompact(&buf);
}
/*-
@@ -4142,6 +4152,7 @@ Var_GetHead(char *file)
void
Var_Init(void)
{
+ VAR_INTERNAL = Targ_NewGN("Internal");
VAR_GLOBAL = Targ_NewGN("Global");
VAR_CMD = Targ_NewGN("Command");