Update to bmake-20160818 on the vendor branch
authorJohn Marino <draco@marino.st>
Mon, 29 Aug 2016 16:40:03 +0000 (11:40 -0500)
committerJohn Marino <marino@rogue.synsport.com>
Mon, 29 Aug 2016 13:05:39 +0000 (08:05 -0500)
77 files changed:
contrib/bmake/ChangeLog
contrib/bmake/FILES
contrib/bmake/Makefile
contrib/bmake/README
contrib/bmake/arch.c
contrib/bmake/bmake.1
contrib/bmake/bmake.cat1
contrib/bmake/boot-strap
contrib/bmake/compat.c
contrib/bmake/cond.c
contrib/bmake/config.h.in
contrib/bmake/configure
contrib/bmake/configure.in
contrib/bmake/dir.c
contrib/bmake/dirname.c
contrib/bmake/for.c
contrib/bmake/getopt.c
contrib/bmake/hash.h
contrib/bmake/job.c
contrib/bmake/machine.sh
contrib/bmake/main.c
contrib/bmake/make-bootstrap.sh.in
contrib/bmake/make.1
contrib/bmake/make.c
contrib/bmake/make.h
contrib/bmake/meta.c
contrib/bmake/meta.h
contrib/bmake/metachar.c [new file with mode: 0644]
contrib/bmake/metachar.h [copied from contrib/bmake/dirname.c with 51% similarity]
contrib/bmake/mk/ChangeLog
contrib/bmake/mk/auto.dep.mk
contrib/bmake/mk/auto.obj.mk
contrib/bmake/mk/autodep.mk
contrib/bmake/mk/dirdeps.mk
contrib/bmake/mk/doc.mk
contrib/bmake/mk/dpadd.mk
contrib/bmake/mk/final.mk
contrib/bmake/mk/gendirdeps.mk
contrib/bmake/mk/host-target.mk
contrib/bmake/mk/init.mk
contrib/bmake/mk/install-mk
contrib/bmake/mk/lib.mk
contrib/bmake/mk/libnames.mk
contrib/bmake/mk/meta.autodep.mk
contrib/bmake/mk/meta.stage.mk
contrib/bmake/mk/meta.subdir.mk
contrib/bmake/mk/meta.sys.mk
contrib/bmake/mk/meta2deps.py
contrib/bmake/mk/meta2deps.sh
contrib/bmake/mk/mkopt.sh
contrib/bmake/mk/nls.mk
contrib/bmake/mk/own.mk
contrib/bmake/mk/prog.mk
contrib/bmake/mk/rst2htm.mk
contrib/bmake/mk/subdir.mk
contrib/bmake/mk/sys.clean-env.mk
contrib/bmake/mk/sys.dependfile.mk
contrib/bmake/mk/sys.mk
contrib/bmake/mk/sys/AIX.mk
contrib/bmake/mk/sys/Darwin.mk
contrib/bmake/mk/sys/Generic.mk
contrib/bmake/mk/sys/HP-UX.mk
contrib/bmake/mk/sys/IRIX.mk
contrib/bmake/mk/sys/Linux.mk
contrib/bmake/mk/sys/NetBSD.mk
contrib/bmake/mk/sys/OSF1.mk
contrib/bmake/mk/sys/OpenBSD.mk
contrib/bmake/mk/sys/SunOS.mk
contrib/bmake/mk/sys/UnixWare.mk
contrib/bmake/mk/warnings.mk
contrib/bmake/nonints.h
contrib/bmake/os.sh
contrib/bmake/parse.c
contrib/bmake/str.c
contrib/bmake/suff.c
contrib/bmake/targ.c
contrib/bmake/var.c

index 88df587..731d939 100644 (file)
@@ -1,3 +1,273 @@
+2016-08-18  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160818
+         its a neater number; pick up whitespace fixes to man page.
+
+2016-08-17  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160817
+         Merge with NetBSD make, pick up
+         o meta.c: move handling of .MAKE.META.IGNORE_* to meta_ignore()
+           so we can call it before adding entries to missingFiles.
+           Thus we do not track files we have been told to ignore.
+
+2016-08-15  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160815
+         Merge with NetBSD make, pick up
+         o meta_oodate: apply .MAKE.META.IGNORE_FILTER (if defined) to
+           pathnames, and skip if the expansion is empty.
+           Useful for dirdeps.mk when checking DIRDEPS_CACHE.
+
+2016-08-12  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160812
+         Merge with NetBSD make, pick up
+         o meta.c: remove all missingFiles entries that match a deleted
+           dir.
+         o main.c: set .ERROR_CMD if possible.
+         
+2016-06-06  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160606
+         Merge with NetBSD make, pick up
+         o dir.c: extend mtimes cache to others via cached_stat()
+
+2016-06-04  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160604
+         Merge with NetBSD make, pick up
+         o meta.c: missing filemon data is only relevant if we read a
+           meta file.
+           Also do not return oodate for a missing metafile if gn->path
+           points to .CURDIR
+       
+2016-06-02  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160602
+         Merge with NetBSD make, pick up
+         o cached_realpath(): avoid hitting filesystem more than necessary.
+         o meta.c: refactor need_meta decision, add knobs for 
+           missing meta file and filemon data wrt out-of-datedness.
+
+2016-05-28  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160528
+
+       * boot-strap, make-bootstrap.sh.in: Makefile now uses _MAKE_VERSION 
+
+2016-05-12  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160512
+         Merge with NetBSD make, pick up
+         o meta.c: ignore paths that match .MAKE.META.IGNORE_PATTERNS
+           this is useful for gcov builds.
+         o propagate errors from filemon(4).
+       
+2016-05-09  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160509
+         Merge with NetBSD make, pick up
+         o remove use of non-standard types u_int etc.
+         o meta.c: apply realpath() before matching against metaIgnorePaths
+
+2016-04-04  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160404
+         Merge with NetBSD make, pick up
+         o allow makefile to set .MAKE.JOBS
+
+       * Makefile (PROG_NAME): use ${_MAKE_VERSION}
+
+2016-03-15  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): 20160315
+         Merge with NetBSD make, pick up
+         o fix handling of archive members
+
+2016-03-13  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (_MAKE_VERSION): rename variable to avoid interference
+         with checks for ${MAKE_VERSION}
+
+2016-03-10  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20160310
+         Merge with NetBSD make, pick up
+         o meta.c: treat missing Read file same as Write, incase we Delete it.
+
+2016-03-07  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20160307
+         Merge with NetBSD make, pick up
+         o var.c: fix :ts\nnn to be octal by default.
+         o meta.c: meta_finish() to cleanup memory.
+
+2016-02-26  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20160226
+         Merge with NetBSD make, pick up
+         o meta.c: allow meta file for makeDepend if makefiles want it.
+
+2016-02-19  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * var.c: default .MAKE.SAVE_DOLLARS to FALSE
+         for backwards compatability.
+
+       * Makefile (MAKE_VERSION): 20160220
+         Merge with NetBSD make, pick up
+         o var.c: add knob to control handling of '$$' in :=
+
+2016-02-18  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20160218
+         Merge with NetBSD make, pick up
+         o var.c: add .export-literal allows us to fix sys.clean-env.mk
+           post the changes to Var_Subst.
+           Var_Subst now takes flags, and does not consume '$$' in :=
+
+2016-02-17  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20160217
+         Merge with NetBSD make, pick up
+         o var.c: preserve '$$' in :=
+         o parse.c: add .dinclude for handling included 
+           makefile like .depend
+
+2015-12-20  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151220
+         Merge with NetBSD make, pick up
+         o suff.c: re-initialize suffNull when clearing suffixes.
+
+2015-12-01  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151201
+         Merge with NetBSD make, pick up
+         o cond.c: CondCvtArg: avoid access beyond end of empty buffer.
+         o meta.c: meta_oodate: use lstat(2) for checking link target
+           in case it is a symlink.
+         o var.c: avoid calling brk_string and Var_Export1 with empty
+           strings.
+       
+2015-11-26  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151126
+         Merge with NetBSD make, pick up
+         o parse.c: ParseTrackInput don't access beyond 
+           end of old value.
+       
+2015-10-22  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151022
+
+       * Add support for BSD/OS which lacks inttypes.h
+         and really needs sys/param.h for sys/sysctl.h
+         also 'type' is not a shell builtin.
+
+       * var.c: eliminate uint32_t and need for inttypes.h
+       
+       * main.c: PrintOnError flush stdout before run .ERROR
+
+       * parse.c: cope with _SC_PAGESIZE not being defined.
+
+       
+2015-10-20  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151020
+         Merge with NetBSD make, pick up
+         o var.c: fix uninitialized var 
+
+2015-10-12  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * var.c: the conditional expressions used with ':?' can be
+       expensive, if already discarding do not evaluate or expand
+       anything. 
+
+2015-10-10  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151010
+         Merge with NetBSD make, pick up
+         o Add Boolean wantit flag to Var_Subst and Var_Parse
+           when FALSE we know we are discarding the result and can
+           skip operations like Cmd_Exec.
+
+2015-10-09  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20151009
+         Merge with NetBSD make, pick up
+         o var.c: don't check for NULL before free()
+         o meta.c: meta_oodate, do not hard code ignore of makeDependfile
+
+2015-09-10  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20150910
+         Merge with NetBSD make, pick up
+         o main.c: with -w print Enter/Leaving messages for objdir too
+           if necessary.
+         o centralize shell metachar handling
+       
+       * FILES: add metachar.[ch]
+
+2015-06-06  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Makefile (MAKE_VERSION): 20150606
+         Merge with NetBSD make, pick up
+         o make.1: document .OBJDIR target
+
+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
index 8189973..720eb1b 100644 (file)
@@ -71,6 +71,8 @@ make_malloc.h
 makefile.in
 meta.c
 meta.h
+metachar.c
+metachar.h
 missing/sys/cdefs.h
 mkdeps.sh
 nonints.h
@@ -96,6 +98,8 @@ 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
index 93e0066..fbb9b0a 100644 (file)
@@ -1,7 +1,7 @@
-#      $Id: Makefile,v 1.30 2014/11/11 15:57:11 sjg Exp $
+#      $Id: Makefile,v 1.72 2016/08/18 23:02:26 sjg Exp $
 
 # Base version on src date
-MAKE_VERSION= 20141111
+_MAKE_VERSION= 20160818
 
 PROG=  bmake
 
@@ -18,6 +18,7 @@ SRCS= \
        make.c \
        make_malloc.c \
        meta.c \
+       metachar.c \
        parse.c \
        str.c \
        strlist.c \
@@ -75,7 +76,7 @@ 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}\""
+COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\""
 
 # meta mode can be useful even without filemon 
 FILEMON_H ?= /usr/include/dev/filemon/filemon.h
@@ -94,7 +95,7 @@ SUBDIR+= unit-tests
 # 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
+BSD44_LIST= NetBSD FreeBSD OpenBSD DragonFly MirBSD Bitrig
 # we are...
 OS!= uname -s
 # are we 4.4BSD ?
@@ -130,9 +131,9 @@ OPTIONS_DEFAULT_NO+= \
 .include <own.mk>
 
 .if ${MK_PROG_VERSION} == "yes"
-PROG_NAME= ${PROG}-${MAKE_VERSION}
+PROG_NAME= ${PROG}-${_MAKE_VERSION}
 .if ${MK_PROG_LINK} == "yes"
-SYMLINKS+= ${PROG}-${MAKE_VERSION} ${BINDIR}/${PROG}
+SYMLINKS+= ${PROG_NAME} ${BINDIR}/${PROG}
 .endif
 .endif
 
@@ -180,9 +181,9 @@ COPTS.parse.c += -Wno-format-nonliteral
 COPTS.var.c += -Wno-format-nonliteral
 
 # Force these
-SHAREDIR= ${prefix}/share
-BINDIR= ${prefix}/bin
-MANDIR= ${SHAREDIR}/man
+SHAREDIR= ${SHAREDIR.bmake:U${prefix}/share}
+BINDIR= ${BINDIR.bmake:U${prefix}/bin}
+MANDIR= ${MANDIR.bmake:U${SHAREDIR}/man}
 
 .if !exists(.depend)
 ${OBJS}: config.h
index d09e977..a782f6d 100644 (file)
@@ -1,47 +1,52 @@
                               bmake
+                              *****
 
-This directory contains a port of the BSD make tool (from NetBSD)
-I have run it on SunOS,Solaris,HP-UX,AIX,IRIX,FreeBSD and Linux.
+This directory contains a port of the BSD make tool (from NetBSD).
+Since 1993 I have run it on AIX, BSDi, Darwin, FreeBSD, HP-UX, IRIX,
+Linux, Minix, OSF, Solaris, SunOS and even UTS.
+Others have run it on many more systems.
 
-Version 3 was re-worked from scratch to better facilitate
-importing newer make(1) versions from NetBSD.  The original code base
-was NetBSD-1.0, so version 3 was built by doing a fresh import of the
-NetBSD-1.0 usr.bin/make, adding the autoconf and other portability
-patches to sync it with bmake v2, and then NetBSD's make 
-of Feb 20, 2000 was imported and conflicts dealt with.
-NetBSD's make was again imported on June 6 and December 15, 2000.
+Currently each release is tested on NetBSD, FreeBSD, Solaris and Linux.
 
-In 2003 bmake switched to a date based version (first was 20030714)
+Since 2003 bmake switched to a date based version (first was 20030714)
 which generally represents the date it was last merged with NetBSD's
 make.  Since then, NetBSD's make is imported within a week of any
 interesting changes, so that bmake tracks it very closely.
 
-Building:
+Building
+========
 
-The preferred way to bootstrap bmake is:
+The preferred way to bootstrap bmake is::
 
-./bmake/boot-strap
+       ./bmake/boot-strap
 
 there are a number of args - most of which get passed to configure,
 eg.
+::
 
-./bmake/boot-strap --prefix=/opt
+       ./bmake/boot-strap --prefix=/opt
 
 see the boot-strap script for details.
 
+For folk that hate to read anything, since 20121212 you can also use
+the GNU standard process of::
+
+       ./configure; make; make install
+
 To make much use of bmake you will need the bsd.*.mk macros or my
-portable *.mk macros.  See 
+portable *.mk macros which are included with bmake since 20121212
+and separately available from
 http://www.crufty.net/ftp/pub/sjg/mk.tar.gz
 which will be links to the latest versions.
 
-On a non-BSD system, you would want to unpack mk[-YYYYmmdd].tar.gz in
-the same directory as bmake (so ./mk and ./bmake exist), and
-./bmake/boot-strap will do the rest.
+Porting
+=======
+
+If you encounter a system that bmake does not build or work on *out of
+the box*, I welcome patches.
+If you can provide access to a suitable machine - even better.
 
-If you want to do it all by hand then read boot-strap first to get the
-idea.
+More info can be found at http://www.crufty.net/help/sjg/bmake.htm
 
-Even if you have an earlier version of bmake installed, use boot-strap
-to ensure that all goes well.
+--sjg <sjg@crufty.net>
 
---sjg
index 943f41e..1b5bab7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $  */
+/*     $NetBSD: arch.c,v 1.69 2016/04/06 09:57:00 gson Exp $   */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $";
+static char rcsid[] = "$NetBSD: arch.c,v 1.69 2016/04/06 09:57:00 gson 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.63 2012/06/12 19:21:50 joerg Exp $");
+__RCSID("$NetBSD: arch.c,v 1.69 2016/04/06 09:57:00 gson Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -136,7 +136,6 @@ __RCSID("$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $");
 #include    <sys/stat.h>
 #include    <sys/time.h>
 #include    <sys/param.h>
-#include    <ctype.h>
 #ifdef HAVE_AR_H
 #include    <ar.h>
 #else
@@ -156,7 +155,6 @@ struct ar_hdr {
 #if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB))
 #include    <ranlib.h>
 #endif
-#include    <fcntl.h>
 #include    <stdio.h>
 #include    <stdlib.h>
 #ifdef HAVE_UTIME_H
@@ -254,8 +252,7 @@ ArchFree(void *ap)
        free(Hash_GetValue(entry));
 
     free(a->name);
-    if (a->fnametab)
-       free(a->fnametab);
+    free(a->fnametab);
     Hash_DeleteTable(&a->members);
     free(a);
 }
@@ -310,9 +307,10 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
            void        *freeIt;
            char        *result;
 
-           result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
-           if (freeIt)
-               free(freeIt);
+           result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
+                              &length, &freeIt);
+           free(freeIt);
+
            if (result == var_Error) {
                return(FAILURE);
            } else {
@@ -325,7 +323,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
 
     *cp++ = '\0';
     if (subLibName) {
-       libName = Var_Subst(NULL, libName, ctxt, TRUE);
+       libName = Var_Subst(NULL, libName, ctxt, VARF_UNDEFERR|VARF_WANTRES);
     }
 
 
@@ -351,9 +349,10 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
                void    *freeIt;
                char    *result;
 
-               result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
-               if (freeIt)
-                   free(freeIt);
+               result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
+                                  &length, &freeIt);
+               free(freeIt);
+
                if (result == var_Error) {
                    return(FAILURE);
                } else {
@@ -404,7 +403,8 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
            char    *oldMemName = memName;
            size_t   sz;
 
-           memName = Var_Subst(NULL, memName, ctxt, TRUE);
+           memName = Var_Subst(NULL, memName, ctxt,
+                               VARF_UNDEFERR|VARF_WANTRES);
 
            /*
             * Now form an archive spec and recurse to deal with nested
@@ -759,8 +759,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
 badarch:
     fclose(arch);
     Hash_DeleteTable(&ar->members);
-    if (ar->fnametab)
-       free(ar->fnametab);
+    free(ar->fnametab);
     free(ar);
     return NULL;
 }
@@ -833,7 +832,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
            }
        if (DEBUG(ARCH)) {
            fprintf(debug_file, "Found svr4 archive name table with %lu entries\n",
-                   (u_long)entry);
+                   (unsigned long)entry);
        }
        return 0;
     }
@@ -851,7 +850,7 @@ ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch)
     if (entry >= ar->fnamesize) {
        if (DEBUG(ARCH)) {
            fprintf(debug_file, "SVR4 entry offset %s is greater than %lu\n",
-                  name, (u_long)ar->fnamesize);
+                  name, (unsigned long)ar->fnamesize);
        }
        return 2;
     }
@@ -1045,10 +1044,10 @@ Arch_Touch(GNode *gn)
     arch = ArchFindMember(Var_Value(ARCHIVE, gn, &p1),
                          Var_Value(MEMBER, gn, &p2),
                          &arh, "r+");
-    if (p1)
-       free(p1);
-    if (p2)
-       free(p2);
+
+    free(p1);
+    free(p2);
+
     snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
 
     if (arch != NULL) {
@@ -1127,10 +1126,9 @@ Arch_MTime(GNode *gn)
     arhPtr = ArchStatMember(Var_Value(ARCHIVE, gn, &p1),
                             Var_Value(MEMBER, gn, &p2),
                             TRUE);
-    if (p1)
-       free(p1);
-    if (p2)
-       free(p2);
+
+    free(p1);
+    free(p2);
 
     if (arhPtr != NULL) {
        modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10);
index 5363e88..4ea8dee 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: make.1,v 1.229 2014/01/19 10:23:29 apb Exp $
+.\"    $NetBSD: make.1,v 1.262 2016/08/18 19:23:20 wiz 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 February 14, 2014
+.Dd August 15, 2016
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -209,8 +209,6 @@ Force the
 option to print raw values of variables.
 .It Ar v
 Print debugging information about variable assignment.
-.It Ar w
-Print entering and leaving directory messages, pre and post processing.
 .It Ar x
 Run shell commands with
 .Fl x
@@ -295,7 +293,7 @@ then
 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.
+the Makefile and then works upward towards the root of the file system.
 If the search is successful, then the resulting directory replaces the
 .Qq \&.../
 specification in the
@@ -352,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.
@@ -441,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
@@ -469,6 +481,7 @@ 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
@@ -477,22 +490,21 @@ 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.
-.Pp
 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
+it will be passed to the shell; otherwise
 .Nm
 will attempt direct execution.
-.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.
+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
@@ -500,20 +512,32 @@ operation does not change their behavior.
 For example, any command which needs to use
 .Dq cd
 or
-.Dq chdir ,
-without side-effect should be put in parenthesis:
+.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} $@)
+       @(cd ${.CURDIR} && ${MAKE} $@)
        @echo Back in `pwd`
 
 ensure-one-shell-regardless-of-mode:
-       @echo Building $@ in `pwd`; \\
-       (cd ${.CURDIR} && ${.MAKE} $@); \\
+       @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.
@@ -624,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
@@ -639,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
@@ -648,31 +679,44 @@ 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 @ .
+For compatibility with other makes this is an alias for
+.Ic .ARCHIVE
+in archive member rules.
 .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.
@@ -682,7 +726,6 @@ These variables are
 .Ql Va .ARCHIVE ,
 and
 .Ql Va .MEMBER .
-.El
 .Ss Additional built-in variables
 In addition,
 .Nm
@@ -803,7 +846,7 @@ Can affect the mode that
 .Nm
 runs in.
 It can contain a number of keywords:
-.Bl -hang -width ignore-cmd
+.Bl -hang -width missing-filemon=bf.
 .It Pa compat
 Like
 .Fl B ,
@@ -827,8 +870,19 @@ will not create .meta files in
 This can be overridden by setting
 .Va bf
 to a value which represents True.
+.It Pa missing-meta= Ar bf
+If
+.Va bf
+is True, then a missing .meta file makes the target out-of-date.
+.It Pa missing-filemon= Ar bf
+If
+.Va bf
+is True, then missing filemon data makes the target out-of-date.
+.It Pa nofilemon
+Do not use
+.Xr filemon 4 .
 .It Pa env
-For debugging, it can be useful to inlcude the environment
+For debugging, it can be useful to include the environment
 in the .meta file.
 .It Pa verbose
 If in "meta" mode, print a clue about the target being built.
@@ -870,6 +924,12 @@ 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.IGNORE_PATTERNS
+Provides a list of patterns to match against pathnames.
+Ignore any that match.
+.It Va .MAKE.META.IGNORE_FILTER
+Provides a list of variable modifiers to apply to each pathname.
+Ignore if the expansion is an empty string.
 .It Va .MAKE.META.PREFIX
 Defines the message printed for each meta file updated in "meta verbose" mode.
 The default value is:
@@ -878,7 +938,7 @@ The default value is:
 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
 .Ql Ev MAKEFLAGS .
-This behaviour can be disabled by assigning an empty value to
+This behavior can be disabled by assigning an empty value to
 .Ql Va .MAKEOVERRIDES
 within a makefile.
 Extra variables can be exported from a makefile
@@ -901,10 +961,35 @@ The process-id of
 .It Va .MAKE.PPID
 The parent process-id of
 .Nm .
+.It Va .MAKE.SAVE_DOLLARS
+value should be a boolean that controls whether
+.Ql $$
+are preserved when doing
+.Ql :=
+assignments.
+The default is false, for backwards compatibility.
+Set to true for compatability with other makes.
+If set to false,
+.Ql $$
+becomes
+.Ql $
+per normal evaluation rules.
 .It Va MAKE_PRINT_VAR_ON_ERROR
 When
 .Nm
-stops due to an error, it prints its name and the value of
+stops due to an error, it sets
+.Ql Va .ERROR_TARGET
+to the name of the target that failed,
+.Ql Va .ERROR_CMD
+to the commands of the failed target,
+and in "meta" mode, it also sets
+.Ql Va .ERROR_CWD
+to the
+.Xr getcwd 3 ,
+and
+.Ql Va .ERROR_META_FILE
+to the path of the meta file (if any) describing the failed target.
+It then prints its name and the value of
 .Ql Va .CURDIR
 as well as the value of any variables named in
 .Ql Va MAKE_PRINT_VAR_ON_ERROR .
@@ -953,14 +1038,15 @@ This is especially useful with
 .Ql Ev MAKEOBJDIR .
 .Pp
 .Ql Va .OBJDIR
-may be modified in the makefile as a global variable.
+may be modified in the makefile via the special target
+.Ql Ic .OBJDIR .
 In all cases,
 .Nm
 will
 .Xr chdir 2
-to
+to the specified directory if it exists, and set
 .Ql Va .OBJDIR
-and set
+and
 .Ql Ev PWD
 to that directory before executing any targets.
 .
@@ -1003,7 +1089,7 @@ sets
 to the value of
 .Ql Ev PWD
 instead.
-This behaviour is disabled if
+This behavior is disabled if
 .Ql Ev MAKEOBJDIRPREFIX
 is set or
 .Ql Ev MAKEOBJDIR
@@ -1073,7 +1159,7 @@ The wildcard 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
 .Dl ${VAR:M*}
-will normalise the inter-word spacing, removing all leading and
+will normalize the inter-word spacing, removing all leading and
 trailing space, and converting multiple consecutive spaces
 to single spaces.
 .
@@ -1093,7 +1179,7 @@ Randomize words in variable.
 The results will be different each time you are referring to the
 modified variable; use the assignment with expansion
 .Pq Ql Cm \&:=
-to prevent such behaviour.
+to prevent such behavior.
 For example,
 .Bd -literal -offset indent
 LIST=                  uno due tre quattro
@@ -1125,7 +1211,7 @@ The value is a format string for
 using the current
 .Xr gmtime 3 .
 .It Cm \&:hash
-Compute a 32bit hash of the value and encode it as hex digits.
+Compute a 32-bit hash of the value and encode it as hex digits.
 .It Cm \&:localtime
 The value is a format string for
 .Xr strftime 3 ,
@@ -1403,7 +1489,7 @@ value is divided into words.
 .Pp
 Ordinarily, a value is treated as a sequence of words
 delimited by white space.
-Some modifiers suppress this behaviour,
+Some modifiers suppress this behavior,
 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,
@@ -1489,12 +1575,20 @@ For compatibility with other versions of
 .Nm
 .Ql include file ...
 is also accepted.
+.Pp
 If the include statement is written as
 .Cm .-include
 or as
 .Cm .sinclude
 then errors locating and/or opening include files are ignored.
 .Pp
+If the include statement is written as
+.Cm .dinclude
+not only are errors locating and/or opening include files ignored,
+but stale dependencies within the included file will be ignored
+just like
+.Va .MAKE.DEPENDFILE .
+.Pp
 Conditional expressions are also preceded by a single dot as the first
 character of a line.
 The possible conditionals are as follows:
@@ -1530,6 +1624,10 @@ This allows exporting a value to the environment which is different from that
 used by
 .Nm
 internally.
+.It Ic .export-literal Ar variable ...
+The same as
+.Ql .export-env ,
+except that variables in the value are not expanded.
 .It Ic .info Ar message
 The message is printed along with the name of the makefile and line number.
 .It Ic .undef Ar variable
@@ -1961,6 +2059,15 @@ Disable parallel mode.
 Synonym for
 .Ic .NOTPARALLEL ,
 for compatibility with other pmake variants.
+.It Ic .OBJDIR
+The source is a new value for
+.Ql Va .OBJDIR .
+If it exists,
+.Nm
+will
+.Xr chdir 2
+to it and update the value of
+.Ql Va .OBJDIR .
 .It Ic .ORDER
 The named targets are made in sequence.
 This ordering does not add targets to the list of targets to be made.
@@ -2018,7 +2125,7 @@ The sources are a set of
 pairs.
 .Bl -tag -width hasErrCtls
 .It Ar name
-This is the minimal specification, used to select one of the builtin
+This is the minimal specification, used to select one of the built-in
 shell specs;
 .Ar sh ,
 .Ar ksh ,
@@ -2119,19 +2226,87 @@ 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
-NetBSD 4.0
-so that .ORDER and .WAIT apply recursively to the dependent 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
 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
+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
+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
index 0ce26a5..5e5622c 100644 (file)
@@ -122,9 +122,6 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
              _\bv       Print debugging information about variable assignment.
 
-             _\bw       Print entering and leaving directory messages, pre and
-                     post processing.
-
              _\bx       Run shell commands with -\b-x\bx so the actual commands are
                      printed as they are executed.
 
@@ -181,11 +178,11 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
              then b\bbm\bma\bak\bke\be 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 -\b-m\bm argument.  If used, this feature allows b\bbm\bma\bak\bke\be to easily
-             search in the current source tree for customized sys.mk files
-             (e.g., by using ".../mk/sys.mk" as an argument).
+             towards the root of the file system.  If the search is success-
+             ful, then the resulting directory replaces the ".../" specifica-
+             tion in the -\b-m\bm argument.  If used, this feature allows b\bbm\bma\bak\bke\be to
+             easily search in the current source tree for customized sys.mk
+             files (e.g., by using ".../mk/sys.mk" as an argument).
 
      -\b-n\bn      Display the commands that would have been executed, but do not
              actually execute them unless the target depends on the .MAKE spe-
@@ -221,6 +218,9 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
      -\b-W\bW      Treat any warnings during makefile parsing as errors.
 
+     -\b-w\bw      Print entering and leaving directory messages, pre and post pro-
+             cessing.
+
      -\b-X\bX      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 _\bM_\bA_\bK_\bE_\bF_\bL_\bA_\bG_\bS environment variable.  This
@@ -273,46 +273,55 @@ F\bFI\bIL\bLE\bE D\bDE\bEP\bPE\bEN\bND\bDE\bEN\bNC\bCY\bY S\bSP\bPE\bEC\bCI\bIF\bFI\bIC\bCA\bAT\bTI\bIO\bO
      done in the shell.
 
 S\bSH\bHE\bEL\bLL\bL C\bCO\bOM\bMM\bMA\bAN\bND\bDS\bS
-     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
-     _\bm_\bu_\bs_\bt 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 `:\b::\b:' operator is used.
-
-     If the first characters of the command line are any combination of `@\b@',
-     `+\b+', or `-\b-', the command is treated specially.  A `@\b@' causes the command
-     not to be echoed before it is executed.  A `+\b+' causes the command to be
-     executed even when -\b-n\bn 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 `-\b-' 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 _\bm_\bu_\bs_\bt 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 `:\b::\b:' 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 `@\b@', `+\b+', or `-\b-', the command is treated specially.  A `@\b@' causes the
+     command not to be echoed before it is executed.  A `+\b+' causes the command
+     to be executed even when -\b-n\bn 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 `-\b-' in compatibility mode causes any non-zero
+     exit status of the command line to be ignored.
 
      When b\bbm\bma\bak\bke\be is run in jobs mode with -\b-j\bj _\bm_\ba_\bx_\b__\bj_\bo_\bb_\bs, 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
-     (`#=|^(){};&<>*?[]:$`\\n') it will be passed to the shell, otherwise
-     b\bbm\bma\bak\bke\be will attempt direct execution.
-
-     Since b\bbm\bma\bak\bke\be will chdir(2) to `_\b._\bO_\bB_\bJ_\bD_\bI_\bR' before executing any targets, each
-     child process starts with that as its current working directory.
+     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 b\bbm\bma\bak\bke\be will attempt direct execu-
+     tion.  If a line starts with `-\b-' and the shell has ErrCtl enabled then
+     failure of the command line will be ignored as in compatibility mode.
+     Otherwise `-\b-' 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 b\bbm\bma\bak\bke\be operation does not
      change their behavior.  For example, any command which needs to use
-     ``cd'' or ``chdir'', without side-effect should be put in parenthesis:
-
+     ``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} $@)
+                   @(cd ${.CURDIR} && ${MAKE} $@)
                    @echo Back in `pwd`
 
            ensure-one-shell-regardless-of-mode:
                    @echo Building $@ in `pwd`; \
-                   (cd ${.CURDIR} && ${.MAKE} $@); \
+                   (cd ${.CURDIR} && ${MAKE} $@); \
                    echo Back in `pwd`
 
+     Since b\bbm\bma\bak\bke\be will chdir(2) to `_\b._\bO_\bB_\bJ_\bD_\bI_\bR' before executing any targets, each
+     child process starts with that as its current working directory.
+
 V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
      Variables in make are much like variables in the shell, and, by tradi-
      tion, consist of all upper-case letters.
@@ -402,40 +411,49 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
              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.
 
-             _\b._\bA_\bL_\bL_\bS_\bR_\bC   The list of all sources for this target; also known as
-                       `_\b>'.
+     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:
 
-             _\b._\bA_\bR_\bC_\bH_\bI_\bV_\bE  The name of the archive file.
+           _\b._\bA_\bL_\bL_\bS_\bR_\bC   The list of all sources for this target; also known as
+                     `_\b>'.
 
-             _\b._\bI_\bM_\bP_\bS_\bR_\bC   In suffix-transformation rules, the name/path of the
-                       source from which the target is to be transformed (the
-                       ``implied'' source); also known as `_\b<'.  It is not
-                       defined in explicit rules.
+           _\b._\bA_\bR_\bC_\bH_\bI_\bV_\bE  The name of the archive file; also known as `_\b!'.
 
-             _\b._\bM_\bE_\bM_\bB_\bE_\bR   The name of the archive member.
+           _\b._\bI_\bM_\bP_\bS_\bR_\bC   In suffix-transformation rules, the name/path of the
+                     source from which the target is to be transformed (the
+                     ``implied'' source); also known as `_\b<'.  It is not
+                     defined in explicit rules.
 
-             _\b._\bO_\bO_\bD_\bA_\bT_\bE   The list of sources for this target that were deemed
-                       out-of-date; also known as `_\b?'.
+           _\b._\bM_\bE_\bM_\bB_\bE_\bR   The name of the archive member; also known as `_\b%'.
 
-             _\b._\bP_\bR_\bE_\bF_\bI_\bX   The file prefix of the target, containing only the file
-                       portion, no suffix or preceding directory components;
-                       also known as `_\b*'.
+           _\b._\bO_\bO_\bD_\bA_\bT_\bE   The list of sources for this target that were deemed out-
+                     of-date; also known as `_\b?'.
 
-             _\b._\bT_\bA_\bR_\bG_\bE_\bT   The name of the target; also known as `_\b@'.
+           _\b._\bP_\bR_\bE_\bF_\bI_\bX   The file prefix of the target, containing only the file
+                     portion, no suffix or preceding directory components;
+                     also known as `_\b*'.  The suffix must be one of the known
+                     suffixes declared with .\b.S\bSU\bUF\bFF\bFI\bIX\bXE\bES\bS or it will not be recog-
+                     nized.
 
-             The shorter forms `_\b@', `_\b?', `_\b<', `_\b>', and `_\b*' are permitted for
-             backward compatibility with historical makefiles and are not rec-
-             ommended.  The six variables `_\b@_\bF', `_\b@_\bD', `_\b<_\bF', `_\b<_\bD', `_\b*_\bF', and
-             `_\b*_\bD' are permitted for compatibility with AT&T System V UNIX
-             makefiles and are not recommended.
+           _\b._\bT_\bA_\bR_\bG_\bE_\bT   The name of the target; also known as `_\b@'.  For compati-
+                     bility with other makes this is an alias for .\b.A\bAR\bRC\bCH\bHI\bIV\bVE\bE in
+                     archive member rules.
 
-             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 `_\b._\bT_\bA_\bR_\bG_\bE_\bT', `_\b._\bP_\bR_\bE_\bF_\bI_\bX', `_\b._\bA_\bR_\bC_\bH_\bI_\bV_\bE',
-             and `_\b._\bM_\bE_\bM_\bB_\bE_\bR'.
+     The shorter forms (`_\b>', `_\b!', `_\b<', `_\b%', `_\b?', `_\b*', and `_\b@') are permitted
+     for backward compatibility with historical makefiles and legacy POSIX
+     make and are not recommended.
+
+     Variants of these variables with the punctuation followed immediately by
+     `D' or `F', e.g.  `_\b$_\b(_\b@_\bD_\b)', 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 `_\b._\bT_\bA_\bR_\bG_\bE_\bT', `_\b._\bP_\bR_\bE_\bF_\bI_\bX', `_\b._\bA_\bR_\bC_\bH_\bI_\bV_\bE', and `_\b._\bM_\bE_\bM_\bB_\bE_\bR'.
 
    A\bAd\bdd\bdi\bit\bti\bio\bon\bna\bal\bl b\bbu\bui\bil\blt\bt-\b-i\bin\bn v\bva\bar\bri\bia\bab\bbl\ble\bes\bs
      In addition, b\bbm\bma\bak\bke\be sets or knows about the following variables:
@@ -513,37 +531,51 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
                      mode that b\bbm\bma\bak\bke\be runs in.  It can contain a number of key-
                      words:
 
-                     _\bc_\bo_\bm_\bp_\ba_\bt      Like -\b-B\bB, puts b\bbm\bma\bak\bke\be into "compat" mode.
+                     _\bc_\bo_\bm_\bp_\ba_\bt               Like -\b-B\bB, puts b\bbm\bma\bak\bke\be into "compat"
+                                          mode.
+
+                     _\bm_\be_\bt_\ba                 Puts b\bbm\bma\bak\bke\be into "meta" mode, where
+                                          meta files are created for each tar-
+                                          get to capture the command run, the
+                                          output generated and if filemon(4)
+                                          is available, the system calls which
+                                          are of interest to b\bbm\bma\bak\bke\be.  The cap-
+                                          tured output can be very useful when
+                                          diagnosing errors.
+
+                     _\bc_\bu_\br_\bd_\bi_\br_\bO_\bk_\b= _\bb_\bf         Normally b\bbm\bma\bak\bke\be will not create .meta
+                                          files in `_\b._\bC_\bU_\bR_\bD_\bI_\bR'.  This can be
+                                          overridden by setting _\bb_\bf to a value
+                                          which represents True.
+
+                     _\bm_\bi_\bs_\bs_\bi_\bn_\bg_\b-_\bm_\be_\bt_\ba_\b= _\bb_\bf     If _\bb_\bf is True, then a missing .meta
+                                          file makes the target out-of-date.
 
-                     _\bm_\be_\bt_\ba        Puts b\bbm\bma\bak\bke\be 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 b\bbm\bma\bak\bke\be.  The captured
-                                 output can be very useful when diagnosing
-                                 errors.
+                     _\bm_\bi_\bs_\bs_\bi_\bn_\bg_\b-_\bf_\bi_\bl_\be_\bm_\bo_\bn_\b= _\bb_\bf  If _\bb_\bf is True, then missing filemon
+                                          data makes the target out-of-date.
 
-                     _\bc_\bu_\br_\bd_\bi_\br_\bO_\bk_\b= _\bb_\bf Normally b\bbm\bma\bak\bke\be will not create .meta files
-                                 in `_\b._\bC_\bU_\bR_\bD_\bI_\bR'.  This can be overridden by set-
-                                 ting _\bb_\bf to a value which represents True.
+                     _\bn_\bo_\bf_\bi_\bl_\be_\bm_\bo_\bn            Do not use filemon(4).
 
-                     _\be_\bn_\bv         For debugging, it can be useful to inlcude
-                                 the environment in the .meta file.
+                     _\be_\bn_\bv                  For debugging, it can be useful to
+                                          include the environment in the .meta
+                                          file.
 
-                     _\bv_\be_\br_\bb_\bo_\bs_\be     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:
-                                 _\b._\bM_\bA_\bK_\bE_\b._\bM_\bE_\bT_\bA_\b._\bP_\bR_\bE_\bF_\bI_\bX.
+                     _\bv_\be_\br_\bb_\bo_\bs_\be              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:
+                                          _\b._\bM_\bA_\bK_\bE_\b._\bM_\bE_\bT_\bA_\b._\bP_\bR_\bE_\bF_\bI_\bX.
 
-                     _\bi_\bg_\bn_\bo_\br_\be_\b-_\bc_\bm_\bd  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
-                                 .\b.N\bNO\bOM\bME\bET\bTA\bA_\b_C\bCM\bMP\bP.
+                     _\bi_\bg_\bn_\bo_\br_\be_\b-_\bc_\bm_\bd           Some makefiles have commands which
+                                          are simply not stable.  This keyword
+                                          causes them to be ignored for deter-
+                                          mining whether a target is out of
+                                          date in "meta" mode.  See also
+                                          .\b.N\bNO\bOM\bME\bET\bTA\bA_\b_C\bCM\bMP\bP.
 
-                     _\bs_\bi_\bl_\be_\bn_\bt_\b= _\bb_\bf  If _\bb_\bf is True, when a .meta file is created,
-                                 mark the target .\b.S\bSI\bIL\bLE\bEN\bNT\bT.
+                     _\bs_\bi_\bl_\be_\bn_\bt_\b= _\bb_\bf           If _\bb_\bf is True, when a .meta file is
+                                          created, mark the target .\b.S\bSI\bIL\bLE\bEN\bNT\bT.
 
      _\b._\bM_\bA_\bK_\bE_\b._\bM_\bE_\bT_\bA_\b._\bB_\bA_\bI_\bL_\bI_\bW_\bI_\bC_\bK
                      In "meta" mode, provides a list of prefixes which match
@@ -568,6 +600,14 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
                      The default list includes: `_\b/_\bd_\be_\bv _\b/_\be_\bt_\bc _\b/_\bp_\br_\bo_\bc _\b/_\bt_\bm_\bp _\b/_\bv_\ba_\br_\b/_\br_\bu_\bn
                      _\b/_\bv_\ba_\br_\b/_\bt_\bm_\bp'
 
+     _\b._\bM_\bA_\bK_\bE_\b._\bM_\bE_\bT_\bA_\b._\bI_\bG_\bN_\bO_\bR_\bE_\b__\bP_\bA_\bT_\bT_\bE_\bR_\bN_\bS
+                     Provides a list of patterns to match against pathnames.
+                     Ignore any that match.
+
+     _\b._\bM_\bA_\bK_\bE_\b._\bM_\bE_\bT_\bA_\b._\bI_\bG_\bN_\bO_\bR_\bE_\b__\bF_\bI_\bL_\bT_\bE_\bR
+                     Provides a list of variable modifiers to apply to each
+                     pathname.  Ignore if the expansion is an empty string.
+
      _\b._\bM_\bA_\bK_\bE_\b._\bM_\bE_\bT_\bA_\b._\bP_\bR_\bE_\bF_\bI_\bX
                      Defines the message printed for each meta file updated in
                      "meta verbose" mode.  The default value is:
@@ -575,7 +615,7 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
 
      _\b._\bM_\bA_\bK_\bE_\bO_\bV_\bE_\bR_\bR_\bI_\bD_\bE_\bS  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
+                     exported as part of `MAKEFLAGS'.  This behavior can be
                      disabled by assigning an empty value to `_\b._\bM_\bA_\bK_\bE_\bO_\bV_\bE_\bR_\bR_\bI_\bD_\bE_\bS'
                      within a makefile.  Extra variables can be exported from
                      a makefile by appending their names to `_\b._\bM_\bA_\bK_\bE_\bO_\bV_\bE_\bR_\bR_\bI_\bD_\bE_\bS'.
@@ -591,10 +631,22 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
 
      _\b._\bM_\bA_\bK_\bE_\b._\bP_\bP_\bI_\bD      The parent process-id of b\bbm\bma\bak\bke\be.
 
+     _\b._\bM_\bA_\bK_\bE_\b._\bS_\bA_\bV_\bE_\b__\bD_\bO_\bL_\bL_\bA_\bR_\bS
+                     value should be a boolean that controls whether `$$' are
+                     preserved when doing `:=' assignments.  The default is
+                     false, for backwards compatibility.  Set to true for com-
+                     patability with other makes.  If set to false, `$$'
+                     becomes `$' per normal evaluation rules.
+
      _\bM_\bA_\bK_\bE_\b__\bP_\bR_\bI_\bN_\bT_\b__\bV_\bA_\bR_\b__\bO_\bN_\b__\bE_\bR_\bR_\bO_\bR
-                     When b\bbm\bma\bak\bke\be stops due to an error, it prints its name and
-                     the value of `_\b._\bC_\bU_\bR_\bD_\bI_\bR' as well as the value of any vari-
-                     ables named in `_\bM_\bA_\bK_\bE_\b__\bP_\bR_\bI_\bN_\bT_\b__\bV_\bA_\bR_\b__\bO_\bN_\b__\bE_\bR_\bR_\bO_\bR'.
+                     When b\bbm\bma\bak\bke\be stops due to an error, it sets `_\b._\bE_\bR_\bR_\bO_\bR_\b__\bT_\bA_\bR_\bG_\bE_\bT'
+                     to the name of the target that failed, `_\b._\bE_\bR_\bR_\bO_\bR_\b__\bC_\bM_\bD' to
+                     the commands of the failed target, and in "meta" mode, it
+                     also sets `_\b._\bE_\bR_\bR_\bO_\bR_\b__\bC_\bW_\bD' to the getcwd(3), and
+                     `_\b._\bE_\bR_\bR_\bO_\bR_\b__\bM_\bE_\bT_\bA_\b__\bF_\bI_\bL_\bE' to the path of the meta file (if any)
+                     describing the failed target.  It then prints its name
+                     and the value of `_\b._\bC_\bU_\bR_\bD_\bI_\bR' as well as the value of any
+                     variables named in `_\bM_\bA_\bK_\bE_\b__\bP_\bR_\bI_\bN_\bT_\b__\bV_\bA_\bR_\b__\bO_\bN_\b__\bE_\bR_\bR_\bO_\bR'.
 
      _\b._\bn_\be_\bw_\bl_\bi_\bn_\be        This variable is simply assigned a newline character as
                      its value.  This allows expansions using the :\b:@\b@ modifier
@@ -631,10 +683,10 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
                      may be used.  This is especially useful with
                      `MAKEOBJDIR'.
 
-                     `_\b._\bO_\bB_\bJ_\bD_\bI_\bR' may be modified in the makefile as a global
-                     variable.  In all cases, b\bbm\bma\bak\bke\be will chdir(2) to `_\b._\bO_\bB_\bJ_\bD_\bI_\bR'
-                     and set `PWD' to that directory before executing any tar-
-                     gets.
+                     `_\b._\bO_\bB_\bJ_\bD_\bI_\bR' may be modified in the makefile via the special
+                     target `.\b.O\bOB\bBJ\bJD\bDI\bIR\bR'.  In all cases, b\bbm\bma\bak\bke\be will chdir(2) to
+                     the specified directory if it exists, and set `_\b._\bO_\bB_\bJ_\bD_\bI_\bR'
+                     and `PWD' to that directory before executing any targets.
 
      _\b._\bP_\bA_\bR_\bS_\bE_\bD_\bI_\bR       A path to the directory of the current `_\bM_\ba_\bk_\be_\bf_\bi_\bl_\be' being
                      parsed.
@@ -654,7 +706,7 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
                      sets `_\b._\bC_\bU_\bR_\bD_\bI_\bR' 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 b\bbm\bma\bak\bke\be sets
-                     `_\b._\bC_\bU_\bR_\bD_\bI_\bR' to the value of `PWD' instead.  This behaviour
+                     `_\b._\bC_\bU_\bR_\bD_\bI_\bR' to the value of `PWD' instead.  This behavior
                      is disabled if `MAKEOBJDIRPREFIX' is set or `MAKEOBJDIR'
                      contains a variable transform.  `PWD' is set to the value
                      of `_\b._\bO_\bB_\bJ_\bD_\bI_\bR' for all programs which b\bbm\bma\bak\bke\be executes.
@@ -701,7 +753,7 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
           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
+          will normalize the inter-word spacing, removing all leading and
           trailing space, and converting multiple consecutive spaces to single
           spaces.
 
@@ -714,7 +766,7 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
 
      :\b:O\bOx\bx  Randomize words in variable.  The results will be different each
           time you are referring to the modified variable; use the assignment
-          with expansion (`:\b:=\b=') to prevent such behaviour.  For example,
+          with expansion (`:\b:=\b=') to prevent such behavior.  For example,
 
                 LIST=                   uno due tre quattro
                 RANDOM_LIST=            ${LIST:Ox}
@@ -742,7 +794,7 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
           gmtime(3).
 
      :\b:h\bha\bas\bsh\bh
-          Compute a 32bit hash of the value and encode it as hex digits.
+          Compute a 32-bit hash of the value and encode it as hex digits.
 
      :\b:l\blo\boc\bca\bal\blt\bti\bim\bme\be
           The value is a format string for strftime(3), using the current
@@ -898,13 +950,13 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE A\bAS\bSS\bSI\bIG\bGN\bNM\bME\bEN\bNT\bTS\bS
           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
-          `:\b:[\b[]\b]' 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).
+          white space.  Some modifiers suppress this behavior, 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 `:\b:[\b[]\b]'
+          modifier, the words are indexed both forwards using positive inte-
+          gers (where index 1 represents the first word), and backwards using
+          negative integers (where index -1 represents the last word).
 
           The _\br_\ba_\bn_\bg_\be is subjected to variable expansion, and the expanded
           result is then interpreted as follows:
@@ -941,8 +993,14 @@ I\bIN\bNC\bCL\bLU\bUD\bDE\bE S\bST\bTA\bAT\bTE\bEM\bME\bEN\bNT\bTS\bS,\b, C\bCO\bON\bND\bDI\bIT\bTI\bIO\bO
      used, the including makefile's directory and any directories specified
      using the -\b-I\bI option are searched before the system makefile directory.
      For compatibility with other versions of b\bbm\bma\bak\bke\be `include file ...' is also
-     accepted.  If the include statement is written as .\b.-\b-i\bin\bnc\bcl\blu\bud\bde\be or as
-     .\b.s\bsi\bin\bnc\bcl\blu\bud\bde\be then errors locating and/or opening include files are ignored.
+     accepted.
+
+     If the include statement is written as .\b.-\b-i\bin\bnc\bcl\blu\bud\bde\be or as .\b.s\bsi\bin\bnc\bcl\blu\bud\bde\be then
+     errors locating and/or opening include files are ignored.
+
+     If the include statement is written as .\b.d\bdi\bin\bnc\bcl\blu\bud\bde\be not only are errors
+     locating and/or opening include files ignored, but stale dependencies
+     within the included file will be ignored just like _\b._\bM_\bA_\bK_\bE_\b._\bD_\bE_\bP_\bE_\bN_\bD_\bF_\bI_\bL_\bE.
 
      Conditional expressions are also preceded by a single dot as the first
      character of a line.  The possible conditionals are as follows:
@@ -966,6 +1024,10 @@ I\bIN\bNC\bCL\bLU\bUD\bDE\bE S\bST\bTA\bAT\bTE\bEM\bME\bEN\bNT\bTS\bS,\b, C\bCO\bON\bND\bDI\bIT\bTI\bIO\bO
              to _\b._\bM_\bA_\bK_\bE_\b._\bE_\bX_\bP_\bO_\bR_\bT_\bE_\bD.  This allows exporting a value to the environ-
              ment which is different from that used by b\bbm\bma\bak\bke\be internally.
 
+     .\b.e\bex\bxp\bpo\bor\brt\bt-\b-l\bli\bit\bte\ber\bra\bal\bl _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be _\b._\b._\b.
+             The same as `.export-env', except that variables in the value are
+             not expanded.
+
      .\b.i\bin\bnf\bfo\bo _\bm_\be_\bs_\bs_\ba_\bg_\be
              The message is printed along with the name of the makefile and
              line number.
@@ -1255,6 +1317,9 @@ S\bSP\bPE\bEC\bCI\bIA\bAL\bL T\bTA\bAR\bRG\bGE\bET\bTS\bS
               Synonym for .\b.N\bNO\bOT\bTP\bPA\bAR\bRA\bAL\bLL\bLE\bEL\bL, for compatibility with other pmake
               variants.
 
+     .\b.O\bOB\bBJ\bJD\bDI\bIR\bR  The source is a new value for `_\b._\bO_\bB_\bJ_\bD_\bI_\bR'.  If it exists, b\bbm\bma\bak\bke\be
+              will chdir(2) to it and update the value of `_\b._\bO_\bB_\bJ_\bD_\bI_\bR'.
+
      .\b.O\bOR\bRD\bDE\bER\bR   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
@@ -1288,7 +1353,7 @@ S\bSP\bPE\bEC\bCI\bIA\bAL\bL T\bTA\bAR\bRG\bGE\bET\bTS\bS
               sources are a set of _\bf_\bi_\be_\bl_\bd_\b=_\bv_\ba_\bl_\bu_\be pairs.
 
               _\bn_\ba_\bm_\be        This is the minimal specification, used to select
-                          one of the builtin shell specs; _\bs_\bh, _\bk_\bs_\bh, and _\bc_\bs_\bh.
+                          one of the built-in shell specs; _\bs_\bh, _\bk_\bs_\bh, and _\bc_\bs_\bh.
 
               _\bp_\ba_\bt_\bh        Specifies the path to the shell.
 
@@ -1356,19 +1421,58 @@ F\bFI\bIL\bLE\bES\bS
      /usr/share/mk  system makefile directory
 
 C\bCO\bOM\bMP\bPA\bAT\bTI\bIB\bBI\bIL\bLI\bIT\bTY\bY
-     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 dependent nodes.  The algo-
-     rithms used may change again in the future.
+   O\bOl\bld\bde\ber\br v\bve\ber\brs\bsi\bio\bon\bns\bs
+     An incomplete list of changes in older versions of b\bbm\bma\bak\bke\be:
 
      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.
 
+     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.
+
+   O\bOt\bth\bhe\ber\br m\bma\bak\bke\be d\bdi\bia\bal\ble\bec\bct\bts\bs
+     Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not sup-
+     port most of the features of b\bbm\bma\bak\bke\be as described in this manual.  Most
+     notably:
+
+           +\b+\bo\bo   The .\b.W\bWA\bAI\bIT\bT and .\b.O\bOR\bRD\bDE\bER\bR declarations and most functionality per-
+               taining to parallelization.  (GNU make supports parallelization
+               but lacks these features needed to control it effectively.)
+
+           +\b+\bo\bo   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.)
+
+           +\b+\bo\bo   All built-in variables that begin with a dot.
+
+           +\b+\bo\bo   Most of the special sources and targets that begin with a dot,
+               with the notable exception of .\b.P\bPH\bHO\bON\bNY\bY, .\b.P\bPR\bRE\bEC\bCI\bIO\bOU\bUS\bS, and .\b.S\bSU\bUF\bFF\bFI\bIX\bXE\bES\bS.
+
+           +\b+\bo\bo   Variable modifiers, except for the
+                     :old=new
+               string substitution, which does not portably support globbing
+               with `%' and historically only works on declared suffixes.
+
+           +\b+\bo\bo   The $\b$>\b> variable even in its short form; most makes support this
+               functionality but its name varies.
+
+     Some features are somewhat more portable, such as assignment with +\b+=\b=, ?\b?=\b=,
+     and !\b!=\b=.  The .\b.P\bPA\bAT\bTH\bH functionality is based on an older feature V\bVP\bPA\bAT\bTH\bH found
+     in GNU make and many versions of SVR4 make; however, historically its
+     behavior is too ill-defined (and too buggy) to rely upon.
+
+     The $\b$@\b@ and $\b$<\b< variables are more or less universally portable, as is the
+     $\b$(\b(M\bMA\bAK\bKE\bE)\b) 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.
+
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
      mkdep(1)
 
@@ -1394,4 +1498,4 @@ B\bBU\bUG\bGS\bS
 
      There is no way of escaping a space character in a filename.
 
-NetBSD 5.1                     February 14, 2014                    NetBSD 5.1
+NetBSD 5.1                      August 15, 2016                     NetBSD 5.1
index 340c46a..af128b4 100755 (executable)
 #      Simon J. Gerraty <sjg@crufty.net>
 
 # RCSid:
-#      $Id: boot-strap,v 1.45 2014/04/05 22:56:54 sjg Exp $
+#      $Id: boot-strap,v 1.49 2016/05/29 00:09:14 sjg Exp $
 #
 #      @(#) Copyright (c) 2001 Simon J. Gerraty
 #
@@ -395,8 +395,15 @@ Bmake() {
     )
 }
 
+# there is actually a shell where type is not a builtin
+# if type is missing, which(1) had better exists!
+if (type cat) > /dev/null 2>&1; then
+which() {
+        type "$@" | sed 's,[()],,g;s,^[^/][^/]*,,;q'
+}
+fi
 # make sure test below uses the same diff that configure did
-TOOL_DIFF=`type diff | sed 's,[()],,g;s,^[^/][^/]*,,;q'`
+TOOL_DIFF=`which diff`
 export TOOL_DIFF
 
 op_configure() {
@@ -444,7 +451,7 @@ op_all() {
                op_install
        else
                op_test
-               MAKE_VERSION=`sed -n '/^MAKE_VERSION/ { s,.*=  *,,;p; }' $srcdir/Makefile`
+               MAKE_VERSION=`sed -n '/^_MAKE_VERSION/ { s,.*=  *,,;p; }' $srcdir/Makefile`
                echo You can install by running:
                echo
                echo $0 $cmd_args op=install
index fd00eb7..87e1261 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $        */
+/*     $NetBSD: compat.c,v 1.105 2016/05/12 20:28:34 sjg Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.105 2016/05/12 20:28:34 sjg 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.96 2014/09/07 20:55:34 joerg Exp $");
+__RCSID("$NetBSD: compat.c,v 1.105 2016/05/12 20:28:34 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -111,37 +111,14 @@ __RCSID("$NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $");
 #include    "hash.h"
 #include    "dir.h"
 #include    "job.h"
+#include    "metachar.h"
 #include    "pathnames.h"
 
-/*
- * The following array is used to make a fast determination of which
- * characters are interpreted specially by the shell.  If a command
- * contains any of these characters, it is executed by the shell, not
- * directly by us.
- */
-
-static char        meta[256];
 
 static GNode       *curTarg = NULL;
 static GNode       *ENDNode;
 static void CompatInterrupt(int);
 
-static void
-Compat_Init(void)
-{
-    const char *cp;
-
-    Shell_Init();              /* setup default shell */
-    
-    for (cp = "~#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
-       meta[(unsigned char) *cp] = 1;
-    }
-    /*
-     * The null character serves as a sentinel in the string.
-     */
-    meta[0] = 1;
-}
-
 /*-
  *-----------------------------------------------------------------------
  * CompatInterrupt --
@@ -169,8 +146,8 @@ CompatInterrupt(int signo)
        if (!noExecute && eunlink(file) != -1) {
            Error("*** %s removed", file);
        }
-       if (p1)
-           free(p1);
+
+       free(p1);
 
        /*
         * Run .INTERRUPT only if hit with interrupt signal
@@ -236,7 +213,7 @@ CompatRunCommand(void *cmdp, void *gnp)
     doIt = FALSE;
     
     cmdNode = Lst_Member(gn->commands, cmd);
-    cmdStart = Var_Subst(NULL, cmd, gn, FALSE);
+    cmdStart = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
 
     /*
      * brk_string will return an argv with a NULL in av[0], thus causing
@@ -271,8 +248,8 @@ CompatRunCommand(void *cmdp, void *gnp)
            break;
        case '+':
            doIt = TRUE;
-           if (!meta[0])               /* we came here from jobs */
-               Compat_Init();
+           if (!shellName)             /* we came here from jobs */
+               Shell_Init();
            break;
        }
        cmd++;
@@ -300,11 +277,13 @@ CompatRunCommand(void *cmdp, void *gnp)
      * Search for meta characters in the command. If there are no meta
      * characters, there's no need to execute a shell to execute the
      * command.
+     *
+     * Additionally variable assignments and empty commands
+     * go to the shell. Therefore treat '=' and ':' like shell
+     * meta characters as documented in make(1).
      */
-    for (cp = cmd; !meta[(unsigned char)*cp]; cp++) {
-       continue;
-    }
-    useShell = (*cp != '\0');
+    
+    useShell = needshell(cmd, FALSE);
 #endif
 
     /*
@@ -395,10 +374,10 @@ again:
        execError("exec", av[0]);
        _exit(1);
     }
-    if (mav)
-       free(mav);
-    if (bp)
-       free(bp);
+
+    free(mav);
+    free(bp);
+
     Lst_Replace(cmdNode, NULL);
 
 #ifdef USE_META
@@ -512,8 +491,8 @@ Compat_Make(void *gnp, void *pgnp)
     GNode *gn = (GNode *)gnp;
     GNode *pgn = (GNode *)pgnp;
 
-    if (!meta[0])              /* we came here from jobs */
-       Compat_Init();
+    if (!shellName)            /* we came here from jobs */
+       Shell_Init();
     if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
        /*
         * First mark ourselves to be made, then apply whatever transformations
@@ -537,8 +516,7 @@ Compat_Make(void *gnp, void *pgnp)
        if (Lst_Member(gn->iParents, pgn) != NULL) {
            char *p1;
            Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
-           if (p1)
-               free(p1);
+           free(p1);
        }
 
        /*
@@ -608,7 +586,8 @@ Compat_Make(void *gnp, void *pgnp)
        }
 #ifdef USE_META
        if (useMeta && !NoExecute(gn)) {
-           meta_job_finish(NULL);
+           if (meta_job_finish(NULL) != 0)
+               gn->made = ERROR;
        }
 #endif
 
@@ -641,8 +620,7 @@ Compat_Make(void *gnp, void *pgnp)
        if (Lst_Member(gn->iParents, pgn) != NULL) {
            char *p1;
            Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
-           if (p1)
-               free(p1);
+           free(p1);
        }
        switch(gn->made) {
            case BEINGMADE:
@@ -693,7 +671,8 @@ Compat_Run(Lst targs)
     GNode        *gn = NULL;/* Current root target */
     int                  errors;   /* Number of targets not remade due to errors */
 
-    Compat_Init();
+    if (!shellName)
+       Shell_Init();
 
     if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) {
        bmake_signal(SIGINT, CompatInterrupt);
index a1c6705..cf0107b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 christos Exp $       */
+/*     $NetBSD: cond.c,v 1.74 2016/02/18 18:29:14 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 christos Exp $";
+static char rcsid[] = "$NetBSD: cond.c,v 1.74 2016/02/18 18:29:14 christos 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.67 2012/11/03 13:59:27 christos Exp $");
+__RCSID("$NetBSD: cond.c,v 1.74 2016/02/18 18:29:14 christos 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)
 {
@@ -280,10 +289,10 @@ CondGetArg(char **linePtr, char **argPtr, const char *func)
            int         len;
            void        *freeIt;
 
-           cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &freeIt);
+           cp2 = Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES,
+                           &len, &freeIt);
            Buf_AddBytes(&buf, strlen(cp2), cp2);
-           if (freeIt)
-               free(freeIt);
+           free(freeIt);
            cp += len;
            continue;
        }
@@ -337,8 +346,8 @@ CondDoDefined(int argLen MAKE_ATTR_UNUSED, const char *arg)
     } else {
        result = FALSE;
     }
-    if (p1)
-       free(p1);
+
+    free(p1);
     return (result);
 }
 \f
@@ -481,6 +490,10 @@ CondCvtArg(char *str, double *value)
     double d_val;
 
     errno = 0;
+    if (!*str) {
+       *value = (double)0;
+       return TRUE;
+    }
     l_val = strtoul(str, &eptr, str[1] == 'x' ? 16 : 10);
     ech = *eptr;
     if (ech == 0 && errno != ERANGE) {
@@ -517,7 +530,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;
@@ -561,8 +574,9 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt)
            break;
        case '$':
            /* if we are in quotes, then an undefined variable is ok */
-           str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval),
-                           &len, freeIt);
+           str = Var_Parse(condExpr, VAR_CMD,
+                           ((!qt && doEval) ? VARF_UNDEFERR : 0) |
+                           VARF_WANTRES, &len, freeIt);
            if (str == var_Error) {
                if (*freeIt) {
                    free(*freeIt);
@@ -601,6 +615,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 +672,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 +733,7 @@ compare_expression(Boolean doEval)
        goto done;
     }
 
-    rhs = CondGetString(doEval, &rhsQuoted, &rhsFree);
+    rhs = CondGetString(doEval, &rhsQuoted, &rhsFree, FALSE);
     if (!rhs)
        goto done;
 
@@ -782,10 +806,8 @@ do_string_compare:
     }
 
 done:
-    if (lhsFree)
-       free(lhsFree);
-    if (rhsFree)
-       free(rhsFree);
+    free(lhsFree);
+    free(rhsFree);
     return t;
 }
 
@@ -804,7 +826,7 @@ get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED)
     /* We do all the work here and return the result as the length */
     *argPtr = NULL;
 
-    val = Var_Parse(cp - 1, VAR_CMD, FALSE, &length, &freeIt);
+    val = Var_Parse(cp - 1, VAR_CMD, VARF_WANTRES, &length, &freeIt);
     /*
      * Advance *linePtr to beyond the closing ). Note that
      * we subtract one because 'length' is calculated from 'cp - 1'.
@@ -825,8 +847,7 @@ get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED)
      * true/false here.
      */
     length = *val ? 2 : 1;
-    if (freeIt)
-       free(freeIt);
+    free(freeIt);
     return length;
 }
 
@@ -877,8 +898,7 @@ compare_function(Boolean doEval)
        }
        /* Evaluate the argument using the required function. */
        t = !doEval || fn_def->fn_proc(arglen, arg);
-       if (arg)
-           free(arg);
+       free(arg);
        condExpr = cp;
        return t;
     }
@@ -910,8 +930,7 @@ compare_function(Boolean doEval)
      * be empty - even if it contained a variable expansion.
      */
     t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot;
-    if (arg)
-       free(arg);
+    free(arg);
     return t;
 }
 
@@ -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++;
 
@@ -1359,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;
index ce30da1..82e7e99 100644 (file)
 /* Define to 1 if you have the `killpg' function. */
 #undef HAVE_KILLPG
 
+/* Define to 1 if you have the <libgen.h> header file. */
+#undef HAVE_LIBGEN_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
    */
 #undef HAVE_SYS_NDIR_H
 
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
 /* Define to 1 if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
 /* Define to 1 if you need to in order for `stat' and other things to work. */
 #undef _POSIX_SOURCE
 
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT32_T
+
 /* C99 function name */
 #undef __func__
 
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
 /* Define to `long int' if <sys/types.h> does not define. */
 #undef off_t
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
 
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
 /* Define as `fork' if `vfork' does not work. */
 #undef vfork
index 08b21b3..1a70f3d 100755 (executable)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for bmake 20140214.
+# Generated by GNU Autoconf 2.64 for bmake 20160606.
 #
 # Report bugs to <sjg@NetBSD.org>.
 #
@@ -549,8 +549,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='bmake'
 PACKAGE_TARNAME='bmake'
-PACKAGE_VERSION='20140214'
-PACKAGE_STRING='bmake 20140214'
+PACKAGE_VERSION='20160606'
+PACKAGE_STRING='bmake 20160606'
 PACKAGE_BUGREPORT='sjg@NetBSD.org'
 PACKAGE_URL=''
 
@@ -1221,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 20140214 to adapt to many kinds of systems.
+\`configure' configures bmake 20160606 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1282,7 +1282,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of bmake 20140214:";;
+     short | recursive ) echo "Configuration of bmake 20160606:";;
    esac
   cat <<\_ACEOF
 
@@ -1387,7 +1387,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-bmake configure 20140214
+bmake configure 20160606
 generated by GNU Autoconf 2.64
 
 Copyright (C) 2009 Free Software Foundation, Inc.
@@ -1742,6 +1742,58 @@ $as_echo "$ac_res" >&6; }
 
 } # ac_fn_c_check_type
 
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+     for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+        'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) -1 >> ($2 - 1) == 1)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  case $ac_type in #(
+  uint$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       eval as_val=\$$3
+   if test "x$as_val" = x""no; then :
+
+else
+  break
+fi
+     done
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_find_uintX_t
+
 # ac_fn_c_check_decl LINENO SYMBOL VAR
 # ------------------------------------
 # Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
@@ -1908,7 +1960,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 20140214, which was
+It was created by bmake $as_me 20160606, which was
 generated by GNU Autoconf 2.64.  Invocation command line was
 
   $ $0 $@
@@ -4569,10 +4621,41 @@ fi
 
 fi
 
+for ac_header in sys/param.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_PARAM_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in sys/sysctl.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "sys/sysctl.h" "ac_cv_header_sys_sysctl_h" "#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# endif
+
+"
+if test "x$ac_cv_header_sys_sysctl_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SYSCTL_H 1
+_ACEOF
+
+fi
+
+done
+
+
 for ac_header in \
        ar.h \
        err.h \
        fcntl.h \
+       libgen.h \
+       limits.h \
        paths.h \
        poll.h \
        ranlib.h \
@@ -4580,7 +4663,6 @@ for ac_header in \
        sys/mman.h \
        sys/select.h \
        sys/socket.h \
-       sys/sysctl.h \
        sys/time.h \
        sys/uio.h \
        unistd.h \
@@ -4973,6 +5055,17 @@ $as_echo "#define const /**/" >>confdefs.h
 
 fi
 
+ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
+if test "x$ac_cv_type_mode_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
 ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
 if test "x$ac_cv_type_off_t" = x""yes; then :
 
@@ -5006,6 +5099,20 @@ _ACEOF
 
 fi
 
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+  no|yes) ;; #(
+  *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+  esac
+
 ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h>
 /* NetBSD declares sys_siglist in unistd.h.  */
 #ifdef HAVE_UNISTD_H
@@ -6406,7 +6513,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 20140214, which was
+This file was extended by bmake $as_me 20160606, which was
 generated by GNU Autoconf 2.64.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6466,7 +6573,7 @@ Report bugs to <sjg@NetBSD.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-bmake config.status 20140214
+bmake config.status 20160606
 configured by $0, generated by GNU Autoconf 2.64,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index e2249b0..29d368b 100644 (file)
@@ -1,11 +1,11 @@
 dnl
 dnl RCSid:
-dnl    $Id: configure.in,v 1.53 2014/11/06 01:49:40 sjg Exp $
+dnl    $Id: configure.in,v 1.57 2016/06/07 00:49:44 sjg Exp $
 dnl
 dnl Process this file with autoconf to produce a configure script
 dnl
 AC_PREREQ(2.50)
-AC_INIT([bmake], [20140214], [sjg@NetBSD.org])
+AC_INIT([bmake], [20160606], [sjg@NetBSD.org])
 AC_CONFIG_HEADERS(config.h)
 
 dnl make srcdir absolute
@@ -101,10 +101,20 @@ AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
 AC_HEADER_DIRENT
 dnl Keep this list sorted
+AC_CHECK_HEADERS(sys/param.h)
+dnl On BSDi at least we really need sys/param.h for sys/sysctl.h
+AC_CHECK_HEADERS([sys/sysctl.h], [], [],
+[#ifdef HAVE_SYS_PARAM_H
+# include <sys/param.h>
+# endif
+])
+
 AC_CHECK_HEADERS( \
        ar.h \
        err.h \
        fcntl.h \
+       libgen.h \
+       limits.h \
        paths.h \
        poll.h \
        ranlib.h \
@@ -112,7 +122,6 @@ AC_CHECK_HEADERS( \
        sys/mman.h \
        sys/select.h \
        sys/socket.h \
-       sys/sysctl.h \
        sys/time.h \
        sys/uio.h \
        unistd.h \
@@ -139,9 +148,11 @@ dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C___ATTRIBUTE__
 AC_C_BIGENDIAN
 AC_C_CONST
+AC_TYPE_MODE_T
 AC_TYPE_OFF_T
 AC_TYPE_PID_T
 AC_TYPE_SIZE_T
+AC_TYPE_UINT32_T
 AC_DECL_SYS_SIGLIST
 AC_HEADER_TIME
 AC_STRUCT_TM
index 7b12769..4667e3c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $        */
+/*     $NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $     */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $";
+static char rcsid[] = "$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg 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.67 2013/03/05 22:01:43 christos Exp $");
+__RCSID("$NetBSD: dir.c,v 1.68 2016/06/07 00:40:00 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -244,6 +244,7 @@ static Hash_Table mtimes;   /* Results of doing a last-resort stat in
                             * be two rules to update a single file, so this
                             * should be ok, but... */
 
+static Hash_Table lmtimes;  /* same as mtimes but for lstat */
 
 static int DirFindName(const void *, const void *);
 static int DirMatchFiles(const char *, Path *, Lst);
@@ -256,6 +257,80 @@ static char *DirLookupSubdir(Path *, const char *);
 static char *DirFindDot(Boolean, const char *, const char *);
 static char *DirLookupAbs(Path *, const char *, const char *);
 
+
+/*
+ * We use stat(2) a lot, cache the results
+ * mtime and mode are all we care about.
+ */
+struct cache_st {
+    time_t mtime;
+    mode_t  mode;
+};
+
+/* minimize changes below */
+static time_t
+Hash_GetTimeValue(Hash_Entry *entry)
+{
+    struct cache_st *cst;
+
+    cst = entry->clientPtr;
+    return cst->mtime;
+}
+
+#define CST_LSTAT 1
+#define CST_UPDATE 2
+
+static int
+cached_stats(Hash_Table *htp, const char *pathname, struct stat *st, int flags)
+{
+    Hash_Entry *entry;
+    struct cache_st *cst;
+    int rc;
+
+    if (!pathname || !pathname[0])
+       return -1;
+
+    entry = Hash_FindEntry(htp, pathname);
+
+    if (entry && (flags & CST_UPDATE) == 0) {
+       cst = entry->clientPtr;
+
+       memset(st, 0, sizeof(*st));
+       st->st_mtime = cst->mtime;
+       st->st_mode = cst->mode;
+       return 0;
+    }
+
+    rc = (flags & CST_LSTAT) ? lstat(pathname, st) : stat(pathname, st);
+    if (rc == -1)
+       return -1;
+
+    if (st->st_mtime == 0)
+       st->st_mtime = 1;      /* avoid confusion with missing file */
+
+    if (!entry)
+       entry = Hash_CreateEntry(htp, pathname, NULL);
+    if (!entry->clientPtr)
+       entry->clientPtr = bmake_malloc(sizeof(*cst));
+    cst = entry->clientPtr;
+    cst->mtime = st->st_mtime;
+    cst->mode = st->st_mode;
+
+    return 0;
+}
+
+int
+cached_stat(const char *pathname, void *st)
+{
+    return cached_stats(&mtimes, pathname, st, 0);
+}
+
+int
+cached_lstat(const char *pathname, void *st)
+{
+    return cached_stats(&lmtimes, pathname, st, CST_LSTAT);
+}
+
 /*-
  *-----------------------------------------------------------------------
  * Dir_Init --
@@ -274,6 +349,7 @@ Dir_Init(const char *cdname)
     dirSearchPath = Lst_Init(FALSE);
     openDirectories = Lst_Init(FALSE);
     Hash_InitTable(&mtimes, 0);
+    Hash_InitTable(&lmtimes, 0);
 
     Dir_InitCur(cdname);
 
@@ -901,7 +977,6 @@ static char *
 DirLookupSubdir(Path *p, const char *name)
 {
     struct stat          stb;          /* Buffer for stat, if necessary */
-    Hash_Entry  *entry;        /* Entry for mtimes table */
     char        *file;         /* the current filename to check */
 
     if (p != dot) {
@@ -917,9 +992,7 @@ DirLookupSubdir(Path *p, const char *name)
        fprintf(debug_file, "checking %s ...\n", file);
     }
 
-    if (stat(file, &stb) == 0) {
-       if (stb.st_mtime == 0)
-               stb.st_mtime = 1;
+    if (cached_stat(file, &stb) == 0) {
        /*
         * Save the modification time so if it's needed, we don't have
         * to fetch it again.
@@ -928,8 +1001,6 @@ DirLookupSubdir(Path *p, const char *name)
            fprintf(debug_file, "   Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                    file);
        }
-       entry = Hash_CreateEntry(&mtimes, file, NULL);
-       Hash_SetTimeValue(entry, stb.st_mtime);
        nearmisses += 1;
        return (file);
     }
@@ -1312,15 +1383,11 @@ Dir_FindFile(const char *name, Lst path)
            fprintf(debug_file, "   got it (in mtime cache)\n");
        }
        return(bmake_strdup(name));
-    } else if (stat(name, &stb) == 0) {
-       if (stb.st_mtime == 0)
-               stb.st_mtime = 1;
-       entry = Hash_CreateEntry(&mtimes, name, NULL);
+    } else if (cached_stat(name, &stb) == 0) {
        if (DEBUG(DIR)) {
            fprintf(debug_file, "   Caching %s for %s\n", Targ_FmtTime(stb.st_mtime),
                    name);
        }
-       Hash_SetTimeValue(entry, stb.st_mtime);
        return (bmake_strdup(name));
     } else {
        if (DEBUG(DIR)) {
@@ -1368,7 +1435,7 @@ Dir_FindHereOrAbove(char *here, char *search_path, char *result, int rlen) {
 
                /* try and stat(2) it ... */
                snprintf(try, sizeof(try), "%s/%s", dirbase, search_path);
-               if (stat(try, &st) != -1) {
+               if (cached_stat(try, &st) != -1) {
                        /*
                         * success!  if we found a file, chop off
                         * the filename so we return a directory.
@@ -1489,12 +1556,12 @@ Dir_MTime(GNode *gn, Boolean recheck)
     else
        entry = NULL;
     if (entry != NULL) {
+       stb.st_mtime = Hash_GetTimeValue(entry);
        if (DEBUG(DIR)) {
            fprintf(debug_file, "Using cached time %s for %s\n",
-                   Targ_FmtTime(Hash_GetTimeValue(entry)), fullName);
+                   Targ_FmtTime(stb.st_mtime), fullName);
        }
-       stb.st_mtime = Hash_GetTimeValue(entry);
-    } else if (stat(fullName, &stb) < 0) {
+    } else if (cached_stats(&mtimes, fullName, &stb, recheck ? CST_UPDATE : 0) < 0) {
        if (gn->type & OP_MEMBER) {
            if (fullName != gn->path)
                free(fullName);
@@ -1502,18 +1569,8 @@ Dir_MTime(GNode *gn, Boolean recheck)
        } 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;
-       }
-       entry = Hash_CreateEntry(&mtimes, fullName, NULL);
-       Hash_SetTimeValue(entry, stb.st_mtime);
     }
-       
+
     if (fullName && gn->path == NULL) {
        gn->path = fullName;
     }
index 8b6b6c3..154593b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $     */
+/*     $NetBSD: dirname.c,v 1.13 2014/07/16 10:52:26 christos Exp $    */
 
 /*-
  * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
 #ifndef HAVE_DIRNAME
 
 #include <sys/cdefs.h>
-
+#include <sys/param.h>
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
 #ifndef PATH_MAX
 # define PATH_MAX 1024
 #endif
+#ifndef MIN
+# define MIN(a, b) ((a < b) ? a : b)
+#endif
 
-char *
-dirname(char *path)
+
+static size_t
+xdirname_r(const char *path, char *buf, size_t buflen)
 {
-       static char result[PATH_MAX];
-       const char *lastp;
+       const char *endp;
        size_t len;
 
        /*
         * If `path' is a null pointer or points to an empty string,
         * return a pointer to the string ".".
         */
-       if ((path == NULL) || (*path == '\0'))
-               goto singledot;
-
+       if (path == NULL || *path == '\0') {
+               path = ".";
+               len = 1;
+               goto out;
+       }
 
        /* Strip trailing slashes, if any. */
-       lastp = path + strlen(path) - 1;
-       while (lastp != path && *lastp == '/')
-               lastp--;
+       endp = path + strlen(path) - 1;
+       while (endp != path && *endp == '/')
+               endp--;
 
-       /* Terminate path at the last occurence of '/'. */
-       do {
-               if (*lastp == '/') {
-                       /* Strip trailing slashes, if any. */
-                       while (lastp != path && *lastp == '/')
-                               lastp--;
+       /* Find the start of the dir */
+       while (endp > path && *endp != '/')
+               endp--;
 
-                       /* ...and copy the result into the result buffer. */
-                       len = (lastp - path) + 1 /* last char */;
-                       if (len > (PATH_MAX - 1))
-                               len = PATH_MAX - 1;
+       if (endp == path) {
+               path = *endp == '/' ? "/" : ".";
+               len = 1;
+               goto out;
+       }
 
-                       memcpy(result, path, len);
-                       result[len] = '\0';
+       do
+               endp--;
+       while (endp > path && *endp == '/');
 
-                       return (result);
-               }
-       } while (--lastp >= path);
+       len = endp - path + 1;
+out:
+       if (buf != NULL && buflen != 0) {
+               buflen = MIN(len, buflen - 1);
+               memcpy(buf, path, buflen);
+               buf[buflen] = '\0';
+       }
+       return len;
+}
 
-       /* No /'s found, return a pointer to the string ".". */
-singledot:
-       result[0] = '.';
-       result[1] = '\0';
+char *
+dirname(char *path)
+{
+       static char result[PATH_MAX];
+       (void)xdirname_r(path, result, sizeof(result));
+       return result;
+}
+
+#ifdef MAIN
+#include <stdlib.h>
+#include <stdio.h>
 
-       return (result);
+int
+main(int argc, char *argv[])
+{
+       printf("%s\n", dirname(argv[1]));
+       exit(0);
 }
 #endif
+#endif
index 33bcf13..ec00a45 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $     */
+/*     $NetBSD: for.c,v 1.52 2016/02/18 18:29:14 christos Exp $        */
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.52 2016/02/18 18:29:14 christos 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.49 2012/06/03 04:29:40 sjg Exp $");
+__RCSID("$NetBSD: for.c,v 1.52 2016/02/18 18:29:14 christos Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -216,7 +216,7 @@ For_Eval(char *line)
      * We can't do the escapes here - because we don't know whether
      * we are substuting into ${...} or $(...).
      */
-    sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
+    sub = Var_Subst(NULL, ptr, VAR_GLOBAL, VARF_WANTRES);
 
     /*
      * Split into words allowing for quoted strings.
index c40bc13..da29dae 100644 (file)
@@ -1,3 +1,5 @@
+/*     $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $     */
+
 /*
  * Copyright (c) 1987, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
 # include "config.h"
 #endif
 #if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT)
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/* static char sccsid[] = "from: @(#)getopt.c  8.2 (Berkeley) 4/2/94"; */
-static char *rcsid = "$Id: getopt.c,v 1.3 1999/01/08 02:14:18 sjg Exp $";
-#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -61,13 +55,10 @@ char        *optarg;                /* argument associated with option */
  *     Parse argc/argv argument vector.
  */
 int
-getopt(nargc, nargv, ostr)
-       int nargc;
-       char * const *nargv;
-       const char *ostr;
+getopt(int nargc, char * const nargv[], const char *ostr)
 {
        extern char *__progname;
-       static char *place = EMSG;              /* option letter processing */
+       static const char *place = EMSG;        /* option letter processing */
        char *oli;                              /* option letter list index */
 
 #ifndef BSD4_4
@@ -79,43 +70,63 @@ getopt(nargc, nargv, ostr)
        }
 #endif
        
-       if (optreset || !*place) {              /* update scanning pointer */
+       if (optreset || *place == 0) {          /* update scanning pointer */
                optreset = 0;
-               if (optind >= nargc || *(place = nargv[optind]) != '-') {
+               place = nargv[optind];
+               if (optind >= nargc || *place++ != '-') {
+                       /* Argument is absent or is not an option */
                        place = EMSG;
                        return (-1);
                }
-               if (place[1] && *++place == '-' /* found "--" */
-                   && !place[1]) {             /* and not "--foo" */
+               optopt = *place++;
+               if (optopt == '-' && *place == 0) {
+                       /* "--" => end of options */
                        ++optind;
                        place = EMSG;
                        return (-1);
                }
-       }                                       /* option letter okay? */
-       if ((optopt = (int)*place++) == (int)':' ||
-           !(oli = strchr(ostr, optopt))) {
-               /*
-                * if the user didn't specify '-' as an option,
-                * assume it means -1.
-                */
-               if (optopt == (int)'-')
-                       return (-1);
-               if (!*place)
+               if (optopt == 0) {
+                       /* Solitary '-', treat as a '-' option
+                          if the program (eg su) is looking for it. */
+                       place = EMSG;
+                       if (strchr(ostr, '-') == NULL)
+                               return -1;
+                       optopt = '-';
+               }
+       } else
+               optopt = *place++;
+
+       /* See if option letter is one the caller wanted... */
+       if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
+               if (*place == 0)
                        ++optind;
                if (opterr && *ostr != ':')
                        (void)fprintf(stderr,
-                           "%s: illegal option -- %c\n", __progname, optopt);
+                           "%s: unknown option -- %c\n", __progname, optopt);
                return (BADCH);
        }
-       if (*++oli != ':') {                    /* don't need argument */
+
+       /* Does this option need an argument? */
+       if (oli[1] != ':') {
+               /* don't need argument */
                optarg = NULL;
-               if (!*place)
+               if (*place == 0)
                        ++optind;
-       }
-       else {                                  /* need an argument */
-               if (*place)                     /* no white space */
-                       optarg = place;
-               else if (nargc <= ++optind) {   /* no arg */
+       } else {
+               /* Option-argument is either the rest of this argument or the
+                  entire next argument. */
+               if (*place)
+                       optarg = __UNCONST(place);
+               else if (oli[2] == ':')
+                       /*
+                        * GNU Extension, for optional arguments if the rest of
+                        * the argument is empty, we return NULL
+                        */
+                       optarg = NULL;
+               else if (nargc > ++optind)
+                       optarg = nargv[optind];
+               else {
+                       /* option-argument absent */
                        place = EMSG;
                        if (*ostr == ':')
                                return (BADARG);
@@ -125,12 +136,10 @@ getopt(nargc, nargv, ostr)
                                    __progname, optopt);
                        return (BADCH);
                }
-               else                            /* white space */
-                       optarg = nargv[optind];
                place = EMSG;
                ++optind;
        }
-       return (optopt);                        /* dump back option letter */
+       return (optopt);                        /* return option letter */
 }
 #endif
 #ifdef MAIN
index 31d2ff1..0e3d22d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $    */
+/*     $NetBSD: hash.h,v 1.11 2016/06/07 00:40:00 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -89,10 +89,7 @@ typedef struct Hash_Entry {
     struct Hash_Entry *next;           /* Used to link together all the
                                         * entries associated with the same
                                         * bucket. */
-    union {
-       void          *clientPtr;       /* Arbitrary pointer */
-       time_t        clientTime;       /* Arbitrary Time */
-    } clientInfo;
+    void             *clientPtr;       /* Arbitrary pointer */
     unsigned         namehash;         /* hash value of key */
     char             name[1];          /* key string */
 } Hash_Entry;
@@ -125,8 +122,7 @@ typedef struct Hash_Search {
  *     Hash_Entry *h;
  */
 
-#define Hash_GetValue(h) ((h)->clientInfo.clientPtr)
-#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime)
+#define Hash_GetValue(h) ((h)->clientPtr)
 
 /*
  * Hash_SetValue(h, val);
@@ -134,8 +130,7 @@ typedef struct Hash_Search {
  *     char *val;
  */
 
-#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val))
-#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val))
+#define Hash_SetValue(h, val) ((h)->clientPtr = (val))
 
 /*
  * Hash_Size(n) returns the number of words in an object of n bytes
index 95326eb..999c370 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: job.c,v 1.177 2014/07/16 15:33:41 christos Exp $       */
+/*     $NetBSD: job.c,v 1.187 2016/05/12 20:28:34 sjg Exp $    */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: job.c,v 1.177 2014/07/16 15:33:41 christos Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.187 2016/05/12 20:28:34 sjg 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.177 2014/07/16 15:33:41 christos Exp $");
+__RCSID("$NetBSD: job.c,v 1.187 2016/05/12 20:28:34 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -144,7 +144,6 @@ __RCSID("$NetBSD: job.c,v 1.177 2014/07/16 15:33:41 christos Exp $");
 
 #include <assert.h>
 #include <errno.h>
-#include <fcntl.h>
 #if !defined(USE_SELECT) && defined(HAVE_POLL_H)
 #include <poll.h>
 #else
@@ -425,8 +424,8 @@ JobCreatePipe(Job *job, int minfd)
     }
     
     /* Set close-on-exec flag for both */
-    (void)fcntl(job->jobPipe[0], F_SETFD, 1);
-    (void)fcntl(job->jobPipe[1], F_SETFD, 1);
+    (void)fcntl(job->jobPipe[0], F_SETFD, FD_CLOEXEC);
+    (void)fcntl(job->jobPipe[1], F_SETFD, FD_CLOEXEC);
 
     /*
      * We mark the input side of the pipe non-blocking; we poll(2) the
@@ -715,7 +714,7 @@ JobPrintCommand(void *cmdp, void *jobp)
 
     numCommands += 1;
 
-    cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
+    cmdStart = cmd = Var_Subst(NULL, cmd, job->node, VARF_WANTRES);
 
     cmdTemplate = "%s\n";
 
@@ -728,7 +727,6 @@ JobPrintCommand(void *cmdp, void *jobp)
            shutUp = DEBUG(LOUD) ? FALSE : TRUE;
            break;
        case '-':
-           job->flags |= JOB_IGNERR;
            errOff = TRUE;
            break;
        case '+':
@@ -807,6 +805,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);
@@ -866,8 +865,7 @@ JobPrintCommand(void *cmdp, void *jobp)
     
     DBPRINTF(cmdTemplate, cmd);
     free(cmdStart);
-    if (escCmd)
-        free(escCmd);
+    free(escCmd);
     if (errOff) {
        /*
         * If echoing is already off, there's no point in issuing the
@@ -903,7 +901,7 @@ JobPrintCommand(void *cmdp, void *jobp)
 static int
 JobSaveCommand(void *cmd, void *gn)
 {
-    cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE);
+    cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, VARF_WANTRES);
     (void)Lst_AtEnd(postCommands->commands, cmd);
     return(0);
 }
@@ -1058,7 +1056,11 @@ JobFinish (Job *job, WAIT_T status)
 
 #ifdef USE_META
     if (useMeta) {
-       meta_job_finish(job);
+       int x;
+
+       if ((x = meta_job_finish(job)) != 0 && status == 0) {
+           status = x;
+       }
     }
 #endif
     
@@ -1234,8 +1236,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
             */
            Make_HandleUse(DEFAULT, gn);
            Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0);
-           if (p1)
-               free(p1);
+           free(p1);
        } 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
@@ -1598,7 +1599,7 @@ JobStart(GNode *gn, int flags)
        if (job->cmdFILE == NULL) {
            Punt("Could not fdopen %s", tfile);
        }
-       (void)fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
+       (void)fcntl(FILENO(job->cmdFILE), F_SETFD, FD_CLOEXEC);
        /*
         * Send the commands to the command file, flush all its buffers then
         * rewind and remove the thing.
@@ -1894,16 +1895,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;
        }
     }
@@ -2194,7 +2195,8 @@ Job_SetPrefix(void)
        Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL, 0);
     }
 
-    targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}", VAR_GLOBAL, 0);
+    targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}",
+                          VAR_GLOBAL, VARF_WANTRES);
 }
 
 /*-
@@ -2401,8 +2403,7 @@ Job_ParseShell(char *line)
        line++;
     }
 
-    if (shellArgv)
-       free(UNCONST(shellArgv));
+    free(UNCONST(shellArgv));
 
     memset(&newShell, 0, sizeof(newShell));
 
@@ -2650,8 +2651,7 @@ void
 Job_End(void)
 {
 #ifdef CLEANUP
-    if (shellArgv)
-       free(shellArgv);
+    free(shellArgv);
 #endif
 }
 
@@ -2850,8 +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);
+       (void)fcntl(jp_0, F_SETFD, FD_CLOEXEC);
+       (void)fcntl(jp_1, F_SETFD, FD_CLOEXEC);
        return;
     }
 
index 32a0f7a..2209eaa 100755 (executable)
@@ -2,7 +2,7 @@
 # derrived from /etc/rc_d/os.sh
 
 # RCSid:
-#      $Id: machine.sh,v 1.16 2010/10/17 00:05:51 sjg Exp $
+#      $Id: machine.sh,v 1.17 2015/05/05 00:10:54 sjg 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
        ;;
index b5be211..ff786fb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.231 2014/09/09 06:18:17 dholland Exp $      */
+/*     $NetBSD: main.c,v 1.250 2016/08/11 19:53:17 sjg Exp $   */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.231 2014/09/09 06:18:17 dholland Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.250 2016/08/11 19:53:17 sjg 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.231 2014/09/09 06:18:17 dholland Exp $");
+__RCSID("$NetBSD: main.c,v 1.250 2016/08/11 19:53:17 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -125,7 +125,6 @@ __RCSID("$NetBSD: main.c,v 1.231 2014/09/09 06:18:17 dholland Exp $");
 #include "wait.h"
 
 #include <errno.h>
-#include <fcntl.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -172,6 +171,7 @@ Boolean                     keepgoing;      /* -k flag */
 Boolean                        queryFlag;      /* -q flag */
 Boolean                        touchFlag;      /* -t flag */
 Boolean                        enterFlag;      /* -w flag */
+Boolean                        enterFlagObj;   /* -w and objdir != srcdir */
 Boolean                        ignoreErrors;   /* -i flag */
 Boolean                        beSilent;       /* -s flag */
 Boolean                        oldVars;        /* variable substitution style */
@@ -695,8 +695,7 @@ Main_ParseArgLine(const char *line)
 #endif
        buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
        (void)snprintf(buf, len, "%s %s", argv0, line);
-       if (p1)
-               free(p1);
+       free(p1);
 
        argv = brk_string(buf, &argc, TRUE, &args);
        if (argv == NULL) {
@@ -722,7 +721,7 @@ Main_SetObjdir(const char *path)
        /* expand variable substitutions */
        if (strchr(path, '$') != 0) {
                snprintf(buf, MAXPATHLEN, "%s", path);
-               path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0);
+               path = p = Var_Subst(NULL, buf, VAR_GLOBAL, VARF_WANTRES);
        }
 
        if (path[0] != '/') {
@@ -741,11 +740,12 @@ Main_SetObjdir(const char *path)
                        setenv("PWD", objdir, 1);
                        Dir_InitDot();
                        rc = TRUE;
+                       if (enterFlag && strcmp(objdir, curdir) != 0)
+                               enterFlagObj = TRUE;
                }
        }
 
-       if (p)
-               free(p);
+       free(p);
        return rc;
 }
 
@@ -803,7 +803,8 @@ MakeMode(const char *mode)
     char *mp = NULL;
 
     if (!mode)
-       mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0);
+       mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}",
+                             VAR_GLOBAL, VARF_WANTRES);
 
     if (mode && *mode) {
        if (strstr(mode, "compat")) {
@@ -815,8 +816,8 @@ MakeMode(const char *mode)
            meta_mode_init(mode);
 #endif
     }
-    if (mp)
-       free(mp);
+
+    free(mp);
 }
 
 /*-
@@ -1013,7 +1014,7 @@ main(int argc, char **argv)
            /*
             * A relative path, canonicalize it.
             */
-           p1 = realpath(argv[0], mdpath);
+           p1 = cached_realpath(argv[0], mdpath);
            if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) {
                p1 = argv[0];           /* realpath failed */
            }
@@ -1150,14 +1151,6 @@ main(int argc, char **argv)
                }
        }
 
-       /*
-        * Be compatible if user did not specify -j and did not explicitly
-        * turned compatibility on
-        */
-       if (!compatMake && !forceJobs) {
-               compatMake = TRUE;
-       }
-       
        /*
         * Initialize archive, target and suffix modules in preparation for
         * parsing the makefile(s)
@@ -1249,7 +1242,7 @@ main(int argc, char **argv)
                            (char *)Lst_Datum(ln));
        } else {
            p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
-               VAR_CMD, 0);
+               VAR_CMD, VARF_WANTRES);
            if (p1) {
                (void)str2Lst_Append(makefiles, p1, NULL);
                (void)Lst_Find(makefiles, NULL, ReadMakefile);
@@ -1260,17 +1253,49 @@ main(int argc, char **argv)
        /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
        if (!noBuiltins || !printVars) {
            makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
-               VAR_CMD, 0);
+               VAR_CMD, VARF_WANTRES);
            doing_depend = TRUE;
            (void)ReadMakefile(makeDependfile, NULL);
            doing_depend = FALSE;
        }
 
+       if (enterFlagObj)
+               printf("%s: Entering directory `%s'\n", progname, objdir);
+       
        MakeMode(NULL);
 
        Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
-       if (p1)
-           free(p1);
+       free(p1);
+
+       if (!forceJobs && !compatMake &&
+           Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) {
+           char *value;
+           int n;
+
+           value = Var_Subst(NULL, "${.MAKE.JOBS}", VAR_GLOBAL, VARF_WANTRES);
+           n = strtol(value, NULL, 0);
+           if (n < 1) {
+               (void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n",
+                   progname);
+               exit(1);
+           }
+           if (n != maxJobs) {
+               Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
+               Var_Append(MAKEFLAGS, value, VAR_GLOBAL);
+           }
+           maxJobs = n;
+           maxJobTokens = maxJobs;
+           forceJobs = TRUE;
+           free(value);
+       }
+
+       /*
+        * Be compatible if user did not specify -j and did not explicitly
+        * turned compatibility on
+        */
+       if (!compatMake && !forceJobs) {
+           compatMake = TRUE;
+       }
 
        if (!compatMake)
            Job_ServerStart(maxJobTokens, jp_0, jp_1);
@@ -1295,7 +1320,7 @@ main(int argc, char **argv)
                 */
                static char VPATH[] = "${VPATH}";
 
-               vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE);
+               vpath = Var_Subst(NULL, VPATH, VAR_CMD, VARF_WANTRES);
                path = vpath;
                do {
                        /* skip to end of directory */
@@ -1342,20 +1367,21 @@ main(int argc, char **argv)
                        char *value;
                        
                        if (strchr(var, '$')) {
-                               value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0);
+                           value = p1 = Var_Subst(NULL, var, VAR_GLOBAL,
+                                                  VARF_WANTRES);
                        } 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);
+                               value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL,
+                                                      VARF_WANTRES);
                        } else {
                                value = Var_Value(var, VAR_GLOBAL, &p1);
                        }
                        printf("%s\n", value ? value : "");
-                       if (p1)
-                               free(p1);
+                       free(p1);
                }
        } else {
                /*
@@ -1406,9 +1432,14 @@ main(int argc, char **argv)
 
        Trace_Log(MAKEEND, 0);
 
+       if (enterFlagObj)
+               printf("%s: Leaving directory `%s'\n", progname, objdir);
        if (enterFlag)
                printf("%s: Leaving directory `%s'\n", progname, curdir);
 
+#ifdef USE_META
+       meta_finish();
+#endif
        Suff_End();
         Targ_End();
        Arch_End();
@@ -1477,8 +1508,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
                        name = Dir_FindFile(fname,
                                Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
                if (!name || (fd = open(name, O_RDONLY)) == -1) {
-                       if (name)
-                               free(name);
+                       free(name);
                        free(path);
                        return(-1);
                }
@@ -1527,7 +1557,6 @@ Cmd_Exec(const char *cmd, const char **errnum)
 
 
     *errnum = NULL;
-    savederr = 0;
 
     if (!shellName)
        Shell_Init();
@@ -1581,6 +1610,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
         */
        (void)close(fds[1]);
 
+       savederr = 0;
        Buf_Init(&buf, 0);
 
        do {
@@ -1854,6 +1884,35 @@ usage(void)
 }
 
 
+/*
+ * realpath(3) can get expensive, cache results...
+ */
+char *
+cached_realpath(const char *pathname, char *resolved)
+{
+    static GNode *cache;
+    char *rp, *cp;
+
+    if (!pathname || !pathname[0])
+       return NULL;
+
+    if (!cache) {
+       cache = Targ_NewGN("Realpath");
+#ifndef DEBUG_REALPATH_CACHE
+       cache->flags = INTERNAL;
+#endif
+    }
+
+    if ((rp = Var_Value(pathname, cache, &cp)) != NULL) {
+       /* a hit */
+       strlcpy(resolved, rp, MAXPATHLEN);
+    } else if ((rp = realpath(pathname, resolved)) != NULL) {
+       Var_Set(pathname, rp, cache, 0);
+    }
+    free(cp);
+    return rp ? resolved : NULL;
+}
+
 int
 PrintAddr(void *a, void *b)
 {
@@ -1862,6 +1921,14 @@ PrintAddr(void *a, void *b)
 }
 
 
+static int
+addErrorCMD(void *cmdp, void *gnp)
+{
+    if (cmdp == NULL)
+       return 1;                       /* stop */
+    Var_Append(".ERROR_CMD", cmdp, VAR_GLOBAL);
+    return 0;
+}
 
 void
 PrintOnError(GNode *gn, const char *s)
@@ -1882,15 +1949,19 @@ PrintOnError(GNode *gn, const char *s)
         * We can print this even if there is no .ERROR target.
         */
        Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
+       Var_Delete(".ERROR_CMD", VAR_GLOBAL);
+       Lst_ForEach(gn->commands, addErrorCMD, gn);
     }
     strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
            sizeof(tmp) - 1);
-    cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+    cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
     if (cp) {
        if (*cp)
            printf("%s", cp);
        free(cp);
     }
+    fflush(stdout);
+
     /*
      * Finally, see if there is a .ERROR target, and run it if so.
      */
@@ -1914,7 +1985,7 @@ Main_ExportMAKEFLAGS(Boolean first)
     
     strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
            sizeof(tmp));
-    s = Var_Subst(NULL, tmp, VAR_CMD, 0);
+    s = Var_Subst(NULL, tmp, VAR_CMD, VARF_WANTRES);
     if (s && *s) {
 #ifdef POSIX
        setenv("MAKEFLAGS", s, 1);
@@ -1936,7 +2007,8 @@ getTmpdir(void)
         * Honor $TMPDIR but only if it is valid.
         * Ensure it ends with /.
         */
-       tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0);
+       tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
+                          VARF_WANTRES);
        if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
            free(tmpdir);
            tmpdir = bmake_strdup(_PATH_TMP);
@@ -1976,6 +2048,44 @@ mkTempFile(const char *pattern, char **fnamep)
     return fd;
 }
 
+/*
+ * Convert a string representation of a boolean.
+ * Anything that looks like "No", "False", "Off", "0" etc,
+ * is FALSE, otherwise TRUE.
+ */
+Boolean
+s2Boolean(const char *s, Boolean bf)
+{
+    if (s) {
+       switch(*s) {
+       case '\0':                      /* not set - the default wins */
+           break;
+       case '0':
+       case 'F':
+       case 'f':
+       case 'N':
+       case 'n':
+           bf = FALSE;
+           break;
+       case 'O':
+       case 'o':
+           switch (s[1]) {
+           case 'F':
+           case 'f':
+               bf = FALSE;
+               break;
+           default:
+               bf = TRUE;
+               break;
+           }
+           break;
+       default:
+           bf = TRUE;
+           break;
+       }
+    }
+    return (bf);
+}
 
 /*
  * Return a Boolean based on setting of a knob.
@@ -1990,32 +2100,11 @@ 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 (snprintf(tmp, sizeof(tmp), "${%s:U:tl}", name) < (int)(sizeof(tmp))) {
+       cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
 
        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;
-           }
+           bf = s2Boolean(cp, bf);
            free(cp);
        }
     }
index 2bb4c25..83336b4 100755 (executable)
@@ -13,7 +13,7 @@ esac
 CC="@CC@"
 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' $srcdir/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@\" \
@@ -52,7 +52,7 @@ do_link() {
 }
 
 BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \
-job.o make.o make_malloc.o parse.o sigcompat.o str.o strlist.o \
+job.o make.o make_malloc.o metachar.o parse.o sigcompat.o str.o strlist.o \
 suff.o targ.o trace.o var.o util.o"
 
 LST_OBJECTS="lstAppend.o lstDupl.o lstInit.o lstOpen.o \
index 153dce7..fb3333c 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $NetBSD: make.1,v 1.243 2014/09/14 08:47:19 apb Exp $
+.\"    $NetBSD: make.1,v 1.262 2016/08/18 19:23:20 wiz 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 September 13, 2014
+.Dd August 15, 2016
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -293,7 +293,7 @@ then
 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.
+the Makefile and then works upward towards the root of the file system.
 If the search is successful, then the resulting directory replaces the
 .Qq \&.../
 specification in the
@@ -481,6 +481,7 @@ 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
@@ -495,6 +496,15 @@ If the command contains any shell meta characters
 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
@@ -675,6 +685,9 @@ or it will not be recognized.
 .It Va .TARGET
 The name of the target; also known as
 .Ql Va @ .
+For compatibility with other makes this is an alias for
+.Ic .ARCHIVE
+in archive member rules.
 .El
 .Pp
 The shorter forms
@@ -833,7 +846,7 @@ Can affect the mode that
 .Nm
 runs in.
 It can contain a number of keywords:
-.Bl -hang -width ignore-cmd
+.Bl -hang -width missing-filemon=bf.
 .It Pa compat
 Like
 .Fl B ,
@@ -857,8 +870,19 @@ will not create .meta files in
 This can be overridden by setting
 .Va bf
 to a value which represents True.
+.It Pa missing-meta= Ar bf
+If
+.Va bf
+is True, then a missing .meta file makes the target out-of-date.
+.It Pa missing-filemon= Ar bf
+If
+.Va bf
+is True, then missing filemon data makes the target out-of-date.
+.It Pa nofilemon
+Do not use
+.Xr filemon 4 .
 .It Pa env
-For debugging, it can be useful to inlcude the environment
+For debugging, it can be useful to include the environment
 in the .meta file.
 .It Pa verbose
 If in "meta" mode, print a clue about the target being built.
@@ -900,6 +924,12 @@ 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.IGNORE_PATTERNS
+Provides a list of patterns to match against pathnames.
+Ignore any that match.
+.It Va .MAKE.META.IGNORE_FILTER
+Provides a list of variable modifiers to apply to each pathname.
+Ignore if the expansion is an empty string.
 .It Va .MAKE.META.PREFIX
 Defines the message printed for each meta file updated in "meta verbose" mode.
 The default value is:
@@ -908,7 +938,7 @@ The default value is:
 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
 .Ql Ev MAKEFLAGS .
-This behaviour can be disabled by assigning an empty value to
+This behavior can be disabled by assigning an empty value to
 .Ql Va .MAKEOVERRIDES
 within a makefile.
 Extra variables can be exported from a makefile
@@ -931,10 +961,35 @@ The process-id of
 .It Va .MAKE.PPID
 The parent process-id of
 .Nm .
+.It Va .MAKE.SAVE_DOLLARS
+value should be a boolean that controls whether
+.Ql $$
+are preserved when doing
+.Ql :=
+assignments.
+The default is false, for backwards compatibility.
+Set to true for compatability with other makes.
+If set to false,
+.Ql $$
+becomes
+.Ql $
+per normal evaluation rules.
 .It Va MAKE_PRINT_VAR_ON_ERROR
 When
 .Nm
-stops due to an error, it prints its name and the value of
+stops due to an error, it sets
+.Ql Va .ERROR_TARGET
+to the name of the target that failed,
+.Ql Va .ERROR_CMD
+to the commands of the failed target,
+and in "meta" mode, it also sets
+.Ql Va .ERROR_CWD
+to the
+.Xr getcwd 3 ,
+and
+.Ql Va .ERROR_META_FILE
+to the path of the meta file (if any) describing the failed target.
+It then prints its name and the value of
 .Ql Va .CURDIR
 as well as the value of any variables named in
 .Ql Va MAKE_PRINT_VAR_ON_ERROR .
@@ -983,14 +1038,15 @@ This is especially useful with
 .Ql Ev MAKEOBJDIR .
 .Pp
 .Ql Va .OBJDIR
-may be modified in the makefile as a global variable.
+may be modified in the makefile via the special target
+.Ql Ic .OBJDIR .
 In all cases,
 .Nm
 will
 .Xr chdir 2
-to
+to the specified directory if it exists, and set
 .Ql Va .OBJDIR
-and set
+and
 .Ql Ev PWD
 to that directory before executing any targets.
 .
@@ -1033,7 +1089,7 @@ sets
 to the value of
 .Ql Ev PWD
 instead.
-This behaviour is disabled if
+This behavior is disabled if
 .Ql Ev MAKEOBJDIRPREFIX
 is set or
 .Ql Ev MAKEOBJDIR
@@ -1103,7 +1159,7 @@ The wildcard 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
 .Dl ${VAR:M*}
-will normalise the inter-word spacing, removing all leading and
+will normalize the inter-word spacing, removing all leading and
 trailing space, and converting multiple consecutive spaces
 to single spaces.
 .
@@ -1123,7 +1179,7 @@ Randomize words in variable.
 The results will be different each time you are referring to the
 modified variable; use the assignment with expansion
 .Pq Ql Cm \&:=
-to prevent such behaviour.
+to prevent such behavior.
 For example,
 .Bd -literal -offset indent
 LIST=                  uno due tre quattro
@@ -1155,7 +1211,7 @@ The value is a format string for
 using the current
 .Xr gmtime 3 .
 .It Cm \&:hash
-Compute a 32bit hash of the value and encode it as hex digits.
+Compute a 32-bit hash of the value and encode it as hex digits.
 .It Cm \&:localtime
 The value is a format string for
 .Xr strftime 3 ,
@@ -1433,7 +1489,7 @@ value is divided into words.
 .Pp
 Ordinarily, a value is treated as a sequence of words
 delimited by white space.
-Some modifiers suppress this behaviour,
+Some modifiers suppress this behavior,
 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,
@@ -1519,12 +1575,20 @@ For compatibility with other versions of
 .Nm
 .Ql include file ...
 is also accepted.
+.Pp
 If the include statement is written as
 .Cm .-include
 or as
 .Cm .sinclude
 then errors locating and/or opening include files are ignored.
 .Pp
+If the include statement is written as
+.Cm .dinclude
+not only are errors locating and/or opening include files ignored,
+but stale dependencies within the included file will be ignored
+just like
+.Va .MAKE.DEPENDFILE .
+.Pp
 Conditional expressions are also preceded by a single dot as the first
 character of a line.
 The possible conditionals are as follows:
@@ -1560,6 +1624,10 @@ This allows exporting a value to the environment which is different from that
 used by
 .Nm
 internally.
+.It Ic .export-literal Ar variable ...
+The same as
+.Ql .export-env ,
+except that variables in the value are not expanded.
 .It Ic .info Ar message
 The message is printed along with the name of the makefile and line number.
 .It Ic .undef Ar variable
@@ -1991,6 +2059,15 @@ Disable parallel mode.
 Synonym for
 .Ic .NOTPARALLEL ,
 for compatibility with other pmake variants.
+.It Ic .OBJDIR
+The source is a new value for
+.Ql Va .OBJDIR .
+If it exists,
+.Nm
+will
+.Xr chdir 2
+to it and update the value of
+.Ql Va .OBJDIR .
 .It Ic .ORDER
 The named targets are made in sequence.
 This ordering does not add targets to the list of targets to be made.
@@ -2048,7 +2125,7 @@ The sources are a set of
 pairs.
 .Bl -tag -width hasErrCtls
 .It Ar name
-This is the minimal specification, used to select one of the builtin
+This is the minimal specification, used to select one of the built-in
 shell specs;
 .Ar sh ,
 .Ar ksh ,
index fde1850..5ea04fc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: make.c,v 1.91 2014/10/18 08:33:30 snj Exp $    */
+/*     $NetBSD: make.c,v 1.95 2016/02/18 18:29:14 christos Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: make.c,v 1.91 2014/10/18 08:33:30 snj Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.95 2016/02/18 18:29:14 christos 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.91 2014/10/18 08:33:30 snj Exp $");
+__RCSID("$NetBSD: make.c,v 1.95 2016/02/18 18:29:14 christos Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -482,10 +482,9 @@ Make_HandleUse(GNode *cgn, GNode *pgn)
            if (gn->uname == NULL) {
                gn->uname = gn->name;
            } else {
-               if (gn->name)
-                   free(gn->name);
+               free(gn->name);
            }
-           gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE);
+           gn->name = Var_Subst(NULL, gn->uname, pgn, VARF_WANTRES);
            if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) {
                /* See if we have a target for this node. */
                tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
@@ -692,8 +691,7 @@ Make_Update(GNode *cgn)
     checked++;
 
     cname = Var_Value(TARGET, cgn, &p1);
-    if (p1)
-       free(p1);
+    free(p1);
 
     if (DEBUG(MAKE))
        fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);
@@ -838,8 +836,7 @@ Make_Update(GNode *cgn)
                    Var_Set(PREFIX, cpref, pgn, 0);
            }
        }
-       if (p1)
-           free(p1);
+       free(p1);
        Lst_Close(cgn->iParents);
     }
 }
@@ -907,8 +904,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
        }
        if (allsrc != NULL)
                Var_Append(ALLSRC, allsrc, pgn);
-       if (p2)
-           free(p2);
+       free(p2);
        if (pgn->type & OP_JOIN) {
            if (cgn->made == MADE) {
                Var_Append(OODATE, child, pgn);
@@ -934,8 +930,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
             */
            Var_Append(OODATE, child, pgn);
        }
-       if (p1)
-           free(p1);
+       free(p1);
     }
     return (0);
 }
@@ -981,8 +976,7 @@ Make_DoAllVar(GNode *gn)
     if (gn->type & OP_JOIN) {
        char *p1;
        Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn, 0);
-       if (p1)
-           free(p1);
+       free(p1);
     }
     gn->flags |= DONE_ALLSRC;
 }
index 9cf7243..0fe12ab 100644 (file)
@@ -1,4 +1,4 @@
-/*     $NetBSD: make.h,v 1.95 2014/09/07 20:55:34 joerg Exp $  */
+/*     $NetBSD: make.h,v 1.100 2016/06/07 00:40:00 sjg Exp $   */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -88,6 +88,7 @@
 #include <sys/param.h>
 
 #include <ctype.h>
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef HAVE_STRING_H
 #include <unistd.h>
 #include <sys/cdefs.h>
 
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
 #if defined(__GNUC__)
 #define        MAKE_GNUC_PREREQ(x, y)                                          \
        ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||                  \
@@ -194,6 +199,7 @@ typedef struct GNode {
 #define DONE_ALLSRC    0x40    /* We do it once only */
 #define CYCLE          0x1000  /* Used by MakePrintStatus */
 #define DONECYCLE      0x2000  /* Used by MakePrintStatus */
+#define INTERNAL       0x4000  /* Internal use only */
     enum enum_made {
        UNMADE, DEFERRED, REQUESTED, BEINGMADE,
        MADE, UPTODATE, ERROR, ABORTED
@@ -500,6 +506,12 @@ void Main_ExportMAKEFLAGS(Boolean);
 Boolean Main_SetObjdir(const char *);
 int mkTempFile(const char *, char **);
 int str2Lst_Append(Lst, char *, const char *);
+int cached_lstat(const char *, void *);
+int cached_stat(const char *, void *);
+
+#define        VARF_UNDEFERR   1
+#define        VARF_WANTRES    2
+#define        VARF_ASSIGN     4
 
 #ifdef __GNUC__
 #define UNCONST(ptr)   ({              \
@@ -519,8 +531,15 @@ int str2Lst_Append(Lst, char *, const char *);
 #define MAX(a, b) ((a > b) ? a : b)
 #endif
 
+/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
 #ifndef MAXPATHLEN
-#define MAXPATHLEN BMAKE_PATH_MAX
+#define MAXPATHLEN     BMAKE_PATH_MAX
+#endif
+#ifndef PATH_MAX
+#define PATH_MAX       MAXPATHLEN
 #endif
 
 #endif /* _MAKE_H_ */
index 4b9add7..0ea41f6 100644 (file)
@@ -1,4 +1,4 @@
-/*      $NetBSD: meta.c,v 1.36 2014/11/06 01:36:57 sjg Exp $ */
+/*      $NetBSD: meta.c,v 1.67 2016/08/17 15:52:42 sjg Exp $ */
 
 /*
  * Implement 'meta' mode.
@@ -6,7 +6,7 @@
  * --sjg
  */
 /*
- * Copyright (c) 2009-2010, Juniper Networks, Inc.
+ * Copyright (c) 2009-2016, Juniper Networks, Inc.
  * Portions Copyright (c) 2009, John Birrell.
  * 
  * Redistribution and use in source and binary forms, with or without
 #endif
 #include <sys/stat.h>
 #include <sys/ioctl.h>
-#include <fcntl.h>
+#ifdef HAVE_LIBGEN_H
 #include <libgen.h>
+#elif !defined(HAVE_DIRNAME)
+char * dirname(char *);
+#endif
 #include <errno.h>
 #if !defined(HAVE_CONFIG_H) || defined(HAVE_ERR_H)
 #include <err.h>
 
 static BuildMon Mybm;                  /* for compat */
 static Lst metaBailiwick;              /* our scope of control */
+static char *metaBailiwickStr;         /* string storage for the list */
 static Lst metaIgnorePaths;            /* paths we deliberately ignore */
+static char *metaIgnorePathsStr;       /* string storage for the list */
 
 #ifndef MAKE_META_IGNORE_PATHS
 #define MAKE_META_IGNORE_PATHS ".MAKE.META.IGNORE_PATHS"
 #endif
+#ifndef MAKE_META_IGNORE_PATTERNS
+#define MAKE_META_IGNORE_PATTERNS ".MAKE.META.IGNORE_PATTERNS"
+#endif
+#ifndef MAKE_META_IGNORE_FILTER
+#define MAKE_META_IGNORE_FILTER ".MAKE.META.IGNORE_FILTER"
+#endif
 
 Boolean useMeta = FALSE;
 static Boolean useFilemon = FALSE;
 static Boolean writeMeta = FALSE;
+static Boolean metaMissing = FALSE;    /* oodate if missing */
+static Boolean filemonMissing = FALSE; /* oodate if missing */
 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 metaIgnorePatterns = FALSE; /* do we need to do pattern matches */
+static Boolean metaIgnoreFilter = FALSE;   /* do we have more complex filtering? */
 static Boolean metaCurdirOk = FALSE;   /* write .meta in .CURDIR Ok? */
 static Boolean metaSilent = FALSE;     /* if we have a .meta be SILENT */
 
@@ -144,36 +159,41 @@ filemon_open(BuildMon *pbm)
        err(1, "Could not set filemon file descriptor!");
     }
     /* we don't need these once we exec */
-    (void)fcntl(pbm->mon_fd, F_SETFD, 1);
-    (void)fcntl(pbm->filemon_fd, F_SETFD, 1);
+    (void)fcntl(pbm->mon_fd, F_SETFD, FD_CLOEXEC);
+    (void)fcntl(pbm->filemon_fd, F_SETFD, FD_CLOEXEC);
 }
 
 /*
  * Read the build monitor output file and write records to the target's
  * metadata file.
  */
-static void
+static int
 filemon_read(FILE *mfp, int fd)
 {
     char buf[BUFSIZ];
     int n;
+    int error;
 
     /* Check if we're not writing to a meta data file.*/
     if (mfp == NULL) {
        if (fd >= 0)
            close(fd);                  /* not interested */
-       return;
+       return 0;
     }
     /* rewind */
     (void)lseek(fd, (off_t)0, SEEK_SET);
 
+    error = 0;
     fprintf(mfp, "\n-- filemon acquired metadata --\n");
 
     while ((n = read(fd, buf, sizeof(buf))) > 0) {
-       fwrite(buf, 1, n, mfp);
+       if ((int)fwrite(buf, 1, n, mfp) < n)
+           error = EIO;
     }
     fflush(mfp);
-    close(fd);
+    if (close(fd) < 0)
+       error = errno;
+    return error;
 }
 #endif
 
@@ -223,24 +243,13 @@ eat_dots(char *buf, size_t bufsz, int dots)
 static char *
 meta_name(struct GNode *gn, char *mname, size_t mnamelen,
          const char *dname,
-         const char *tname)
+         const char *tname,
+         const char *cwd)
 {
     char buf[MAXPATHLEN];
-    char cwd[MAXPATHLEN];
     char *rp;
     char *cp;
     char *tp;
-    char *p[4];                                /* >= number of possible uses */
-    int i;
-
-    i = 0;
-    if (!dname)
-       dname = Var_Value(".OBJDIR", gn, &p[i++]);
-    if (!tname)
-       tname = Var_Value(TARGET, gn, &p[i++]);
-
-    if (realpath(dname, cwd))
-       dname = cwd;
 
     /*
      * Weed out relative paths from the target file name.
@@ -250,7 +259,7 @@ meta_name(struct GNode *gn, char *mname, size_t mnamelen,
      * basename as given to us.
      */
     if ((cp = strrchr(tname, '/'))) {
-       if (realpath(tname, buf)) {
+       if (cached_realpath(tname, buf)) {
            if ((rp = strrchr(buf, '/'))) {
                rp++;
                cp++;
@@ -295,10 +304,6 @@ meta_name(struct GNode *gn, char *mname, size_t mnamelen,
        }
     }
     free(tp);
-    for (i--; i >= 0; i--) {
-       if (p[i])
-           free(p[i]);
-    }
     return (mname);
 }
 
@@ -324,7 +329,7 @@ is_submake(void *cmdp, void *gnp)
     }
     cp = strchr(cmd, '$');
     if ((cp)) {
-       mp = Var_Subst(NULL, cmd, gn, FALSE);
+       mp = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
        cmd = mp;
     }
     cp2 = strstr(cmd, p_make);
@@ -349,8 +354,7 @@ is_submake(void *cmdp, void *gnp)
            }
        }
     }
-    if (mp)
-       free(mp);
+    free(mp);
     return (rc);
 }
 
@@ -367,11 +371,10 @@ printCMD(void *cmdp, void *mfpp)
     char *cp = NULL;
 
     if (strchr(cmd, '$')) {
-       cmd = cp = Var_Subst(NULL, cmd, mfp->gn, FALSE);
+       cmd = cp = Var_Subst(NULL, cmd, mfp->gn, VARF_WANTRES);
     }
     fprintf(mfp->fp, "CMD %s\n", cmd);
-    if (cp)
-       free(cp);
+    free(cp);
     return 0;
 }
 
@@ -380,29 +383,26 @@ printCMD(void *cmdp, void *mfpp)
  */
 #define SKIP_META_TYPE(_type) do { \
     if ((gn->type & __CONCAT(OP_, _type))) {   \
-       if (DEBUG(META)) { \
+       if (verbose) { \
            fprintf(debug_file, "Skipping meta for %s: .%s\n", \
                    gn->name, __STRING(_type));                \
        } \
-       return (NULL); \
+       return FALSE; \
     } \
 } while (0)
 
-static FILE *
-meta_create(BuildMon *pbm, GNode *gn)
+
+/*
+ * Do we need/want a .meta file ?
+ */
+static Boolean
+meta_needed(GNode *gn, const char *dname, const char *tname,
+            char *objdir, int verbose)
 {
-    meta_file_t mf;
-    char buf[MAXPATHLEN];
-    char objdir[MAXPATHLEN];
-    char **ptr;
-    const char *dname;
-    const char *tname;
-    char *fname;
-    const char *cp;
-    char *p[4];                                /* >= possible uses */
-    int i;
     struct stat fs;
 
+    if (verbose)
+       verbose = DEBUG(META);
     
     /* This may be a phony node which we don't want meta data for... */
     /* Skip .meta for .BEGIN, .END, .ERROR etc as well. */
@@ -415,54 +415,76 @@ meta_create(BuildMon *pbm, GNode *gn)
        SKIP_META_TYPE(MAKE);
     }
 
-    mf.fp = NULL;
-    
-    i = 0;
-    
-    dname = Var_Value(".OBJDIR", gn, &p[i++]);
-    tname = Var_Value(TARGET, gn, &p[i++]);
-    
-    /* The object directory may not exist. Check it.. */
-    if (stat(dname, &fs) != 0) {
-       if (DEBUG(META))
-           fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
-                   gn->name);
-       goto out;
-    }
     /* Check if there are no commands to execute. */
     if (Lst_IsEmpty(gn->commands)) {
-       if (DEBUG(META))
+       if (verbose)
            fprintf(debug_file, "Skipping meta for %s: no commands\n",
                    gn->name);
-       goto out;
+       return FALSE;
+    }
+    if ((gn->type & (OP_META|OP_SUBMAKE)) == OP_SUBMAKE) {
+       /* OP_SUBMAKE is a bit too aggressive */
+       if (Lst_ForEach(gn->commands, is_submake, gn)) {
+           if (DEBUG(META))
+               fprintf(debug_file, "Skipping meta for %s: .SUBMAKE\n",
+                       gn->name);
+           return FALSE;
+       }
+    }
+
+    /* The object directory may not exist. Check it.. */
+    if (cached_stat(dname, &fs) != 0) {
+       if (verbose)
+           fprintf(debug_file, "Skipping meta for %s: no .OBJDIR\n",
+                   gn->name);
+       return FALSE;
     }
 
     /* make sure these are canonical */
-    if (realpath(dname, objdir))
+    if (cached_realpath(dname, objdir))
        dname = objdir;
 
     /* If we aren't in the object directory, don't create a meta file. */
     if (!metaCurdirOk && strcmp(curdir, dname) == 0) {
-       if (DEBUG(META))
+       if (verbose)
            fprintf(debug_file, "Skipping meta for %s: .OBJDIR == .CURDIR\n",
                    gn->name);
-       goto out;
-    }
-    if (!(gn->type & OP_META)) {
-       /* We do not generate .meta files for sub-makes */
-       if (Lst_ForEach(gn->commands, is_submake, gn)) {
-           if (DEBUG(META))
-               fprintf(debug_file, "Skipping meta for %s: .MAKE\n",
-                       gn->name);
-           goto out;
-       }
+       return FALSE;
     }
+    return TRUE;
+}
+
+    
+static FILE *
+meta_create(BuildMon *pbm, GNode *gn)
+{
+    meta_file_t mf;
+    char buf[MAXPATHLEN];
+    char objdir[MAXPATHLEN];
+    char **ptr;
+    const char *dname;
+    const char *tname;
+    char *fname;
+    const char *cp;
+    char *p[4];                                /* >= possible uses */
+    int i;
+
+    mf.fp = NULL;
+    i = 0;
+
+    dname = Var_Value(".OBJDIR", gn, &p[i++]);
+    tname = Var_Value(TARGET, gn, &p[i++]);
+
+    /* if this succeeds objdir is realpath of dname */
+    if (!meta_needed(gn, dname, tname, objdir, TRUE))
+       goto out;
+    dname = objdir;
 
     if (metaVerbose) {
        char *mp;
 
        /* Describe the target we are building */
-       mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, 0);
+       mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, VARF_WANTRES);
        if (*mp)
            fprintf(stdout, "%s\n", mp);
        free(mp);
@@ -476,15 +498,12 @@ meta_create(BuildMon *pbm, GNode *gn)
 
     fflush(stdout);
 
-    if (strcmp(cp, makeDependfile) == 0)
-       goto out;
-
     if (!writeMeta)
        /* Don't create meta data. */
        goto out;
 
     fname = meta_name(gn, pbm->meta_fname, sizeof(pbm->meta_fname),
-                     dname, tname);
+                     dname, tname, objdir);
 
 #ifdef DEBUG_META_MODE
     if (DEBUG(META))
@@ -520,8 +539,7 @@ meta_create(BuildMon *pbm, GNode *gn)
     }
  out:
     for (i--; i >= 0; i--) {
-       if (p[i])
-           free(p[i]);
+       free(p[i]);
     }
 
     return (mf.fp);
@@ -554,6 +572,10 @@ meta_init(void)
 }
 
 
+#define get_mode_bf(bf, token) \
+    if ((cp = strstr(make_mode, token))) \
+       bf = boolValue(&cp[sizeof(token) - 1])
+
 /*
  * Initialization we need after reading makefiles.
  */
@@ -576,17 +598,13 @@ meta_mode_init(const char *make_mode)
            writeMeta = FALSE;
        if (strstr(make_mode, "nofilemon"))
            useFilemon = FALSE;
-       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 */
-       Var_Set(".MAKE.META_CREATED", "${.MAKE.META.CREATED}", VAR_GLOBAL, 0);
-       Var_Set(".MAKE.META_FILES", "${.MAKE.META.FILES}", VAR_GLOBAL, 0);
+       if (useFilemon)
+           get_mode_bf(filemonMissing, "missing-filemon=");
+       get_mode_bf(metaCurdirOk, "curdirok=");
+       get_mode_bf(metaMissing, "missing-meta=");
+       get_mode_bf(metaSilent, "silent=");
     }
     if (metaVerbose && !Var_Exists(MAKE_META_PREFIX, VAR_GLOBAL)) {
        /*
@@ -605,9 +623,10 @@ meta_mode_init(const char *make_mode)
      * We consider ourselves master of all within ${.MAKE.META.BAILIWICK}
      */
     metaBailiwick = Lst_Init(FALSE);
-    cp = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}", VAR_GLOBAL, 0);
-    if (cp) {
-       str2Lst_Append(metaBailiwick, cp, NULL);
+    metaBailiwickStr = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}",
+       VAR_GLOBAL, VARF_WANTRES);
+    if (metaBailiwickStr) {
+       str2Lst_Append(metaBailiwick, metaBailiwickStr, NULL);
     }
     /*
      * We ignore any paths that start with ${.MAKE.META.IGNORE_PATHS}
@@ -615,10 +634,25 @@ meta_mode_init(const char *make_mode)
     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);
+    metaIgnorePathsStr = Var_Subst(NULL,
+                  "${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL,
+                  VARF_WANTRES);
+    if (metaIgnorePathsStr) {
+       str2Lst_Append(metaIgnorePaths, metaIgnorePathsStr, NULL);
+    }
+
+    /*
+     * We ignore any paths that match ${.MAKE.META.IGNORE_PATTERNS}
+     */
+    cp = NULL;
+    if (Var_Value(MAKE_META_IGNORE_PATTERNS, VAR_GLOBAL, &cp)) {
+       metaIgnorePatterns = TRUE;
+       free(cp);
+    }
+    cp = NULL;
+    if (Var_Value(MAKE_META_IGNORE_FILTER, VAR_GLOBAL, &cp)) {
+       metaIgnoreFilter = TRUE;
+       free(cp);
     }
 }
 
@@ -659,17 +693,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
@@ -683,9 +721,9 @@ meta_job_error(Job *job, GNode *gn, int flags, int status)
 
     if (job != NULL) {
        pbm = &job->bm;
-    } else {
        if (!gn)
            gn = job->node;
+    } else {
        pbm = &Mybm;
     }
     if (pbm->mfp != NULL) {
@@ -699,7 +737,7 @@ meta_job_error(Job *job, GNode *gn, int flags, int status)
     }
     getcwd(cwd, sizeof(cwd));
     Var_Set(".ERROR_CWD", cwd, VAR_GLOBAL, 0);
-    if (pbm && pbm->meta_fname[0]) {
+    if (pbm->meta_fname[0]) {
        Var_Set(".ERROR_META_FILE", pbm->meta_fname, VAR_GLOBAL, 0);
     }
     meta_job_finish(job);
@@ -723,7 +761,8 @@ meta_job_output(Job *job, char *cp, const char *nl)
            if (!meta_prefix) {
                char *cp2;
 
-               meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", VAR_GLOBAL, 0);
+               meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}",
+                                       VAR_GLOBAL, VARF_WANTRES);
                if ((cp2 = strchr(meta_prefix, '$')))
                    meta_prefix_len = cp2 - meta_prefix;
                else
@@ -739,27 +778,35 @@ meta_job_output(Job *job, char *cp, const char *nl)
     }
 }
 
-void
+int
 meta_cmd_finish(void *pbmp)
 {
+    int error = 0;
 #ifdef USE_FILEMON
     BuildMon *pbm = pbmp;
+    int x;
 
     if (!pbm)
        pbm = &Mybm;
 
     if (pbm->filemon_fd >= 0) {
-       close(pbm->filemon_fd);
-       filemon_read(pbm->mfp, pbm->mon_fd);
+       if (close(pbm->filemon_fd) < 0)
+           error = errno;
+       x = filemon_read(pbm->mfp, pbm->mon_fd);
+       if (error == 0 && x != 0)
+           error = x;
        pbm->filemon_fd = pbm->mon_fd = -1;
     }
 #endif
+    return error;
 }
 
-void
+int
 meta_job_finish(Job *job)
 {
     BuildMon *pbm;
+    int error = 0;
+    int x;
 
     if (job != NULL) {
        pbm = &job->bm;
@@ -767,11 +814,23 @@ meta_job_finish(Job *job)
        pbm = &Mybm;
     }
     if (pbm->mfp != NULL) {
-       meta_cmd_finish(pbm);
-       fclose(pbm->mfp);
+       error = meta_cmd_finish(pbm);
+       x = fclose(pbm->mfp);
+       if (error == 0 && x != 0)
+           error = errno;
        pbm->mfp = NULL;
        pbm->meta_fname[0] = '\0';
     }
+    return error;
+}
+
+void
+meta_finish(void)
+{
+    Lst_Destroy(metaBailiwick, NULL);
+    free(metaBailiwickStr);
+    Lst_Destroy(metaIgnorePaths, NULL);
+    free(metaIgnorePathsStr);
 }
 
 /*
@@ -819,6 +878,7 @@ fgetLine(char **bufp, size_t *szp, int o, FILE *fp)
     return 0;
 }
 
+/* Lst_ForEach wants 1 to stop search */
 static int
 prefix_match(void *p, void *q)
 {
@@ -829,6 +889,32 @@ prefix_match(void *p, void *q)
     return (0 == strncmp(path, prefix, n));
 }
 
+/*
+ * looking for exact or prefix/ match to
+ * Lst_Find wants 0 to stop search
+ */
+static int
+path_match(const void *p, const void *q)
+{
+    const char *prefix = q;
+    const char *path = p;
+    size_t n = strlen(prefix);
+    int rc;
+
+    if ((rc = strncmp(path, prefix, n)) == 0) {
+       switch (path[n]) {
+       case '\0':
+       case '/':
+           break;
+       default:
+           rc = 1;
+           break;
+       }
+    }
+    return rc;
+}
+
+/* Lst_Find wants 0 to stop search */
 static int
 string_match(const void *p, const void *q)
 {
@@ -839,11 +925,73 @@ string_match(const void *p, const void *q)
 }
 
 
+static int
+meta_ignore(GNode *gn, const char *p)
+{
+    char fname[MAXPATHLEN];
+
+    if (p == NULL)
+       return TRUE;
+
+    if (*p == '/') {
+       cached_realpath(p, fname); /* clean it up */
+       if (Lst_ForEach(metaIgnorePaths, prefix_match, fname)) {
+#ifdef DEBUG_META_MODE
+           if (DEBUG(META))
+               fprintf(debug_file, "meta_oodate: ignoring path: %s\n",
+                       p);
+#endif
+           return TRUE;
+       }
+    }
+
+    if (metaIgnorePatterns) {
+       char *pm;
+
+       snprintf(fname, sizeof(fname),
+                "${%s:@m@${%s:L:M$m}@}",
+                MAKE_META_IGNORE_PATTERNS, p);
+       pm = Var_Subst(NULL, fname, gn, VARF_WANTRES);
+       if (*pm) {
+#ifdef DEBUG_META_MODE
+           if (DEBUG(META))
+               fprintf(debug_file, "meta_oodate: ignoring pattern: %s\n",
+                       p);
+#endif
+           free(pm);
+           return TRUE;
+       }
+       free(pm);
+    }
+
+    if (metaIgnoreFilter) {
+       char *fm;
+
+       /* skip if filter result is empty */
+       snprintf(fname, sizeof(fname),
+                "${%s:L:${%s:ts:}}",
+                p, MAKE_META_IGNORE_FILTER);
+       fm = Var_Subst(NULL, fname, gn, VARF_WANTRES);
+       if (*fm == '\0') {
+#ifdef DEBUG_META_MODE
+           if (DEBUG(META))
+               fprintf(debug_file, "meta_oodate: ignoring filtered: %s\n",
+                       p);
+#endif
+           free(fm);
+           return TRUE;
+       }
+       free(fm);
+    }
+    return FALSE;
+}
+
 /*
  * When running with 'meta' functionality, a target can be out-of-date
  * 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"
 
 /*
@@ -869,11 +1017,16 @@ 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];
+    const char *dname;
+    const char *tname;
     char *p;
     char *cp;
     char *link_src;
@@ -883,10 +1036,23 @@ meta_oodate(GNode *gn, Boolean oodate)
     FILE *fp;
     Boolean needOODATE = FALSE;
     Lst missingFiles;
-    
+    char *pa[4];                       /* >= possible uses */
+    int i;
+    int have_filemon = FALSE;
+
     if (oodate)
        return oodate;          /* we're done */
 
+    i = 0;
+
+    dname = Var_Value(".OBJDIR", gn, &pa[i++]);
+    tname = Var_Value(TARGET, gn, &pa[i++]);
+
+    /* if this succeeds fname3 is realpath of dname */
+    if (!meta_needed(gn, dname, tname, fname3, FALSE))
+       goto oodate_out;
+    dname = fname3;
+
     missingFiles = Lst_Init(FALSE);
 
     /*
@@ -897,7 +1063,7 @@ meta_oodate(GNode *gn, Boolean oodate)
      */
     Make_DoAllVar(gn);
 
-    meta_name(gn, fname, sizeof(fname), NULL, NULL);
+    meta_name(gn, fname, sizeof(fname), dname, tname, dname);
 
 #ifdef DEBUG_META_MODE
     if (DEBUG(META))
@@ -910,7 +1076,6 @@ meta_oodate(GNode *gn, Boolean oodate)
        int lineno = 0;
        int lastpid = 0;
        int pid;
-       int f = 0;
        int x;
        LstNode ln;
        struct stat fs;
@@ -925,6 +1090,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();
@@ -947,13 +1114,13 @@ meta_oodate(GNode *gn, Boolean oodate)
            link_src = NULL;
            move_target = NULL;
            /* Find the start of the build monitor section. */
-           if (!f) {
+           if (!have_filemon) {
                if (strncmp(buf, "-- filemon", 10) == 0) {
-                   f = 1;
+                   have_filemon = TRUE;
                    continue;
                }
                if (strncmp(buf, "# buildmon", 10) == 0) {
-                   f = 1;
+                   have_filemon = TRUE;
                    continue;
                }
            }               
@@ -965,7 +1132,7 @@ meta_oodate(GNode *gn, Boolean oodate)
                fprintf(debug_file, "%s: %d: %s\n", fname, lineno, buf);
 #endif
            strsep(&p, " ");
-           if (f) {
+           if (have_filemon) {
                /*
                 * We are in the 'filemon' output section.
                 * Each record from filemon follows the general form:
@@ -1008,25 +1175,32 @@ meta_oodate(GNode *gn, Boolean oodate)
                        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);
                        if (ldir) {
                            strlcpy(latestdir, ldir, sizeof(latestdir));
-                           if (tp)
-                               free(tp);
-                       } else 
-                           strlcpy(latestdir, cwd, sizeof(latestdir));
+                           free(tp);
+                       }
+                       ldir = Var_Value(lcwd_vname, VAR_GLOBAL, &tp);
+                       if (ldir) {
+                           strlcpy(lcwd, ldir, sizeof(lcwd));
+                           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;
                }
@@ -1036,6 +1210,7 @@ meta_oodate(GNode *gn, Boolean oodate)
                /* 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;
@@ -1047,15 +1222,30 @@ 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 */
@@ -1077,12 +1267,19 @@ meta_oodate(GNode *gn, Boolean oodate)
                    /* FALLTHROUGH */
                case 'D':               /* unlink */
                    if (*p == '/' && !Lst_IsEmpty(missingFiles)) {
-                       /* remove p from the missingFiles list if present */
-                       if ((ln = Lst_Find(missingFiles, p, string_match)) != NULL) {
-                           char *tp = Lst_Datum(ln);
-                           Lst_Remove(missingFiles, ln);
-                           free(tp);
-                           ln = NULL;  /* we're done with it */
+                       /* remove any missingFiles entries that match p */
+                       if ((ln = Lst_Find(missingFiles, p,
+                                          path_match)) != NULL) {
+                           LstNode nln;
+                           char *tp;
+
+                           do {
+                               nln = Lst_FindFrom(missingFiles, Lst_Succ(ln),
+                                                  p, path_match);
+                               tp = Lst_Datum(ln);
+                               Lst_Remove(missingFiles, ln);
+                               free(tp);
+                           } while ((ln = nln) != NULL);
                        }
                    }
                    if (buf[0] == 'M') {
@@ -1145,8 +1342,12 @@ meta_oodate(GNode *gn, Boolean oodate)
                    if ((strstr("tmp", p)))
                        break;
 
-                   if (stat(p, &fs) < 0) {
-                       Lst_AtEnd(missingFiles, bmake_strdup(p));
+                   if ((link_src != NULL && cached_lstat(p, &fs) < 0) ||
+                       (link_src == NULL && cached_stat(p, &fs) < 0)) {
+                       if (!meta_ignore(gn, p)) {
+                           if (Lst_Find(missingFiles, p, string_match) == NULL)
+                               Lst_AtEnd(missingFiles, bmake_strdup(p));
+                       }
                    }
                    break;
                check_link_src:
@@ -1164,26 +1365,9 @@ meta_oodate(GNode *gn, Boolean oodate)
                     * be part of the dependencies because
                     * they are _expected_ to change.
                     */
-                   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
+                   if (meta_ignore(gn, p))
                        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.
                     * Check if it's not an absolute path.
@@ -1204,11 +1388,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;
 
@@ -1217,7 +1406,7 @@ meta_oodate(GNode *gn, Boolean oodate)
                            if (DEBUG(META))
                                fprintf(debug_file, "%s: %d: looking for: %s\n", fname, lineno, *sdp);
 #endif
-                           if (stat(*sdp, &fs) == 0) {
+                           if (cached_stat(*sdp, &fs) == 0) {
                                found = 1;
                                p = *sdp;
                            }
@@ -1234,7 +1423,7 @@ meta_oodate(GNode *gn, Boolean oodate)
                                oodate = TRUE;
                            } else if (S_ISDIR(fs.st_mode)) {
                                /* Update the latest directory. */
-                               realpath(p, latestdir);
+                               cached_realpath(p, latestdir);
                            }
                        } else if (errno == ENOENT && *p == '/' &&
                                   strncmp(p, cwd, cwdlen) != 0) {
@@ -1242,11 +1431,14 @@ meta_oodate(GNode *gn, Boolean oodate)
                             * A referenced file outside of CWD is missing.
                             * We cannot catch every eventuality here...
                             */
-                           if (DEBUG(META))
-                               fprintf(debug_file, "%s: %d: file '%s' may have moved?...\n", fname, lineno, p);
-                           oodate = TRUE;
+                           if (Lst_Find(missingFiles, p, string_match) == NULL)
+                                   Lst_AtEnd(missingFiles, bmake_strdup(p));
                        }
                    }
+                   if (buf[0] == 'E') {
+                       /* previous latestdir is no longer relevant */
+                       strlcpy(latestdir, lcwd, sizeof(latestdir));
+                   }
                    break;
                default:
                    break;
@@ -1278,7 +1470,7 @@ meta_oodate(GNode *gn, Boolean oodate)
                        if (DEBUG(META))
                            fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
                    }
-                   cmd = Var_Subst(NULL, cmd, gn, TRUE);
+                   cmd = Var_Subst(NULL, cmd, gn, VARF_WANTRES|VARF_UNDEFERR);
 
                    if ((cp = strchr(cmd, '\n'))) {
                        int n;
@@ -1340,15 +1532,33 @@ meta_oodate(GNode *gn, Boolean oodate)
                fprintf(debug_file, "%s: missing files: %s...\n",
                        fname, (char *)Lst_Datum(Lst_First(missingFiles)));
            oodate = TRUE;
-           Lst_Destroy(missingFiles, (FreeProc *)free);
        }
-    } else {
-       if ((gn->type & OP_META)) {
+       if (!oodate && !have_filemon && filemonMissing) {
            if (DEBUG(META))
-               fprintf(debug_file, "%s: required but missing\n", fname);
+               fprintf(debug_file, "%s: missing filemon data\n", fname);
            oodate = TRUE;
        }
+    } else {
+       if (writeMeta && metaMissing) {
+           cp = NULL;
+
+           /* if target is in .CURDIR we do not need a meta file */
+           if (gn->path && (cp = strrchr(gn->path, '/')) && cp > gn->path) {
+               if (strncmp(curdir, gn->path, (cp - gn->path)) != 0) {
+                   cp = NULL;          /* not in .CURDIR */
+               }
+           }
+           if (!cp) {
+               if (DEBUG(META))
+                   fprintf(debug_file, "%s: required but missing\n", fname);
+               oodate = TRUE;
+               needOODATE = TRUE;      /* assume the worst */
+           }
+       }
     }
+
+    Lst_Destroy(missingFiles, (FreeProc *)free);
+
     if (oodate && needOODATE) {
        /*
         * Target uses .OODATE which is empty; or we wouldn't be here.
@@ -1357,8 +1567,12 @@ meta_oodate(GNode *gn, Boolean oodate)
         */
        Var_Delete(OODATE, gn);
        Var_Set(OODATE, Var_Value(ALLSRC, gn, &cp), gn, 0);
-       if (cp)
-           free(cp);
+       free(cp);
+    }
+
+ oodate_out:
+    for (i--; i >= 0; i--) {
+       free(pa[i]);
     }
     return oodate;
 }
@@ -1385,8 +1599,8 @@ meta_compat_start(void)
     if (pipe(childPipe) < 0)
        Punt("Cannot create pipe: %s", strerror(errno));
     /* Set close-on-exec flag for both */
-    (void)fcntl(childPipe[0], F_SETFD, 1);
-    (void)fcntl(childPipe[1], F_SETFD, 1);
+    (void)fcntl(childPipe[0], F_SETFD, FD_CLOEXEC);
+    (void)fcntl(childPipe[1], F_SETFD, FD_CLOEXEC);
 }
 
 void
@@ -1411,6 +1625,7 @@ meta_compat_parent(void)
     while (fgets(buf, sizeof(buf), fp)) {
        meta_job_output(NULL, buf, "");
        printf("%s", buf);
+       fflush(stdout);
     }
     fclose(fp);
 }
index 57c73ca..8f1018e 100644 (file)
@@ -1,4 +1,4 @@
-/*      $NetBSD: meta.h,v 1.3 2013/03/23 05:31:29 sjg Exp $ */
+/*      $NetBSD: meta.h,v 1.5 2016/05/12 20:28:34 sjg Exp $ */
 
 /*
  * Things needed for 'meta' mode.
@@ -42,13 +42,14 @@ extern Boolean useMeta;
 
 struct Job;                            /* not defined yet */
 void meta_init(void);
+void meta_finish(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);
 void meta_job_output(struct Job *, char *, const char *);
-void meta_cmd_finish(void *);
-void meta_job_finish(struct Job *);
+int  meta_cmd_finish(void *);
+int  meta_job_finish(struct Job *);
 Boolean meta_oodate(GNode *, Boolean);
 void meta_compat_start(void);
 void meta_compat_child(void);
diff --git a/contrib/bmake/metachar.c b/contrib/bmake/metachar.c
new file mode 100644 (file)
index 0000000..4960338
--- /dev/null
@@ -0,0 +1,88 @@
+/*     $NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $     */
+
+/*-
+ * Copyright (c) 2015 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#if defined(MAKE_NATIVE) || defined(HAVE_NBTOOL_CONFIG_H)
+#include <sys/cdefs.h>
+#endif
+
+#if defined(__RCSID) && !defined(lint)
+__RCSID("$NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $");
+#endif
+
+#include "metachar.h"
+/*
+ * The following array is used to make a fast determination of which
+ * characters are interpreted specially by the shell.  If a command
+ * contains any of these characters, it is executed by the shell, not
+ * directly by us.
+ *
+ * perhaps move it to ctype?
+ */
+
+unsigned char _metachar[128] = {
+//    nul   soh   stx   etx   eot   enq   ack   bel
+       1,    0,    0,    0,    0,    0,    0,    0,
+//     bs    ht    nl    vt    np    cr    so    si
+       0,    0,    1,    0,    0,    0,    0,    0,
+//    dle   dc1   dc2   dc3   dc4   nak   syn   etb
+       0,    0,    0,    0,    0,    0,    0,    0,
+//    can    em   sub   esc    fs    gs    rs    us
+       0,    0,    0,    0,    0,    0,    0,    0,
+//     sp     !     "     #     $     %     &     '
+       0,    1,    1,    1,    1,    0,    1,    1,
+//      (     )     *     +     ,     -     .     /
+       1,    1,    1,    0,    0,    0,    0,    0,
+//      0     1     2     3     4     5     6     7
+       0,    0,    0,    0,    0,    0,    0,    0,
+//      8     9     :     ;     <     =     >     ?
+       0,    0,    0,    1,    1,    0,    1,    1,
+//      @     A     B     C     D     E     F     G
+       0,    0,    0,    0,    0,    0,    0,    0,
+//      H     I     J     K     L     M     N     O
+       0,    0,    0,    0,    0,    0,    0,    0,
+//      P     Q     R     S     T     U     V     W
+       0,    0,    0,    0,    0,    0,    0,    0,
+//      X     Y     Z     [     \     ]     ^     _
+       0,    0,    0,    1,    1,    1,    1,    0,
+//      `     a     b     c     d     e     f     g
+       1,    0,    0,    0,    0,    0,    0,    0,
+//      h     i     j     k     l     m     n     o
+       0,    0,    0,    0,    0,    0,    0,    0,
+//      p     q     r     s     t     u     v     w
+       0,    0,    0,    0,    0,    0,    0,    0,
+//      x     y     z     {     |     }     ~   del
+       0,    0,    0,    1,    1,    1,    1,    0,
+};
+
similarity index 51%
copy from contrib/bmake/dirname.c
copy to contrib/bmake/metachar.h
index 8b6b6c3..db88d67 100644 (file)
@@ -1,11 +1,11 @@
-/*     $NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $     */
+/*     $NetBSD: metachar.h,v 1.4 2015/06/21 20:26:02 christos Exp $    */
 
 /*-
- * Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 2015 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Klaus Klein and Jason R. Thorpe.
+ * by Christos Zoulas.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+#ifndef _METACHAR_H
+#define _METACHAR_H
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#ifndef HAVE_DIRNAME
+#include <ctype.h>
 
-#include <sys/cdefs.h>
+extern unsigned char _metachar[];
 
-#ifdef HAVE_LIMITS_H
-#include <limits.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifndef PATH_MAX
-# define PATH_MAX 1024
-#endif
+#define ismeta(c)      _metachar[(c) & 0x7f]
 
-char *
-dirname(char *path)
+static inline int
+hasmeta(const char *cmd)
 {
-       static char result[PATH_MAX];
-       const char *lastp;
-       size_t len;
+       while (!ismeta(*cmd))
+               cmd++;
 
-       /*
-        * If `path' is a null pointer or points to an empty string,
-        * return a pointer to the string ".".
-        */
-       if ((path == NULL) || (*path == '\0'))
-               goto singledot;
-
-
-       /* Strip trailing slashes, if any. */
-       lastp = path + strlen(path) - 1;
-       while (lastp != path && *lastp == '/')
-               lastp--;
-
-       /* Terminate path at the last occurence of '/'. */
-       do {
-               if (*lastp == '/') {
-                       /* Strip trailing slashes, if any. */
-                       while (lastp != path && *lastp == '/')
-                               lastp--;
-
-                       /* ...and copy the result into the result buffer. */
-                       len = (lastp - path) + 1 /* last char */;
-                       if (len > (PATH_MAX - 1))
-                               len = PATH_MAX - 1;
-
-                       memcpy(result, path, len);
-                       result[len] = '\0';
-
-                       return (result);
-               }
-       } while (--lastp >= path);
+       return *cmd != '\0';
+}
 
-       /* No /'s found, return a pointer to the string ".". */
-singledot:
-       result[0] = '.';
-       result[1] = '\0';
+static inline int
+needshell(const char *cmd, int white)
+{
+       while (!ismeta(*cmd) && *cmd != ':' && *cmd != '=') {
+               if (white && isspace((unsigned char)*cmd))
+                       break;
+               cmd++;
+       }
 
-       return (result);
+       return *cmd != '\0';
 }
-#endif
+
+#endif /* _METACHAR_H */
index 497141a..483928d 100644 (file)
@@ -1,3 +1,316 @@
+2016-08-15  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160815
+
+       * dirdeps.mk (.MAKE.META.IGNORE_FILTER): set filter to only
+       consider Makefile.depend* when checking if DIRDEPS_CACHE is up-to-date.
+
+2016-08-13  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * meta.sys.mk (.MAKE.META.IGNORE_PATHS): 
+         in meta mode we can ignore the mtime of makefiles
+
+2016-08-02  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160802
+       
+       * lib.mk (libinstall): depends on beforinstall
+
+       * prog.mk (proginstall): depends on beforinstall
+         patch from Lauri Tirkkonen
+       
+       * dirdeps.mk (bootstrap): When bootstrapping; creat
+       .MAKE.DEPENDFILE_DEFAULT and allow additional filtering via
+       .MAKE.DEPENDFILE_BOOTSTRAP_SED
+
+       * dirdeps.mk: move some comments to where they make sense.
+
+2016-07-27  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * dirdeps.mk (DIRDEPS_CACHE): no dirname.
+
+2016-06-02  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160602
+       * meta.autodep.mk: when passing META_FILES to gendirdeps.mk
+         do not apply :T to META_XTRAS
+         patch from Bryan Drewery at FreeBSD.org.
+
+2016-05-30  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160530
+       * meta.stage.mk: we assume ${CLEANFILES} gets .NOPATH
+         make it so.
+       
+2016-05-12  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160512
+
+       * dpadd.mk: always include local.dpadd.mk if it exists
+         remove some things that better belong in local.dpadd.mk
+         skip INCLUDES_* for staged libs unless SRC_* defined.
+
+       * own.mk: add INCLUDEDIR
+       
+2016-04-18  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * dirdeps.mk: when doing -f dirdeps.mk if target suppies no
+         TARGET_MACHINE - :E will be empty or match part of path, use
+         ${MACHINE}
+
+2016-04-07  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * meta.autodep.mk: issue a warning if UPDATE_DEPENDFILE=NO due to
+         NO_FILEMON_COOKIE  
+
+       * dirdeps.mk: move the logic that allows for 
+         make -f dirdeps.mk some/dir.${TARGET_SPEC}
+         inside the check for !target(_DIRDEP_USE)
+
+2016-04-04  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * Use <> when including local*.mk and others which may exist
+         elsewhere so that user can better control what they get.
+       
+       * meta.autodep.mk (NO_FILEMON_COOKIE): 
+         create a cookie if we ever build dir with nofilemon
+         so that UPDATE_DEPENDFILE will be forced to NO until cleaned.
+
+2016-04-01  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160401
+       
+       * meta2deps.py: fix old print statement when debugging.
+
+       * gendirdeps.mk: META2DEPS_CMD append M2D_EXCLUDES with -X
+         patch from Bryan Drewery
+
+2016-03-22  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160317 (St. Pats)
+       
+       * warnings.mk: g++ does not like -Wimplicit
+       
+       * sys.mk sys/*.mk lib.mk prog.mk: use CXX_SUFFIXES to handle the
+         pelthora of common suffixes for C++
+       
+       * lib.mk: use .So for shared objects
+
+2016-03-15  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160315
+
+       * meta.stage.mk (LN_CP_SCRIPT): do not ln(1) if we have to chmod(1)
+         normally only applies to scripts.
+       
+       * dirdeps.mk: NO_DIRDEPS_BELOW to supress DIRDEPS below RELDIR as
+         well as outside it. 
+
+2016-03-10  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160310
+
+       * dirdeps.mk: use targets rather than a list to track DIRDEPS that
+         we have processed; the list gets very inefficient as number of
+         DIRDEPS gets large.
+
+       * sys.dependfile.mk: fix comment wrt MACHINE
+
+       * meta.autodep.mk: ignore staged DPADDs when bootstrapping.
+         patch from Bryan Drewery
+
+2016-03-02  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * meta2deps.sh: don't ignore subdirs.
+         patch from Bryan Drewery
+
+2016-02-26  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160226
+
+       * gendirdeps.mk: mark _DEPENDFILE .NOMETA
+
+2016-02-20  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * dirdeps.mk: we shouldn't normally include .depend but if we do
+         use .dinclude if we can.
+
+2016-02-18  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20160218
+       * sys.clean-env.mk: with recent change to Var_Subst()
+         we cannot use the '$$' trick, but .export-literal does the job
+         we need.
+       * auto.dep.mk: make use .dinclude if we can.
+       
+
+2016-02-05  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * dirdeps.mk: 
+         Add _build_all_dirs such that local.dirdeps.mk can
+         add fully qualified dirs to it.
+         These will be built normally but the current 
+         DEP_RELDIR will not depend on then (to avoid cycles).
+         This makes it easy to hook things like unit-tests into build.
+       
+
+2016-01-21  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * dirdeps.mk: add bootstrap-empty
+
+2015-12-12  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20151212
+       * auto.obj.mk: do not require MAKEOBJDIRPREFIX to exist.
+         only apply :tA to __objdir when comparing to .OBJDIR
+
+2015-11-14  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20151111
+
+       * meta.sys.mk: include sys.dependfile.mk
+
+       * sys.mk (OPTIONS_DEFAULT_NO): use options.mk
+         to set MK_AUTO_OBJ and MK_DIRDEPS_BUILD
+         include local.sys.env.mk early
+         include local.sys.mk later
+       
+       * own.mk (OPTIONS_DEFAULT_NO): AUTO_OBJ etc moved to sys.mk
+
+2015-11-13  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * meta.sys.mk (META_COOKIE_TOUCH):
+         add ${META_COOKIE_TOUCH} to the end of scripts to touch cookie
+
+       * meta.stage.mk: stage_libs should ignore SYMLINKS.
+
+2015-10-23  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20151022
+
+       * sys.mk: BSD/OS does not have 'type' as a shell builtin.
+
+2015-10-20  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20151020
+       
+       * dirdeps.mk: Add logic for 
+         make -f dirdeps.mk some/dir.${TARGET_SPEC}
+
+2015-10-14  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20151010
+
+2015-10-02  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * meta.stage.mk: use staging: ${STAGE_TARGETS:...
+         to have stage_lins run last in non-jobs mode.
+         Use .ORDER only for jobs mode.
+
+2015-09-02  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * rst2htm.mk: allow for per target flags etc.
+
+2015-09-01  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150901
+
+       * doc.mk: create dir if needed use DOC_INSTALL_OWN
+
+2015-06-15  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150615
+       
+       * auto.obj.mk: allow use of MAKEOBJDIRPREFIX too.
+         Follow make's normal precedence rules.
+       
+       * gendirdeps.mk: allow customization of the header.
+         eg. for FreeBSD: 
+         GENDIRDEPS_HEADER= echo '\# ${FreeBSD:L:@v@$$$v$$ @:M*F*}';
+
+       * meta.autodep.mk: ignore dirdeps.cache*
+       
+       * meta.stage.mk: when bootstrapping options it can be handy to
+         throw warnings rather than errors for staging conflicts.
+
+       * meta.sys.mk: include local.meta.sys.mk for customization
+
+2015-06-06  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150606
+       
+       * dirdeps.mk: don't rely on manually maintained Makefile.depend
+         to set DEP_RELDIR and reset DIRDEPS.
+         By setting DEP_RELDIR ourselves we can skip :tA
+       
+       * gendirdeps.mk: skip setting DEP_RELDIR.
+
+2015-05-24  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * dirdeps.mk: avoid wildcards like make(bootstrap*)
+
+2015-05-20  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150520
+
+       * dirdeps.mk: when we are building dirdeps cache file we *want*
+         meta_oodate to look at all the Makefile.depend files, so
+         set .MAKE.DEPENDFILE to something that won't match.
+
+       * meta.stage.mk: for STAGE_AS_* basename of file may not be unique
+         so first use absolute path as key.
+         Also skip staging at level 0. 
+
+2015-04-30  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150430
+       
+       * dirdeps.mk: fix _count_dirdeps for non-cache case.
+
+2015-04-16  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150411
+         bump version
+       
+       * own.mk: put AUTO_OBJ in OPTIONS_DEFAULT_NO rather than YES.
+         it is here mainly for documentation purposes, since
+         if using auto.obj.mk it is better done via sys.mk
+
+2015-04-01  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150401
+       
+       * meta2deps.sh: support @list
+       
+       * meta2deps.py: updates from Juniper
+         o add EXCLUDES 
+         o skip bogus input files.
+         o treat 'M' and 'L' as both an 'R' and a 'W'
+
+2015-03-03  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20150303
+       
+       * dirdeps.mk: if MK_DIRDEPS_CACHE is yes, use dirdeps-cache
+         which is built via sub-make so we have a .meta file to tell if
+         it is out-of-date. 
+         The dirdeps-cache contains the same dependency rules that we
+         normaly construct on the fly.
+         This adds a few seconds overhead when the cache is out of date,
+         but for a large target, the savings can be significant (10-20min).
+
+2014-11-18  Simon J. Gerraty  <sjg@bad.crufty.net>
+
+       * install-mk (MK_VERSION): 20141118
+       
+       * meta.stage.mk: add stale_staged
+       
+       * dirdeps.mk (_DIRDEP_USE_LEVEL): allow this to be tweaked
+         only useful under very rare conditions such as
+         FreeBSD's make universe.
+
+       * auto.obj.mk: Allow MK_AUTO_OBJ to set MKOBJDIRS=auto
+       
 2014-11-11  Simon J. Gerraty  <sjg@bad.crufty.net>
 
        * install-mk (MK_VERSION): 20141111
          needed.
        * gendirdeps.mk: only produce unqualified deps if no
          .MAKE.DEPENDFILE_PREFERENCE ends in .${MACHINE}
-       * meta.subdir.mk: apply SUBDIREPS_FILTER
+       * meta.subdir.mk: apply SUBDIRDEPS_FILTER
        
 2012-04-20  Simon J. Gerraty  <sjg@bad.crufty.net>
 
index 3313724..55b2971 100644 (file)
@@ -1,6 +1,6 @@
 #
 # RCSid:
-#      $Id: auto.dep.mk,v 1.3 2014/08/04 05:19:10 sjg Exp $
+#      $Id: auto.dep.mk,v 1.5 2016/04/05 15:58:37 sjg Exp $
 #
 #      @(#) Copyright (c) 2010, Simon J. Gerraty
 #
@@ -45,6 +45,7 @@ CXXFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
 
 CLEANFILES += .depend ${.MAKE.DEPENDFILE} *.d
 
+.if ${MAKE_VERSION} < 20160218
 # skip generating dependfile for misc targets
 .if ${.TARGETS:Uall:M*all} != ""
 .END:  ${.MAKE.DEPENDFILE}
@@ -60,5 +61,14 @@ ${.MAKE.DEPENDFILE}: ${OBJS} ${POBJS} ${SOBJS}
        -@for f in ${.ALLSRC:M*o:T:O:u:%=%.d}; do \
                echo ".-include \"$$f\""; \
        done > $@
+.else
+# we have .dinclude
+.if empty(_SKIP_BUILD)
+_all_objs = ${OBJS} ${POBJS} ${SOBJS}
+.for d in ${_all_objs:M*o:T:O:u:%=%.d}
+.dinclude <$d>
+.endfor
+.endif
 
 .endif
+.endif
index adccd4b..2395f64 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: auto.obj.mk,v 1.8 2011/08/08 17:35:20 sjg Exp $
+# $Id: auto.obj.mk,v 1.12 2015/12/16 01:57:06 sjg Exp $
 #
 #      @(#) Copyright (c) 2004, Simon J. Gerraty
 #
@@ -34,11 +34,18 @@ Mkdirs= Mkdirs() { \
 # if MKOBJDIRS is set to auto (and NOOBJ isn't defined) do some magic...
 # This will automatically create objdirs as needed.
 # Skip it if we are just doing 'clean'.
+.if ${MK_AUTO_OBJ:Uno} == "yes"
+MKOBJDIRS= auto
+.endif
 .if !defined(NOOBJ) && !defined(NO_OBJ) && ${MKOBJDIRS:Uno} == auto
 # Use __objdir here so it is easier to tweak without impacting
 # the logic.
-__objdir?= ${MAKEOBJDIR}
-.if ${.OBJDIR} != ${__objdir}
+.if !empty(MAKEOBJDIRPREFIX)
+__objdir?= ${MAKEOBJDIRPREFIX}${.CURDIR}
+.endif
+__objdir?= ${MAKEOBJDIR:Uobj}
+__objdir:= ${__objdir}
+.if ${.OBJDIR:tA} != ${__objdir:tA}
 # We need to chdir, make the directory if needed
 .if !exists(${__objdir}/) && \
        (${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "")
@@ -49,8 +56,8 @@ __objdir_made != echo ${__objdir}/; umask ${OBJDIR_UMASK:U002}; \
 .endif
 # This causes make to use the specified directory as .OBJDIR
 .OBJDIR: ${__objdir}
-.if ${.OBJDIR} != ${__objdir} && ${__objdir_made:Uno:M${__objdir}/*} != ""
-.error could not use ${__objdir}
+.if ${.OBJDIR:tA} != ${__objdir:tA} && ${__objdir_made:Uno:M${__objdir}/*} != ""
+.error could not use ${__objdir}: .OBJDIR=${.OBJDIR}
 .endif
 .endif
 .endif
index 84dea81..7ed4c39 100644 (file)
@@ -1,6 +1,6 @@
 #
 # RCSid:
-#      $Id: autodep.mk,v 1.34 2014/08/04 05:12:27 sjg Exp $
+#      $Id: autodep.mk,v 1.36 2016/04/05 15:58:37 sjg Exp $
 #
 #      @(#) Copyright (c) 1999-2010, Simon J. Gerraty
 #
@@ -25,7 +25,11 @@ __${.PARSEFILE}__:
 DEPENDFILE?= .depend
 .for d in ${DEPENDFILE:N.depend}
 # bmake only groks .depend
-.-include "$d"
+.if ${MAKE_VERSION} < 20160218
+.-include <$d>
+.else
+.dinclude <$d>
+.endif
 .endfor
 
 # it does nothing if SRCS is not defined or is empty
@@ -75,6 +79,9 @@ CXXFLAGS_MD=${CXXFLAGS:M-[IUD]*} ${CPPFLAGS}
 CC_MD?=${CC}
 CXX_MD?=${CXX}
 
+# should have been set by sys.mk
+CXX_SUFFIXES?= .cc .cpp .cxx .C
+
 # so we can do an explicit make depend, but not otherwise
 .if make(depend)
 .SUFFIXES:     .d
@@ -100,7 +107,7 @@ CXX_MD?=${CXX}
        @echo updating dependencies for $<
        @${SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} ${AINC} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
 
-.cc.d .cpp.d .C.d .cxx.d:
+${CXX_SUFFIXES:%=%.d}:
        @echo updating dependencies for $<
        @${SHELL} -ec "${CXX_MD} -M ${CXXFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
 .else
@@ -120,7 +127,7 @@ CXX_MD?=${CXX}
 .s.d .S.d:
        ${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} ${AINC} $< > $@ || { ${RM} -f $@; false; }
 
-.cc.d .cpp.d .C.d .cxx.d:
+${CXX_SUFFIXES:%=%.d}:
        ${CXX_MD} ${CFLAGS_MD:S/D//} ${CXXFLAGS_MD} $< > $@ || { ${RM} -f $@; false; }
 .endif
 
index 395c519..5b0de3d 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: dirdeps.mk,v 1.37 2014/10/15 06:31:43 sjg Exp $
+# $Id: dirdeps.mk,v 1.73 2016/08/15 19:28:13 sjg Exp $
 
 # Copyright (c) 2010-2013, Juniper Networks, Inc.
 # All rights reserved.
 #              TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
 #      
 
-.if ${.MAKE.LEVEL} == 0
+# touch this at your peril
+_DIRDEP_USE_LEVEL?= 0
+.if ${.MAKE.LEVEL} == ${_DIRDEP_USE_LEVEL}
 # only the first instance is interested in all this
 
-# First off, we want to know what ${MACHINE} to build for.
-# This can be complicated if we are using a mixture of ${MACHINE} specific
-# and non-specific Makefile.depend*
-
 .if !target(_DIRDEP_USE)
+
 # do some setup we only need once
 _CURDIR ?= ${.CURDIR}
+_OBJDIR ?= ${.OBJDIR}
+
+now_utc = ${%s:L:gmtime}
+.if !defined(start_utc)
+start_utc := ${now_utc}
+.endif
+
+.if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != ""
+# This little trick let's us do
+#
+# mk -f dirdeps.mk some/dir.${TARGET_SPEC}
+#
+all:
+${.TARGETS:Nall}: all
+DIRDEPS := ${.TARGETS:M*[/.]*}
+# so that -DNO_DIRDEPS works
+DEP_RELDIR := ${DIRDEPS:[1]:R}
+# this will become DEP_MACHINE below
+TARGET_MACHINE := ${DIRDEPS:[1]:E:C/,.*//}
+.if ${TARGET_MACHINE:N*/*} == ""
+TARGET_MACHINE := ${MACHINE}
+.endif
+# disable DIRDEPS_CACHE as it does not like this trick
+MK_DIRDEPS_CACHE = no
+.endif
+
+# make sure we get the behavior we expect
+.MAKE.SAVE_DOLLARS = no
 
 # make sure these are empty to start with
 _DEP_TARGET_SPEC =
-_DIRDEP_CHECKED =
 
 # If TARGET_SPEC_VARS is other than just MACHINE
 # it should be set by sys.mk or similar by now.
@@ -193,6 +219,10 @@ N_notmachine := ${.MAKE.DEPENDFILE_PREFERENCE:E:N*${MACHINE}*:${M_ListToSkip}}
 
 .endif                         # !target(_DIRDEP_USE)
 
+# First off, we want to know what ${MACHINE} to build for.
+# This can be complicated if we are using a mixture of ${MACHINE} specific
+# and non-specific Makefile.depend*
+
 # if we were included recursively _DEP_TARGET_SPEC should be valid.
 .if empty(_DEP_TARGET_SPEC)
 # we may or may not have included a dependfile yet
@@ -214,7 +244,7 @@ _DEP_TARGET_SPEC = ${_last_dependfile:${M_dep_qual_fixes:ts:}:E}
 .endif
 .if !empty(_last_dependfile)
 # record that we've read dependfile for this
-_DIRDEP_CHECKED += ${_CURDIR}.${TARGET_SPEC}
+_dirdeps_checked.${_CURDIR}.${TARGET_SPEC}:
 .endif
 .endif
 
@@ -234,10 +264,8 @@ DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
 DEP_MACHINE := ${_DEP_TARGET_SPEC}
 .endif
 
-# pickup customizations
-# as below you can use !target(_DIRDEP_USE) to protect things
-# which should only be done once.
-.-include "local.dirdeps.mk"
+# reset each time through
+_build_all_dirs =
 
 # the first time we are included the _DIRDEP_USE target will not be defined
 # we can use this as a clue to do initialization and other one time things.
@@ -257,6 +285,14 @@ DEBUG_DIRDEPS ?= no
 # remember the initial value of DEP_RELDIR - we test for it below.
 _DEP_RELDIR := ${DEP_RELDIR}
 
+.endif
+
+# pickup customizations
+# as below you can use !target(_DIRDEP_USE) to protect things
+# which should only be done once.
+.-include <local.dirdeps.mk>
+
+.if !target(_DIRDEP_USE)
 # things we skip for host tools
 SKIP_HOSTDIR ?=
 
@@ -274,9 +310,17 @@ DEP_SKIP_DIR = ${SKIP_DIR} \
 
 NSkipDir = ${DEP_SKIP_DIR:${M_ListToSkip}}
 
-.if defined(NO_DIRDEPS) || defined(NODIRDEPS) || defined(WITHOUT_DIRDEPS)
-# confine ourselves to the original dir
+.if defined(NODIRDEPS) || defined(WITHOUT_DIRDEPS)
+NO_DIRDEPS =
+.elif defined(WITHOUT_DIRDEPS_BELOW)
+NO_DIRDEPS_BELOW =
+.endif
+
+.if defined(NO_DIRDEPS)
+# confine ourselves to the original dir and below.
 DIRDEPS_FILTER += M${_DEP_RELDIR}*
+.elif defined(NO_DIRDEPS_BELOW)
+DIRDEPS_FILTER += M${_DEP_RELDIR}
 .endif
 
 # this is what we run below
@@ -332,6 +376,74 @@ _only_machines := ${_only_machines:${NOT_MACHINE_LIST:${M_ListToSkip}}}
 DIRDEPS ?= ${RELDIR}
 .endif                         # target 
 
+# if repeatedly building the same target, 
+# we can avoid the overhead of re-computing the tree dependencies.
+MK_DIRDEPS_CACHE ?= no
+BUILD_DIRDEPS_CACHE ?= no
+BUILD_DIRDEPS ?= yes
+
+.if !defined(NO_DIRDEPS) && !defined(NO_DIRDEPS_BELOW)
+.if ${MK_DIRDEPS_CACHE} == "yes"
+# this is where we will cache all our work
+DIRDEPS_CACHE?= ${_OBJDIR:tA}/dirdeps.cache${.TARGETS:Nall:O:u:ts-:S,/,_,g:S,^,.,:N.}
+
+# just ensure this exists
+build-dirdeps:
+
+M_oneperline = @x@\\${.newline}        $$x@
+
+.if ${BUILD_DIRDEPS_CACHE} == "no" 
+.if !target(dirdeps-cached)
+# we do this via sub-make
+BUILD_DIRDEPS = no
+
+# ignore anything but these
+.MAKE.META.IGNORE_FILTER = M*/${.MAKE.DEPENDFILE_PREFIX}*
+
+dirdeps: dirdeps-cached
+dirdeps-cached:        ${DIRDEPS_CACHE} .MAKE
+       @echo "${TRACER}Using ${DIRDEPS_CACHE}"
+       @MAKELEVEL=${.MAKE.LEVEL} ${.MAKE} -C ${_CURDIR} -f ${DIRDEPS_CACHE} \
+               dirdeps MK_DIRDEPS_CACHE=no BUILD_DIRDEPS=no
+
+# these should generally do
+BUILD_DIRDEPS_MAKEFILE ?= ${MAKEFILE}
+BUILD_DIRDEPS_TARGETS ?= ${.TARGETS}
+
+# we need the .meta file to ensure we update if 
+# any of the Makefile.depend* changed.
+# We do not want to compare the command line though.
+${DIRDEPS_CACHE}:      .META .NOMETA_CMP
+       +@{ echo '# Autogenerated - do NOT edit!'; echo; \
+       echo 'BUILD_DIRDEPS=no'; echo; \
+       echo '.include <dirdeps.mk>'; \
+       } > ${.TARGET}.new
+       +@MAKELEVEL=${.MAKE.LEVEL} DIRDEPS_CACHE=${DIRDEPS_CACHE} \
+       DIRDEPS="${DIRDEPS}" \
+       MAKEFLAGS= ${.MAKE} -C ${_CURDIR} -f ${BUILD_DIRDEPS_MAKEFILE} \
+       ${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \
+       .MAKE.DEPENDFILE=.none \
+       ${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \
+       3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \
+       mv ${.TARGET}.new ${.TARGET}
+
+.endif
+.elif !target(_count_dirdeps)
+# we want to capture the dirdeps count in the cache
+.END: _count_dirdeps
+_count_dirdeps: .NOMETA
+       @echo '.info $${.newline}$${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]}' >&3
+
+.endif
+.elif !make(dirdeps) && !target(_count_dirdeps)
+beforedirdeps: _count_dirdeps
+_count_dirdeps: .NOMETA
+       @echo "${TRACER}Makefiles read: total=${.MAKE.MAKEFILES:[#]} depend=${.MAKE.MAKEFILES:M*depend*:[#]} dirdeps=${.ALLTARGETS:M${SRCTOP}*:O:u:[#]} seconds=`expr ${now_utc} - ${start_utc}`"
+
+.endif
+.endif
+
+.if ${BUILD_DIRDEPS} == "yes"
 .if ${DEBUG_DIRDEPS:@x@${DEP_RELDIR:M$x}${${DEP_RELDIR}.${DEP_MACHINE}:L:M$x}@} != ""
 _debug_reldir = 1
 .else
@@ -355,7 +467,7 @@ _this_dir := ${SRCTOP}/${DEP_RELDIR}
 
 # on rare occasions, there can be a need for extra help
 _dep_hack := ${_this_dir}/${.MAKE.DEPENDFILE_PREFIX}.inc
-.-include "${_dep_hack}"
+.-include <${_dep_hack}>
 
 .if ${DEP_RELDIR} != ${_DEP_RELDIR} || ${DEP_TARGET_SPEC} != ${TARGET_SPEC}
 # this should be all
@@ -392,7 +504,11 @@ _build_dirs += ${_machines:@m@${_CURDIR}.$m@}
 _build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@}
 .if ${DEP_TARGET_SPEC} == ${TARGET_SPEC}
 # pickup local dependencies now
+.if ${MAKE_VERSION} < 20160220
 .-include <.depend>
+.else
+.dinclude <.depend>
+.endif
 .endif
 .endif
 .endif
@@ -444,16 +560,25 @@ _build_dirs += \
 # qualify everything now
 _build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
 
+_build_all_dirs += ${_build_dirs}
+_build_all_dirs := ${_build_all_dirs:O:u}
+
 .endif                         # empty DIRDEPS
 
 # Normally if doing make -V something,
 # we do not want to waste time chasing DIRDEPS
 # but if we want to count the number of Makefile.depend* read, we do.
 .if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == ""
-.if !empty(_build_dirs)
+.if !empty(_build_all_dirs)
+.if ${BUILD_DIRDEPS_CACHE} == "yes"
+x!= { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \
+       echo 'dirdeps: ${_build_all_dirs:${M_oneperline}}'; echo; } >&3; echo
+x!= { ${_build_all_dirs:@x@${target($x):?:echo '$x: _DIRDEP_USE';}@} echo; } >&3; echo
+.else
 # this makes it all happen
-dirdeps: ${_build_dirs}
-${_build_dirs}:        _DIRDEP_USE
+dirdeps: ${_build_all_dirs}
+.endif
+${_build_all_dirs}:    _DIRDEP_USE
 
 .if ${_debug_reldir}
 .info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs}
@@ -467,26 +592,34 @@ ${_build_dirs}:   _DIRDEP_USE
 .if ${_debug_reldir} || ${DEBUG_DIRDEPS:@x@${${DEP_RELDIR}.$m:L:M$x}${${DEP_RELDIR}.$q:L:M$x}@} != ""
 .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$q}
 .endif
+.if ${BUILD_DIRDEPS_CACHE} == "yes"
+x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$q:${M_oneperline}}'; echo; } >&3; echo
+.else
 ${_this_dir}.$m: ${_build_dirs:M*.$q}
+.endif
 .endfor
 .endif
 .if ${_debug_reldir}
 .info ${DEP_RELDIR}.$m: graph: ${_build_dirs:M*.$m:N${_this_dir}.$m}
 .endif
+.if ${BUILD_DIRDEPS_CACHE} == "yes"
+x!= { echo; echo '${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m:${M_oneperline}}'; echo; } >&3; echo
+.else
 ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
+.endif
 .endfor
 
 .endif
 
 # Now find more dependencies - and recurse.
-.for d in ${_build_dirs}
-.if ${_DIRDEP_CHECKED:M$d} == ""
+.for d in ${_build_all_dirs}
+.if !target(_dirdeps_checked.$d)
 # once only
-_DIRDEP_CHECKED += $d
+_dirdeps_checked.$d:
 .if ${_debug_search}
 .info checking $d
 .endif
-# Note: _build_dirs is fully qualifed so d:R is always the directory
+# Note: _build_all_dirs is fully qualifed so d:R is always the directory
 .if exists(${d:R})
 # Warning: there is an assumption here that MACHINE is always 
 # the first entry in TARGET_SPEC_VARS.
@@ -502,6 +635,11 @@ _qm := ${_m:C;(\.depend)$;\1.${d:E};:${M_dep_qual_fixes:ts:}}
 _DEP_TARGET_SPEC := ${d:E}
 # some makefiles may still look at this
 _DEP_MACHINE := ${d:E:C/,.*//}
+# set this "just in case" 
+# we can skip :tA since we computed the path above
+DEP_RELDIR := ${_m:H:S,${SRCTOP}/,,}
+# and reset this
+DIRDEPS =
 .if ${_debug_reldir} && ${_qm} != ${_m}
 .info loading ${_m} for ${d:E}
 .endif
@@ -512,34 +650,56 @@ _DEP_MACHINE := ${d:E:C/,.*//}
 .endfor
 
 .endif                         # -V
+.endif                         # BUILD_DIRDEPS
 
 .elif ${.MAKE.LEVEL} > 42
 .error You should have stopped recursing by now.
 .else
-_DEP_RELDIR := ${DEP_RELDIR}
+# we are building something
+DEP_RELDIR := ${RELDIR}
+_DEP_RELDIR := ${RELDIR}
 # pickup local dependencies
+.if ${MAKE_VERSION} < 20160220
 .-include <.depend>
+.else
+.dinclude <.depend>
+.endif
 .endif
 
 # bootstrapping new dependencies made easy?
-.if make(bootstrap*) && !target(bootstrap)
+.if !target(bootstrap) && (make(bootstrap) || \
+       make(bootstrap-this) || \
+       make(bootstrap-recurse) || \
+       make(bootstrap-empty))
+
+# if we are bootstrapping create the default
+_want = ${.CURDIR}/${.MAKE.DEPENDFILE_DEFAULT:T}
 
-.if exists(${.CURDIR}/${.MAKE.DEPENDFILE:T})
+.if exists(${_want})
 # stop here
 ${.TARGETS:Mboot*}:
-.else
+.elif !make(bootstrap-empty)
 # find a Makefile.depend to use as _src
 _src != cd ${.CURDIR} && for m in ${.MAKE.DEPENDFILE_PREFERENCE:T:S,${MACHINE},*,}; do test -s $$m || continue; echo $$m; break; done; echo
 .if empty(_src)
-.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T}
+.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T}${.newline}Use: bootstrap-empty
 .endif
 
-_src?= ${.MAKE.DEPENDFILE:T}
+_src?= ${.MAKE.DEPENDFILE}
+
+.MAKE.DEPENDFILE_BOOTSTRAP_SED+= -e 's,${_src:E},${MACHINE},g'
 
+# just create Makefile.depend* for this dir
 bootstrap-this:        .NOTMAIN
-       @echo Bootstrapping ${RELDIR}/${.MAKE.DEPENDFILE:T} from ${_src:T}
-       (cd ${.CURDIR} && sed 's,${_src:E},${MACHINE},g' ${_src} > ${.MAKE.DEPENDFILE:T})
+       @echo Bootstrapping ${RELDIR}/${_want:T} from ${_src:T}; \
+       echo You need to build ${RELDIR} to correctly populate it.
+.if ${_src:T} != ${.MAKE.DEPENDFILE_PREFIX:T}
+       (cd ${.CURDIR} && sed ${.MAKE.DEPENDFILE_BOOTSTRAP_SED} ${_src} > ${_want})
+.else
+       cp ${.CURDIR}/${_src} ${_want}
+.endif
 
+# create Makefile.depend* for this dir and its dependencies
 bootstrap: bootstrap-recurse
 bootstrap-recurse: bootstrap-this
 
@@ -554,4 +714,11 @@ bootstrap-recurse: .NOTMAIN .MAKE
        done
 
 .endif
+
+# create an empty Makefile.depend* to get the ball rolling.
+bootstrap-empty: .NOTMAIN .NOMETA
+       @echo Creating empty ${RELDIR}/${_want:T}; \
+       echo You need to build ${RELDIR} to correctly populate it.
+       @{ echo DIRDEPS=; echo ".include <dirdeps.mk>"; } > ${_want}
+
 .endif
index d496c42..d1385e9 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: doc.mk,v 1.4 2012/11/11 22:37:02 sjg Exp $
+# $Id: doc.mk,v 1.5 2015/09/08 06:15:31 sjg Exp $
 
 .if !target(__${.PARSEFILE}__)
 __${.PARSEFILE}__:
@@ -47,17 +47,19 @@ install:
 .else
 FILES?=        ${SRCS}
 install:
-       ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \
-           Makefile ${FILES} ${EXTRA} ${DESTDIR}${BINDIR}/${DIR}
+       test -d ${DESTDIR}${DOCDIR}/${DIR} || \
+           ${INSTALL} -d ${DOC_INSTALL_OWN} -m ${DIRMODE} ${DESTDIR}${DOCDIR}/${DIR}
+       ${INSTALL} ${COPY} ${DOC_INSTALL_OWN} -m ${DOCMODE} \
+           Makefile ${FILES} ${EXTRA} ${DESTDIR}${DOCDIR}/${DIR}
 .endif
 
 spell: ${SRCS}
        spell ${SRCS} | sort | comm -23 - spell.ok > paper.spell
 
-BINDIR?=       /usr/share/doc
-BINGRP?=       bin
-BINOWN?=       bin
-BINMODE?=      444
-
 .include <own.mk>
+
+.if !empty(DOCOWN)
+DOC_INSTALL_OWN?= -o ${DOCOWN} -g ${DOGGRP}
+.endif
+
 .endif
index abc92df..c789acf 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: dpadd.mk,v 1.19 2014/04/05 22:56:54 sjg Exp $
+# $Id: dpadd.mk,v 1.22 2016/05/31 23:30:59 sjg Exp $
 #
 #      @(#) Copyright (c) 2004, Simon J. Gerraty
 #
@@ -21,71 +21,91 @@ __${.PARSEFILE}__:
 _OBJDIR?= ${.OBJDIR}
 _CURDIR?= ${.CURDIR}
 
+.if ${_CURDIR} == ${SRCTOP}
+RELDIR=.
+RELTOP=.
+.else
+RELDIR?= ${_CURDIR:S,${SRCTOP}/,,}
+.if ${RELDIR} == ${_CURDIR}
+RELDIR?= ${_OBJDIR:S,${OBJTOP}/,,}
+.endif
+RELTOP?= ${RELDIR:C,[^/]+,..,g}
+.endif
+RELOBJTOP?= ${OBJTOP}
+RELSRCTOP?= ${SRCTOP}
+
+# we get included just about everywhere so this is handy...
+# C*DEBUG_XTRA are for defining on cmd line etc 
+# so do not use in makefiles.
+.ifdef CFLAGS_DEBUG_XTRA
+CFLAGS_LAST += ${CFLAGS_DEBUG_XTRA}
+.endif
+.ifdef CXXFLAGS_DEBUG_XTRA
+CXXFLAGS_LAST += ${CXXFLAGS_DEBUG_XTRA}
+.endif
+
+.-include <local.dpadd.mk>
+
 # DPLIBS helps us ensure we keep DPADD and LDADD in sync
 DPLIBS+= ${DPLIBS_LAST}
-DPADD+= ${DPLIBS}
+DPADD+= ${DPLIBS:N-*}
 .for __lib in ${DPLIBS:T:R}
-LDADD+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
+.if "${_lib:M-*}" != ""
+LDADD += ${__lib}
+.else
+LDADD += ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
+.endif
 .endfor
 
 # DPADD can contain things other than libs
-__dpadd_libs = ${DPADD:M*/lib*}
+__dpadd_libs := ${DPADD:M*/lib*}
 
 # some libs have dependencies...
 # DPLIBS_* allows bsd.libnames.mk to flag libs which must be included
 # in DPADD for a given library.
-.for __lib in ${__dpadd_libs:@d@${DPLIBS_${d:T:R}}@}
+# Gather all such dependencies into __ldadd_all_xtras
+# dups will be dealt with later.
+# Note: libfoo_pic uses DPLIBS_libfoo
+__ldadd_all_xtras=
+.for __lib in ${__dpadd_libs:@d@${DPLIBS_${d:T:R:S,_pic,,}}@}
+__ldadd_all_xtras+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
 .if "${DPADD:M${__lib}}" == ""
 DPADD+= ${__lib}
-LDADD+= ${LDADD_${__lib}:U${__lib:T:R:S/lib/-l/:C/\.so.*//}}
 .endif
 .endfor
 # Last of all... for libc and libgcc
 DPADD+= ${DPADD_LAST}
 
+# de-dupuplicate __ldadd_all_xtras into __ldadd_xtras
+# in reverse order so that libs end up listed after all that needed them.
+__ldadd_xtras=
+.for __lib in ${__ldadd_all_xtras:[-1..1]}
+.if "${__ldadd_xtras:M${__lib}}" == "" || ${NEED_IMPLICIT_LDADD:tl:Uno} != "no"
+__ldadd_xtras+= ${__lib}
+.endif
+.endfor
+
+.if !empty(__ldadd_xtras)
+# now back to the original order
+__ldadd_xtras:= ${__ldadd_xtras:[-1..1]}
+LDADD+= ${__ldadd_xtras}
+.endif
+
 # Convert DPADD into -I and -L options and add them to CPPFLAGS and LDADD
 # For the -I's convert the path to a relative one.  For separate objdirs
 # the DPADD paths will be to the obj tree so we need to subst anyway.
 
-# If USE_PROFILE is yes, then check for profiled versions of libs
-# and use them.
-
-USE_PROFILE?=no
-.if defined(LIBDL) && exists(${LIBDL})
-.if defined(PROG) && (make(${PROG}_p) || ${USE_PROFILE} == yes) && \
-       defined(LDFLAGS) && ${LDFLAGS:M-export-dynamic}
-# building profiled version of a prog that needs dlopen to work
-DPLIBS+= ${LIBDL}
-.endif
-.endif
-
-.if defined(LIBDMALLOC) && exists(${LIBDMALLOC})
-.if defined(USE_DMALLOC) && ${USE_DMALLOC} != no
-.if !defined(NO_DMALLOC)
-CPPFLAGS+= -DUSE_DMALLOC
-.endif
-DPLIBS+= ${LIBDMALLOC}
-.endif
-.endif
+# update this
+__dpadd_libs := ${DPADD:M*/lib*}
 
 # Order -L's to search ours first.
 # Avoids picking up old versions already installed.
 __dpadd_libdirs := ${__dpadd_libs:R:H:S/^/-L/g:O:u:N-L}
 LDADD += ${__dpadd_libdirs:M-L${OBJTOP}/*}
-LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*}
-
-.if ${.CURDIR} == ${SRCTOP}
-RELDIR=.
-RELTOP=.
-.else
-RELDIR?= ${.CURDIR:S,${SRCTOP}/,,}
-.if ${RELDIR} == ${.CURDIR}
-RELDIR?= ${.OBJDIR:S,${OBJTOP}/,,}
-.endif
-RELTOP?= ${RELDIR:C,[^/]+,..,g}
+LDADD += ${__dpadd_libdirs:N-L${OBJTOP}/*:N-L${HOST_LIBDIR:U/usr/lib}}
+.if defined(HOST_LIBDIR) && ${HOST_LIBDIR} != "/usr/lib"
+LDADD+= -L${HOST_LIBDIR}
 .endif
-RELOBJTOP?= ${OBJTOP}
-RELSRCTOP?= ${SRCTOP}
 
 .if !make(dpadd)
 .ifdef LIB
@@ -109,7 +129,8 @@ __dpadd_libs += ${SRC_LIBS}
 DPMAGIC_LIBS += ${__dpadd_libs} \
        ${__dpadd_libs:@d@${DPMAGIC_LIBS_${d:T:R}}@}
 
-.for __lib in ${DPMAGIC_LIBS:O:u}
+# we skip this for staged libs
+.for __lib in ${DPMAGIC_LIBS:O:u:N${STAGE_OBJTOP:Unot}*/lib/*}
 # 
 # if SRC_libfoo is not set, then we assume that the srcdir corresponding
 # to where we found the library is correct.
@@ -127,6 +148,35 @@ INCLUDES_${__lib:T:R}?= -I${exists(${SRC_${__lib:T:R}}/h):?${SRC_${__lib:T:R}}/h
 
 .endfor
 
+# even for staged libs we sometimes 
+# need to allow direct -I to avoid cicular dependencies 
+.for __lib in ${DPMAGIC_LIBS:O:u:T:R}
+.if !empty(SRC_${__lib}) && empty(INCLUDES_${__lib})
+# must be a staged lib
+.if exists(${SRC_${__lib}}/h)
+INCLUDES_${__lib} = -I${SRC_${__lib}}/h
+.else
+INCLUDES_${__lib} = -I${SRC_${__lib}}
+.endif
+.endif
+.endfor
+
+# when linking a shared lib, avoid non pic libs
+SHLDADD+= ${LDADD:N-[lL]*}
+.for __lib in ${__dpadd_libs:u}
+.if defined(SHLIB_NAME) && ${LDADD:M-l${__lib:T:R:S,lib,,}} != ""
+.if ${__lib:T:N*_pic.a:N*.so} == "" || exists(${__lib:R}.so)
+SHLDADD+= -l${__lib:T:R:S,lib,,}
+.elif exists(${__lib:R}_pic.a)
+SHLDADD+= -l${__lib:T:R:S,lib,,}_pic
+.else
+.warning ${RELDIR}.${TARGET_SPEC} needs ${__lib:T:R}_pic.a
+SHLDADD+= -l${__lib:T:R:S,lib,,}
+.endif
+SHLDADD+= -L${__lib:H}
+.endif
+.endfor
+
 # Now for the bits we actually need
 __dpadd_incs=
 .for __lib in ${__dpadd_libs:u}
@@ -134,20 +184,25 @@ __dpadd_incs=
 __ldadd=-l${__lib:T:R:S,lib,,}
 LDADD := ${LDADD:S,^${__ldadd}$,${__ldadd}_p,g}
 .endif
+.endfor
 
-#
-# Some libs generate headers, so we potentially need both
-# the src dir and the obj dir.
-# If ${INCLUDES_libfoo} contains a word ending in /h, we assume that either
-# 1. it does not generate headers or
-# 2. INCLUDES_libfoo will have been set correctly
-# XXX it gets ugly avoiding duplicates... 
-# use :? to ensure .for does not prevent correct evaluation
 #
 # We take care of duplicate suppression later.
-__dpadd_incs += ${"${INCLUDES_${__lib:T:R}:M*/h}":? :-I${OBJ_${__lib:T:R}}}
-__dpadd_incs += ${INCLUDES_${__lib:T:R}}
-.endfor
+# don't apply :T:R too early
+__dpadd_incs += ${__dpadd_libs:u:@x@${INCLUDES_${x:T:R}}@}
+__dpadd_incs += ${__dpadd_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_${x:T:R}}@}
+
+__dpadd_last_incs += ${__dpadd_libs:u:@x@${INCLUDES_LAST_${x:T:R}}@}
+__dpadd_last_incs += ${__dpadd_libs:O:u:@s@${SRC_LIBS_${s:T:R}:U}@:@x@${INCLUDES_LAST_${x:T:R}}@}
+
+.if defined(HOSTPROG) || ${MACHINE} == "host"
+# we want any -I/usr/* last
+__dpadd_last_incs := \
+       ${__dpadd_last_incs:N-I/usr/*} \
+       ${__dpadd_incs:M-I/usr/*} \
+       ${__dpadd_last_incs:M-I/usr/*} 
+__dpadd_incs := ${__dpadd_incs:N-I/usr/*}
+.endif
 
 #
 # eliminate any duplicates - but don't mess with the order
@@ -164,13 +219,21 @@ __$t_incs+= $i
 .endfor
 .endfor
 
+.for t in CFLAGS_LAST CXXFLAGS_LAST
+# avoid duplicates
+__$t_incs:=${$t:M-I*:u}
+.for i in ${__dpadd_last_incs}
+.if "${__$t_incs:M$i}" == ""
+$t+= $i
+__$t_incs+= $i
+.endif
+.endfor
+.endfor
+
 # This target is used to gather a list of
 # dir: ${DPADD}
 # entries
 .if make(*dpadd*)
-# allow overrides
-.-include "dpadd++.mk"
-
 .if !target(dpadd)
 dpadd: .NOTMAIN
 .if defined(DPADD) && ${DPADD} != ""
@@ -193,4 +256,17 @@ dpadd:     .NOTMAIN
 .PATH: ${SRC_PATHADD}
 .endif
 
+# after all that, if doing -n we don't care
+.if ${.MAKEFLAGS:Ux:M-n} != ""
+DPADD =
+.elif ${.MAKE.MODE:Mmeta*} != "" && exists(${.MAKE.DEPENDFILE})
+DPADD_CLEAR_DPADD ?= yes
+.if ${DPADD_CLEAR_DPADD} == "yes"
+# save this
+__dpadd_libs := ${__dpadd_libs}
+# we have made what use of it we can of DPADD
+DPADD =
+.endif
+.endif
+
 .endif
index 5f41189..235d36d 100644 (file)
@@ -1,10 +1,10 @@
-# $Id: final.mk,v 1.5 2011/03/11 05:22:38 sjg Exp $
+# $Id: final.mk,v 1.6 2016/04/05 15:58:37 sjg Exp $
 
 .if !target(__${.PARSEFILE}__)
 __${.PARSEFILE}__:
 
 # provide a hook for folk who want to do scary stuff
-.-include "${.CURDIR}/../Makefile-final.inc"
+.-include <${.CURDIR:H}/Makefile-final.inc>
 
 .if !empty(STAGE)
 .-include <stage.mk>
index 28e1f21..68f32be 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: gendirdeps.mk,v 1.26 2014/09/05 04:40:52 sjg Exp $
+# $Id: gendirdeps.mk,v 1.32 2016/04/05 15:58:37 sjg Exp $
 
 # Copyright (c) 2010-2013, Juniper Networks, Inc.
 # All rights reserved.
@@ -82,7 +82,7 @@ META_FILES := ${META_FILES:T:O:u}
 .export META_FILES
 
 # pickup customizations
-.-include "local.gendirdeps.mk"
+.-include <local.gendirdeps.mk>
 
 # these are actually prefixes that we'll skip
 # they should all be absolute paths
@@ -138,7 +138,8 @@ META2DEPS_CMD += -T ${TARGET_OBJ_SPEC}
 .endif
 META2DEPS_CMD += \
        -R ${RELDIR} -H ${HOST_TARGET} \
-       ${M2D_OBJROOTS:O:u:@o@-O $o@}
+       ${M2D_OBJROOTS:O:u:@o@-O $o@} \
+       ${M2D_EXCLUDES:O:u:@o@-X $o@} \
 
 
 M2D_OBJROOTS += ${OBJTOP} ${_OBJROOT} ${_objroot}
@@ -157,7 +158,7 @@ M2D_OBJROOTS += ${SB_BACKING_SB}/${SB_OBJPREFIX}
 .endif
 
 # we are only interested in the dirs
-# sepecifically those we read something from.
+# specifically those we read something from.
 # we canonicalize them to keep things simple
 # if we are using a split-fs sandbox, it gets a little messier.
 _objtop := ${_OBJTOP:tA}
@@ -255,6 +256,7 @@ DIRDEPS := ${DIRDEPS:${GENDIRDEPS_FILTER:UNno:ts:}:C,//+,/,g:O:u}
 
 .if ${DEBUG_GENDIRDEPS:Uno:@x@${RELDIR:M$x}@} != ""
 .info ${RELDIR}: M2D_OBJROOTS=${M2D_OBJROOTS}
+.info ${RELDIR}: M2D_EXCLUDES=${M2D_EXCLUDES}
 .info ${RELDIR}: dir_list='${dir_list}'
 .info ${RELDIR}: dpadd_dir_list='${dpadd_dir_list}'
 .info ${RELDIR}: dirdep_list='${dirdep_list}'
@@ -309,9 +311,8 @@ CAT_DEPEND ?= .depend
 # .depend may contain things we don't want.
 # The sed command at the end of the stream, allows for the filters
 # to output _{VAR} tokens which we will turn into proper ${VAR} references.
-${_DEPENDFILE}: ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS}
-       @(echo '# Autogenerated - do NOT edit!'; echo; \
-       echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
+${_DEPENDFILE}: .NOMETA ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS}
+       @(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \
        echo 'DIRDEPS = \'; \
        echo '${DIRDEPS:@d@     $d \\${.newline}@}'; echo; \
        ${_include_src_dirdeps} \
@@ -330,9 +331,8 @@ DIRDEPS := ${SUBDIR:S,^,${RELDIR}/,:O:u}
 
 all:   ${_DEPENDFILE}
 
-${_DEPENDFILE}: ${MAKEFILE} ${_this}
-       @(echo '# Autogenerated - do NOT edit!'; echo; \
-       echo 'DEP_RELDIR := $${_PARSEDIR:S,$${SRCTOP}/,,}'; echo; \
+${_DEPENDFILE}: .NOMETA ${MAKEFILE} ${_this}
+       @(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \
        echo 'DIRDEPS = \'; \
        echo '${DIRDEPS:@d@     $d \\${.newline}@}'; echo; \
        echo '.include <dirdeps.mk>'; \
index eacdf1d..f528db9 100644 (file)
@@ -1,5 +1,5 @@
 # RCSid:
-#      $Id: host-target.mk,v 1.7 2014/05/16 17:54:52 sjg Exp $
+#      $Id: host-target.mk,v 1.11 2015/10/25 00:07:20 sjg Exp $
 
 # Host platform information; may be overridden
 .if !defined(_HOST_OSNAME)
@@ -10,24 +10,33 @@ _HOST_OSNAME !=     uname -s
 _HOST_OSREL  !=        uname -r
 .export _HOST_OSREL
 .endif
+.if !defined(_HOST_MACHINE)
+_HOST_MACHINE != uname -m
+.export _HOST_MACHINE
+.endif
 .if !defined(_HOST_ARCH)
-_HOST_ARCH   !=        uname -p 2>/dev/null || uname -m
+# for NetBSD prefer $MACHINE (amd64 rather than x86_64)
+.if ${_HOST_OSNAME:NNetBSD} == ""
+_HOST_ARCH := ${_HOST_MACHINE}
+.else
+_HOST_ARCH != uname -p 2> /dev/null || uname -m
 # uname -p may produce garbage on linux
-.if ${_HOST_ARCH:[\#]} > 1
-_HOST_ARCH != uname -m
+.if ${_HOST_ARCH:[\#]} > 1 || ${_HOST_ARCH:Nunknown} == ""
+_HOST_ARCH := ${_HOST_MACHINE}
+.endif
 .endif
 .export _HOST_ARCH
 .endif
 .if !defined(HOST_MACHINE)
-HOST_MACHINE != uname -m
+HOST_MACHINE := ${_HOST_MACHINE}
 .export HOST_MACHINE
 .endif
 
 HOST_OSMAJOR := ${_HOST_OSREL:C/[^0-9].*//}
-HOST_OSTYPE  :=        ${_HOST_OSNAME}-${_HOST_OSREL:C/\([^\)]*\)//}-${_HOST_ARCH}
+HOST_OSTYPE  :=        ${_HOST_OSNAME:S,/,,g}-${_HOST_OSREL:C/\([^\)]*\)//}-${_HOST_ARCH}
 HOST_OS      :=        ${_HOST_OSNAME}
 host_os      :=        ${_HOST_OSNAME:tl}
-HOST_TARGET  := ${host_os}${HOST_OSMAJOR}-${_HOST_ARCH}
+HOST_TARGET  := ${host_os:S,/,,g}${HOST_OSMAJOR}-${_HOST_ARCH}
 
 # tr is insanely non-portable, accommodate the lowest common denominator
 TR ?= tr
index e700370..cb5ab82 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: init.mk,v 1.9 2013/07/18 05:46:24 sjg Exp $
+# $Id: init.mk,v 1.12 2016/04/05 15:58:37 sjg Exp $
 #
 #      @(#) Copyright (c) 2002, Simon J. Gerraty
 #
@@ -23,11 +23,14 @@ _this_mk_dir := ${.PARSEDIR}
 .endif
 
 .-include <local.init.mk>
-.-include "${.CURDIR:H}/Makefile.inc"
+.-include <${.CURDIR:H}/Makefile.inc>
 .include <own.mk>
 
 .MAIN:         all
 
+# should have been set by sys.mk
+CXX_SUFFIXES?= .cc .cpp .cxx .C
+
 .if !empty(WARNINGS_SET) || !empty(WARNINGS_SET_${MACHINE_ARCH})
 .include <warnings.mk>
 .endif
@@ -47,4 +50,8 @@ PROFFLAGS?= -DGPROF -DPROF
 _SKIP_BUILD = not building at level 0
 .endif
 
+.if !empty(_SKIP_BUILD)
+all: .PHONY
+.warning ${_SKIP_BUILD}
+.endif
 .endif
index f58f2fc..79b35e8 100644 (file)
@@ -55,7 +55,7 @@
 #       Simon J. Gerraty <sjg@crufty.net>
 
 # RCSid:
-#      $Id: install-mk,v 1.105 2014/11/11 15:55:39 sjg Exp $
+#      $Id: install-mk,v 1.130 2016/08/15 19:28:13 sjg Exp $
 #
 #      @(#) Copyright (c) 1994 Simon J. Gerraty
 #
@@ -70,7 +70,7 @@
 #      sjg@crufty.net
 #
 
-MK_VERSION=20141111
+MK_VERSION=20160815
 OWNER=
 GROUP=
 MODE=444
index 417aa02..6c25937 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: lib.mk,v 1.51 2014/05/23 01:30:36 sjg Exp $
+# $Id: lib.mk,v 1.54 2016/08/02 20:52:17 sjg Exp $
 
 .if !target(__${.PARSEFILE}__)
 __${.PARSEFILE}__:
@@ -40,8 +40,8 @@ SHLIB_FULLVERSION := ${SHLIB_FULLVERSION}
 
 # add additional suffixes not exported.
 # .po is used for profiling object files.
-# .so is used for PIC object files.
-.SUFFIXES: .out .a .ln .so .po .o .s .S .c .cc .C .m .F .f .r .y .l .cl .p .h
+# .So is used for PIC object files.
+.SUFFIXES: .out .a .ln .So .po .o .s .S .c .cc .C .m .F .f .r .y .l .cl .p .h
 .SUFFIXES: .sh .m4 .m
 
 CFLAGS+=       ${COPTS}
@@ -62,12 +62,12 @@ CFLAGS+=    ${COPTS}
 #                      with ELF, also set shared-lib version for ld.so.
 # SHLIB_LDSTARTFILE:   support .o file, call C++ file-level constructors
 # SHLIB_LDENDFILE:     support .o file, call C++ file-level destructors
-# FPICFLAGS:           flags for ${FC} to compile .[fF] files to .so objects.
+# FPICFLAGS:           flags for ${FC} to compile .[fF] files to .So objects.
 # CPPICFLAGS:          flags for ${CPP} to preprocess .[sS] files for ${AS}
-# CPICFLAGS:           flags for ${CC} to compile .[cC] files to .so objects.
+# CPICFLAGS:           flags for ${CC} to compile .[cC] files to .So objects.
 # CAPICFLAGS           flags for {$CC} to compiling .[Ss] files
 #                      (usually just ${CPPPICFLAGS} ${CPICFLAGS})
-# APICFLAGS:           flags for ${AS} to assemble .[sS] to .so objects.
+# APICFLAGS:           flags for ${AS} to assemble .[sS] to .So objects.
 
 .if ${TARGET_OSNAME} == "NetBSD"
 .if ${MACHINE_ARCH} == "alpha"
@@ -162,14 +162,14 @@ LD_shared=-b
 LD_so=sl
 DLLIB=
 # HPsUX lorder does not grok anything but .o
-LD_sobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.so,'`
+LD_sobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.So,'`
 LD_pobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.po,'`
 .elif ${TARGET_OSNAME} == "OSF1"
 LD_shared= -msym -shared -expect_unresolved '*'
 LD_solib= -all lib${LIB}_pic.a
 DLLIB=
 # lorder does not grok anything but .o
-LD_sobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.so,'`
+LD_sobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.So,'`
 LD_pobjs=`${LORDER} ${OBJS} | ${TSORT} | sed 's,\.o,.po,'`
 AR_cq= -cqs
 .elif ${TARGET_OSNAME} == "FreeBSD"
@@ -254,7 +254,7 @@ DLLIB ?= -ldl
 # is a waste of time, this tells meta.autodep.mk to just pick one 
 # (typically .So)
 # yes, 42 is a random number.
-.if ${MK_META_MODE} == "yes" && ${SRCS:Uno:[\#]} > 42
+.if ${MK_DIRDEPS_BUILD} == "yes" && ${SRCS:Uno:[\#]} > 42
 OPTIMIZE_OBJECT_META_FILES ?= yes
 .endif
 
@@ -273,7 +273,7 @@ SHLIB_AGE != . ${.CURDIR}/shlib_version ; echo $$age
        ${COMPILE.c} ${.IMPSRC}
 
 # for the normal .a we do not want to strip symbols
-.cc.o .C.o:
+${CXX_SUFFIXES:%=%.o}:
        ${COMPILE.cc} ${.IMPSRC}
 
 .S.o .s.o:
@@ -284,10 +284,10 @@ SHLIB_AGE != . ${.CURDIR}/shlib_version ; echo $$age
 .c.po:
        ${COMPILE.c} ${CC_PG} ${PROFFLAGS} ${.IMPSRC} -o ${.TARGET}
 
-.cc.po .C.po:
+${CXX_SUFFIXES:%=%.po}:
        ${COMPILE.cc} -pg ${.IMPSRC} -o ${.TARGET}
 
-.S.so .s.so:
+.S.So .s.So:
        ${COMPILE.S} ${PICFLAG} ${CC_PIC} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}
 .else
 .c.po:
@@ -296,13 +296,13 @@ SHLIB_AGE != . ${.CURDIR}/shlib_version ; echo $$age
        @${LD} ${LD_X} ${LD_r} ${.TARGET}.o -o ${.TARGET}
        @rm -f ${.TARGET}.o
 
-.cc.po .C.po:
+${CXX_SUFFIXES:%=%.po}:
        @echo ${COMPILE.cc} ${CXX_PG} ${PROFFLAGS} ${.IMPSRC} -o ${.TARGET}
        @${COMPILE.cc} ${CXX_PG} ${.IMPSRC} -o ${.TARGET}.o
        @${LD} ${LD_X} ${LD_r} ${.TARGET}.o -o ${.TARGET}
        @rm -f ${.TARGET}.o
 
-.S.so .s.so:
+.S.So .s.So:
        @echo ${COMPILE.S} ${PICFLAG} ${CC_PIC} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}
        @${COMPILE.S} ${PICFLAG} ${CC_PIC} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}.o
        @${LD} ${LD_x} ${LD_r} ${.TARGET}.o -o ${.TARGET}
@@ -310,23 +310,23 @@ SHLIB_AGE != . ${.CURDIR}/shlib_version ; echo $$age
 .endif
 
 .if (${LD_x} == "")
-.c.so:
+.c.So:
        ${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
 
-.cc.so .C.so:
+${CXX_SUFFIXES:%=%.So}:
        ${COMPILE.cc} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
 
 .S.po .s.po:
        ${COMPILE.S} ${PROFFLAGS} ${CFLAGS:M-[ID]*} ${AINC} ${.IMPSRC} -o ${.TARGET}
 .else
 
-.c.so:
+.c.So:
        @echo ${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
        @${COMPILE.c} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}.o
        @${LD} ${LD_x} ${LD_r} ${.TARGET}.o -o ${.TARGET}
        @rm -f ${.TARGET}.o
 
-.cc.so .C.so:
+${CXX_SUFFIXES:%=%.So}:
        @echo ${COMPILE.cc} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}
        @${COMPILE.cc} ${PICFLAG} ${CC_PIC} ${.IMPSRC} -o ${.TARGET}.o
        @${LD} ${LD_x} ${LD_r} ${.TARGET}.o -o ${.TARGET}
@@ -396,7 +396,7 @@ prebuild:
 all: _SUBDIRUSE
 
 .for s in ${SRCS:N*.h:M*/*}
-${.o .so .po .lo:L:@o@${s:T:R}$o@}: $s
+${.o .So .po .lo:L:@o@${s:T:R}$o@}: $s
 .endfor
 
 OBJS+= ${SRCS:T:N*.h:R:S/$/.o/g}
@@ -441,7 +441,7 @@ lib${LIB}_p.a:: ${POBJS}
        @${AR} ${AR_cq} ${.TARGET} ${LD_pobjs}
        ${RANLIB} ${.TARGET}
 
-SOBJS+=        ${OBJS:.o=.so}
+SOBJS+=        ${OBJS:.o=.So}
 .NOPATH:       ${SOBJS}
 lib${LIB}_pic.a:: ${SOBJS}
        @echo building shared object ${LIB} library
@@ -502,7 +502,7 @@ cleandir: _SUBDIRUSE clean
 .if defined(SRCS) && (!defined(MKDEP) || ${MKDEP} != autodep)
 afterdepend: .depend
        @(TMP=/tmp/_depend$$$$; \
-           sed -e 's/^\([^\.]*\).o[ ]*:/\1.o \1.po \1.so \1.ln:/' \
+           sed -e 's/^\([^\.]*\).o[ ]*:/\1.o \1.po \1.So \1.ln:/' \
              < .depend > $$TMP; \
            mv $$TMP .depend)
 .endif
@@ -564,6 +564,7 @@ libinstall:
 install: maninstall _SUBDIRUSE
 maninstall: afterinstall
 afterinstall: realinstall
+libinstall: beforeinstall
 realinstall: beforeinstall
 .endif
 
index 60e12eb..b0eabed 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: libnames.mk,v 1.7 2009/12/25 07:34:03 sjg Exp $
+# $Id: libnames.mk,v 1.8 2016/04/05 15:58:37 sjg Exp $
 #
 #      @(#) Copyright (c) 2007-2009, Simon J. Gerraty
 #
@@ -16,7 +16,7 @@
 DLIBEXT ?= .a
 DSHLIBEXT ?= .so
 
-.-include "local.libnames.mk"
-.-include "sjg.libnames.mk"
-.-include "fwall.libnames.mk"
-.-include "host.libnames.mk"
+.-include <local.libnames.mk>
+.-include <sjg.libnames.mk>
+.-include <fwall.libnames.mk>
+.-include <host.libnames.mk>
index 64bc30b..06fa98c 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: meta.autodep.mk,v 1.36 2014/08/02 23:10:29 sjg Exp $
+# $Id: meta.autodep.mk,v 1.45 2016/06/03 17:22:32 sjg Exp $
 
 #
 #      @(#) Copyright (c) 2010, Simon J. Gerraty
@@ -18,7 +18,7 @@ _this ?= ${.PARSEFILE}
 .if !target(__${_this}__)
 __${_this}__: .NOTMAIN
 
-.-include "local.autodep.mk"
+.-include <local.autodep.mk>
 
 .if defined(SRCS)
 # it would be nice to be able to query .SUFFIXES
@@ -50,8 +50,26 @@ UPDATE_DEPENDFILE = NO
 .endif
 
 _CURDIR ?= ${.CURDIR}
+_OBJDIR ?= ${.OBJDIR}
+_OBJTOP ?= ${OBJTOP}
+_OBJROOT ?= ${OBJROOT:U${_OBJTOP}}
 _DEPENDFILE := ${_CURDIR}/${.MAKE.DEPENDFILE:T}
 
+.if ${.MAKE.LEVEL} > 0 || ${BUILD_AT_LEVEL0:Uyes:tl} == "yes"
+# do not allow auto update if we ever built this dir without filemon
+NO_FILEMON_COOKIE = .nofilemon
+CLEANFILES += ${NO_FILEMON_COOKIE}
+.if ${.MAKE.MODE:Uno:Mnofilemon} != ""
+UPDATE_DEPENDFILE = NO
+all: ${NO_FILEMON_COOKIE}
+${NO_FILEMON_COOKIE}: .NOMETA
+       @echo UPDATE_DEPENDFILE=NO > ${.TARGET}
+.elif exists(${NO_FILEMON_COOKIE})
+UPDATE_DEPENDFILE = NO
+.warning ${RELDIR} built with nofilemon; UPDATE_DEPENDFILE=NO
+.endif
+.endif
+
 .if ${.MAKE.LEVEL} == 0
 .if ${BUILD_AT_LEVEL0:Uyes:tl} == "no"
 UPDATE_DEPENDFILE = NO
@@ -83,7 +101,7 @@ WANT_UPDATE_DEPENDFILE ?= yes
 .endif
 
 .if ${WANT_UPDATE_DEPENDFILE:Uno:tl} != "no"
-.if ${.MAKE.MODE:Mmeta*} == "" || ${.MAKE.MODE:M*read*} != ""
+.if ${.MAKE.MODE:Uno:Mmeta*} == "" || ${.MAKE.MODE:Uno:M*read*} != ""
 UPDATE_DEPENDFILE = no
 .endif
 
@@ -97,6 +115,8 @@ UPDATE_DEPENDFILE = no
 # for example the result of running configure
 # just make sure this is not empty
 META_FILE_FILTER ?= N.meta
+# never consider these
+META_FILE_FILTER += Ndirdeps.cache*
 
 .if !empty(DPADD)
 # if we have any non-libs in DPADD, 
@@ -188,9 +208,9 @@ gendirdeps: ${_DEPENDFILE}
 # anything which matches ${_OBJROOT}* but not ${_OBJTOP}*
 # needs to be qualified in DIRDEPS
 # The pseudo machine "host" is used for HOST_TARGET
-DIRDEPS = \
+DIRDEPS += \
        ${DPADD:M${_OBJTOP}*:H:C,${_OBJTOP}[^/]*/,,:N.:O:u} \
-       ${DPADD:M${_OBJROOT}*:N${_OBJTOP}*:H:S,${_OBJROOT},,:C,^([^/]+)/(.*),\2.\1,:S,${HOST_TARGET}$,host,:N.*:O:u}
+       ${DPADD:M${_OBJROOT}*:N${_OBJTOP}*:N${STAGE_ROOT:U${_OBJTOP}}/*:H:S,${_OBJROOT},,:C,^([^/]+)/(.*),\2.\1,:S,${HOST_TARGET}$,host,:N.*:O:u}
 
 .endif
 .endif
@@ -246,7 +266,7 @@ ${_DEPENDFILE}: ${_depend} ${.PARSEDIR}/gendirdeps.mk  ${META2DEPS} $${.MAKE.MET
        DPADD='${FORCE_DPADD:O:u}' ${_gendirdeps_mutex} \
        MAKESYSPATH=${_makesyspath} \
        ${.MAKE} -f gendirdeps.mk RELDIR=${RELDIR} _DEPENDFILE=${_DEPENDFILE} \
-       META_FILES='${META_XTRAS:T:O:u} ${META_FILES:T:O:u:${META_FILE_FILTER:ts:}}')
+       META_FILES='${META_XTRAS:O:u} ${META_FILES:T:O:u:${META_FILE_FILTER:ts:}}')
        @test -s $@ && touch $@; :
 .endif
 
index bb41c8f..11eb5c3 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: meta.stage.mk,v 1.32 2014/10/18 05:48:02 sjg Exp $
+# $Id: meta.stage.mk,v 1.45 2016/05/26 03:59:09 sjg Exp $
 #
 #      @(#) Copyright (c) 2011, Simon J. Gerraty
 #
@@ -23,8 +23,10 @@ _dirdep = ${RELDIR}.${MACHINE}
 _dirdep = ${RELDIR}
 .endif
 
+CLEANFILES+= .dirdep
+
 # this allows us to trace dependencies back to their src dir
-.dirdep:
+.dirdep:       .NOPATH
        @echo '${_dirdep}' > $@
 
 .if defined(NO_POSIX_SHELL) || ${type printf:L:sh:Mbuiltin} == ""
@@ -35,7 +37,13 @@ _stage_file_basename = $${f\#\#*/}
 _stage_target_dirname = $${t%/*}
 .endif
 
+_OBJROOT ?= ${OBJROOT:U${OBJTOP:H}}
+.if ${_OBJROOT:M*/} != ""
+_objroot ?= ${_OBJROOT:tA}/
+.else
 _objroot ?= ${_OBJROOT:tA}
+.endif
+
 # make sure this is global
 _STAGED_DIRS ?=
 .export _STAGED_DIRS
@@ -50,17 +58,26 @@ GENDIRDEPS_FILTER += Nnot-empty-is-important \
 
 LN_CP_SCRIPT = LnCp() { \
   rm -f $$2 2> /dev/null; \
-  ln $$1 $$2 2> /dev/null || \
+  { [ -z "$$mode" ] && ln $$1 $$2 2> /dev/null; } || \
   cp -p $$1 $$2; }
 
+# a staging conflict should cause an error
+# a warning is handy when bootstapping different options.
+STAGE_CONFLICT?= ERROR
+.if ${STAGE_CONFLICT:tl} == "error"
+STAGE_CONFLICT_ACTION= exit 1;
+.else
+STAGE_CONFLICT_ACTION=
+.endif
+
 # it is an error for more than one src dir to try and stage
 # the same file
 STAGE_DIRDEP_SCRIPT = ${LN_CP_SCRIPT}; StageDirdep() { \
   t=$$1; \
   if [ -s $$t.dirdep ]; then \
        cmp -s .dirdep $$t.dirdep && return; \
-       echo "ERROR: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \
-       exit 1; \
+       echo "${STAGE_CONFLICT}: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \
+       ${STAGE_CONFLICT_ACTION} \
   fi; \
   LnCp .dirdep $$t.dirdep || exit 1; }
 
@@ -118,8 +135,9 @@ _STAGE_AS_BASENAME_USE:        .USE ${.TARGET:T}
 
 .if !empty(STAGE_INCSDIR)
 STAGE_TARGETS += stage_incs
-STAGE_INCS ?= ${.ALLSRC:N.dirdep}
+STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*}
 
+stage_includes: stage_incs
 stage_incs:    .dirdep
        @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR:${STAGE_DIR_FILTER}} ${STAGE_INCS}
        @touch $@
@@ -128,15 +146,17 @@ stage_incs:       .dirdep
 .if !empty(STAGE_LIBDIR)
 STAGE_TARGETS += stage_libs
 
-STAGE_LIBS ?= ${.ALLSRC:N.dirdep}
+STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*}
 
 stage_libs:    .dirdep
        @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS}
+.if !defined(NO_SHLIB_LINKS)
 .if !empty(SHLIB_LINKS)
        @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} \
        ${SHLIB_LINKS:@t@${STAGE_LIBS:T:M$t.*} $t@}
 .elif !empty(SHLIB_LINK) && !empty(SHLIB_NAME)
-       @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${SHLIB_NAME} ${SHLIB_LINK} ${SYMLINKS:T}
+       @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${SHLIB_NAME} ${SHLIB_LINK}
+.endif
 .endif
        @touch $@
 .endif
@@ -158,8 +178,8 @@ CLEANFILES += ${STAGE_SETS:@s@stage*$s@}
 
 # some makefiles need to populate multiple directories
 .for s in ${STAGE_SETS:O:u}
-STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep}
-STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep}
+STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
+STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
 STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP}
 STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP}
 
@@ -205,31 +225,35 @@ STAGE_TARGETS += stage_as
 # each ${file} will be staged as ${STAGE_AS_${file:T}}
 # one could achieve the same with SYMLINKS
 .for s in ${STAGE_AS_SETS:O:u}
-STAGE_AS.$s ?= ${.ALLSRC:N.dirdep}
+STAGE_AS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*}
 
 stage_as:      stage_as.$s
 stage_as.$s:   .dirdep
-       @${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:T}:U${f:T}}@}
+       @${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:tA}:U${STAGE_AS_${f:T}:U${f:T}}}@}
        @touch $@
 
 .endfor
 .endif
 
-CLEANFILES += ${STAGE_TARGETS}
+CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes
 
 # stage_*links usually needs to follow any others.
+# for non-jobs mode the order here matters
+staging: ${STAGE_TARGETS:N*_links} ${STAGE_TARGETS:M*_links}
+
+.if ${.MAKE.JOBS:U0} > 0 && ${STAGE_TARGETS:U:M*_links} != ""
+# the above isn't sufficient
 .for t in ${STAGE_TARGETS:N*links:O:u}
 .ORDER: $t stage_links
-.ORDER: $t stage_symlinks
 .endfor
-
-# make sure this exists
-staging:
+.endif
 
 # generally we want staging to wait until everything else is done
 STAGING_WAIT ?= .WAIT
 
+.if ${.MAKE.LEVEL} > 0
 all: ${STAGING_WAIT} staging
+.endif
 
 .if exists(${.PARSEDIR}/stage-install.sh) && !defined(STAGE_INSTALL)
 # this will run install(1) and then followup with .dirdep files.
@@ -245,4 +269,26 @@ beforeinstall: .dirdep
 .endif
 .NOPATH: ${STAGE_FILES}
 
+.if !empty(STAGE_TARGETS)
+.NOPATH: ${CLEANFILES}
+
+MK_STALE_STAGED?= no
+.if ${MK_STALE_STAGED} == "yes"
+all: stale_staged
+# get a list of paths that we have just staged
+# get a list of paths that we have previously staged to those same dirs
+# anything in the 2nd list but not the first is stale - remove it.
+stale_staged: staging .NOMETA
+       @egrep '^[WL] .*${STAGE_OBJTOP}' /dev/null ${.MAKE.META.FILES:M*stage_*} | \
+       sed "/\.dirdep/d;s,.* '*\(${STAGE_OBJTOP}/[^ '][^ ']*\).*,\1," | \
+       sort > ${.TARGET}.staged1
+       @grep -l '${_dirdep}' /dev/null ${_STAGED_DIRS:M${STAGE_OBJTOP}*:O:u:@d@$d/*.dirdep@} | \
+       sed 's,\.dirdep,,' | sort > ${.TARGET}.staged2
+       @comm -13 ${.TARGET}.staged1 ${.TARGET}.staged2 > ${.TARGET}.stale
+       @test ! -s ${.TARGET}.stale || { \
+               echo "Removing stale staged files..."; \
+               sed 's,.*,& &.dirdep,' ${.TARGET}.stale | xargs rm -f; }
+
+.endif
+.endif
 .endif
index 2b739ee..d27de10 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: meta.subdir.mk,v 1.10 2012/07/03 05:26:46 sjg Exp $
+# $Id: meta.subdir.mk,v 1.11 2015/11/24 22:26:51 sjg Exp $
 
 #
 #      @(#) Copyright (c) 2010, Simon J. Gerraty
@@ -62,7 +62,7 @@ _subdeps != cd ${.CURDIR} && \
 DIRDEPS =
 .else
 # clean up if needed
-DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIREPS_FILTER:Uu}}
+DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIRDEPS_FILTER:Uu}}
 .endif
 # we just dealt with it, if we leave it defined,
 # dirdeps.mk will compute some interesting combinations.
index bcafd55..47cd8f5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: meta.sys.mk,v 1.20 2014/08/04 05:12:27 sjg Exp $
+# $Id: meta.sys.mk,v 1.29 2016/08/13 17:51:45 sjg Exp $
 
 #
 #      @(#) Copyright (c) 2010, Simon J. Gerraty
 .if ${MAKE_VERSION:U0} > 20100901
 .if !target(.ERROR)
 
+.-include <local.meta.sys.mk>
+
+# absoulte path to what we are reading.
+_PARSEDIR = ${.PARSEDIR:tA}
+
+.if !defined(SYS_MK_DIR)
+SYS_MK_DIR := ${_PARSEDIR}
+.endif
 
 META_MODE += meta verbose
 .MAKE.MODE ?= ${META_MODE}
@@ -47,17 +55,6 @@ META_MODE += silent=yes
 .endif
 .endif
 
-# make defaults .MAKE.DEPENDFILE to .depend
-# that won't work for us.
-.if ${.MAKE.DEPENDFILE} == ".depend"
-.undef .MAKE.DEPENDFILE
-.endif
-
-# if you don't cross build for multiple MACHINEs concurrently, then
-# .MAKE.DEPENDFILE = Makefile.depend
-# probably makes sense - you can set that in local.sys.mk 
-.MAKE.DEPENDFILE ?= Makefile.depend.${MACHINE}
-
 # we use the pseudo machine "host" for the build host.
 # this should be taken care of before we get here
 .if ${OBJTOP:Ua} == ${HOST_OBJTOP:Ub}
@@ -69,6 +66,7 @@ MACHINE = host
 # for example, if using Makefild.depend for multiple machines,
 # allowing only MACHINE0 to update can keep things simple.
 MACHINE0 := ${MACHINE}
+.export MACHINE0
 
 .if defined(PYTHON) && exists(${PYTHON})
 # we prefer the python version of this - it is much faster
@@ -104,15 +102,46 @@ _metaError: .NOMETA .NOTMAIN
 
 .endif
 
+META_COOKIE_TOUCH=
+# some targets need to be .PHONY in non-meta mode
+META_NOPHONY= .PHONY
 # Are we, after all, in meta mode?
-.if ${.MAKE.MODE:Mmeta*} != ""
+.if ${.MAKE.MODE:Uno:Mmeta*} != ""
 MKDEP_MK = meta.autodep.mk
 
-# if we think we are updating dependencies, 
-# then filemon had better be present
-.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no" && !exists(/dev/filemon)
+.if ${.MAKE.MAKEFILES:M*sys.dependfile.mk} == ""
+# this does all the smarts of setting .MAKE.DEPENDFILE
+.-include <sys.dependfile.mk>
+# check if we got anything sane
+.if ${.MAKE.DEPENDFILE} == ".depend"
+.undef .MAKE.DEPENDFILE
+.endif
+.MAKE.DEPENDFILE ?= Makefile.depend
+.endif
+
+# we can afford to use cookies to prevent some targets
+# re-running needlessly
+META_COOKIE_TOUCH= touch ${COOKIE.${.TARGET}:U${.OBJDIR}/${.TARGET}}
+META_NOPHONY=
+
+# some targets involve old pre-built targets
+# ignore mtime of shell
+# and mtime of makefiles does not matter in meta mode
+.MAKE.META.IGNORE_PATHS += \
+        ${MAKEFILE} \
+        ${SHELL} \
+        ${SYS_MK_DIR}
+
+.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no"
+.if ${.MAKEFLAGS:Uno:M-k} != ""
+# make this more obvious
+.warning Setting UPDATE_DEPENDFILE=NO due to -k
+UPDATE_DEPENDFILE= NO
+.export UPDATE_DEPENDFILE
+.elif !exists(/dev/filemon)
 .error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded.
 .endif
+.endif
 
 .if ${.MAKE.LEVEL} == 0
 # make sure dirdeps target exists and do it first
index 8e349e7..6361493 100755 (executable)
@@ -37,7 +37,7 @@ We only pay attention to a subset of the information in the
 
 """
 RCSid:
-       $Id: meta2deps.py,v 1.17 2014/04/05 22:56:54 sjg Exp $
+       $Id: meta2deps.py,v 1.19 2016/04/02 20:45:40 sjg Exp $
 
        Copyright (c) 2011-2013, Juniper Networks, Inc.
        All rights reserved.
@@ -112,7 +112,8 @@ def abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr):
     rpath = resolve(path, cwd, last_dir, debug, debug_out)
     if rpath:
         path = rpath
-    if (path.find('./') > 0 or
+    if (path.find('/') < 0 or
+       path.find('./') > 0 or
         path.endswith('/..') or
         os.path.islink(path)):
         return os.path.realpath(path)
@@ -142,7 +143,7 @@ class MetaFile:
     host_target = None
     srctops = []
     objroots = []
-    
+    excludes = []
     seen = {}
     obj_deps = []
     src_deps = []
@@ -179,6 +180,10 @@ class MetaFile:
                This can allow 'bmake' to learn all the dirs within
                the tree that depend on 'foo.h'
 
+       EXCLUDES
+               A list of paths to ignore.
+               ccache(1) can otherwise be trouble.
+
         debug  desired debug level
 
         debug_out open file to send debug output to (sys.stderr)
@@ -236,11 +241,14 @@ class MetaFile:
             # we want the longest match
             self.srctops.sort(reverse=True)
             self.objroots.sort(reverse=True)
-            
+
+            self.excludes = getv(conf, 'EXCLUDES', [])
+
             if self.debug:
                 print("host_target=", self.host_target, file=self.debug_out)
                 print("srctops=", self.srctops, file=self.debug_out)
                 print("objroots=", self.objroots, file=sel