Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Jan 2026 21:34:07 +0000
From:      Simon J. Gerraty <sjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 8a4277b9667c - stable/14 - Merge bmake-20250414
Message-ID:  <6962c5cf.25a58.4c16f0a0@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch stable/14 has been updated by sjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=8a4277b9667c5eb3bd0ab40513df1daa6985c679

commit 8a4277b9667c5eb3bd0ab40513df1daa6985c679
Author:     Simon J. Gerraty <sjg@FreeBSD.org>
AuthorDate: 2025-04-19 20:57:00 +0000
Commit:     Simon J. Gerraty <sjg@FreeBSD.org>
CommitDate: 2026-01-10 21:33:13 +0000

    Merge bmake-20250414
    
    Merge commit '284d1f7d496806b18558ab55e4654fd5e96d6a3e'
    
    (cherry picked from commit 759b177aecbfc49ebc900739954ac56b1aa5fc53)
---
 contrib/bmake/ChangeLog                            |  49 ++++++
 contrib/bmake/FILES                                |   6 +
 contrib/bmake/VERSION                              |   2 +-
 contrib/bmake/bmake.1                              |  58 ++++++-
 contrib/bmake/bmake.cat1                           |  41 ++++-
 contrib/bmake/cond.c                               |  32 ++--
 contrib/bmake/dir.c                                |   6 +-
 contrib/bmake/for.c                                |  47 +++---
 contrib/bmake/job.c                                |  38 ++---
 contrib/bmake/main.c                               |  15 +-
 contrib/bmake/make.1                               |  58 ++++++-
 contrib/bmake/make.h                               |   5 +-
 contrib/bmake/meta.c                               |  32 ++--
 contrib/bmake/mk/ChangeLog                         |  22 +++
 contrib/bmake/mk/auto.obj.mk                       |  13 +-
 contrib/bmake/mk/genfiles.mk                       |   5 +-
 contrib/bmake/mk/init.mk                           |  21 ++-
 contrib/bmake/mk/install-mk                        |   4 +-
 contrib/bmake/mk/rst2htm.mk                        |   6 +-
 contrib/bmake/parse.c                              |  22 +--
 contrib/bmake/unit-tests/Makefile                  |  15 +-
 contrib/bmake/unit-tests/archive.exp               |   4 +-
 contrib/bmake/unit-tests/cmd-errors-jobs.exp       |  10 +-
 contrib/bmake/unit-tests/cmd-errors-jobs.mk        |   9 +-
 contrib/bmake/unit-tests/cmd-errors-lint.exp       |   5 +-
 contrib/bmake/unit-tests/cmd-errors-lint.mk        |   4 +-
 contrib/bmake/unit-tests/cmd-errors.exp            |   5 +-
 contrib/bmake/unit-tests/cmd-errors.mk             |   4 +-
 contrib/bmake/unit-tests/cmdline-undefined.exp     |  24 +--
 contrib/bmake/unit-tests/cond-cmp-numeric-eq.exp   |   4 +-
 contrib/bmake/unit-tests/cond-cmp-numeric.exp      |   8 +-
 contrib/bmake/unit-tests/cond-cmp-string.exp       |  16 +-
 contrib/bmake/unit-tests/cond-cmp-unary.exp        |   2 +-
 contrib/bmake/unit-tests/cond-eof.exp              |   6 +-
 contrib/bmake/unit-tests/cond-func-defined.exp     |   4 +-
 contrib/bmake/unit-tests/cond-func-empty.exp       |   2 +-
 contrib/bmake/unit-tests/cond-func-make.exp        |   2 +-
 contrib/bmake/unit-tests/cond-func.exp             |  20 +--
 contrib/bmake/unit-tests/cond-late.exp             |   2 +-
 contrib/bmake/unit-tests/cond-op-and-lint.exp      |   2 +-
 contrib/bmake/unit-tests/cond-op-and.exp           |  16 +-
 contrib/bmake/unit-tests/cond-op-not.exp           |  12 +-
 contrib/bmake/unit-tests/cond-op-or-lint.exp       |   2 +-
 contrib/bmake/unit-tests/cond-op-or.exp            |  16 +-
 contrib/bmake/unit-tests/cond-op-parentheses.exp   |   8 +-
 contrib/bmake/unit-tests/cond-op.exp               |  36 ++---
 contrib/bmake/unit-tests/cond-short.exp            |   2 +-
 contrib/bmake/unit-tests/cond-token-number.exp     |   8 +-
 contrib/bmake/unit-tests/cond-token-plain.exp      |  30 ++--
 contrib/bmake/unit-tests/cond-token-string.exp     |  18 +--
 contrib/bmake/unit-tests/cond-token-string.mk      |   4 +-
 contrib/bmake/unit-tests/cond-token-var.exp        |  26 +--
 contrib/bmake/unit-tests/cond-token-var.mk         |  29 +++-
 contrib/bmake/unit-tests/cond-undef-lint.exp       |   6 +-
 .../bmake/unit-tests/dep-colon-bug-cross-file.exp  |   4 +-
 contrib/bmake/unit-tests/dep-duplicate.exp         |   4 +-
 contrib/bmake/unit-tests/dep-op-missing.exp        |   2 +-
 contrib/bmake/unit-tests/dep.exp                   |   4 +-
 contrib/bmake/unit-tests/deptgt-begin.exp          |   4 +-
 contrib/bmake/unit-tests/deptgt-path-suffix.exp    |   2 +-
 contrib/bmake/unit-tests/deptgt.exp                |  14 +-
 contrib/bmake/unit-tests/deptgt.mk                 |   6 +-
 contrib/bmake/unit-tests/directive-dinclude.exp    |   2 +-
 contrib/bmake/unit-tests/directive-dinclude.mk     |   4 +-
 contrib/bmake/unit-tests/directive-elif.exp        |  36 ++---
 contrib/bmake/unit-tests/directive-else.exp        |  16 +-
 contrib/bmake/unit-tests/directive-endfor.exp      |   2 +-
 contrib/bmake/unit-tests/directive-endif.exp       |  10 +-
 contrib/bmake/unit-tests/directive-error.exp       |   2 +-
 .../bmake/unit-tests/directive-export-gmake.exp    |   6 +-
 contrib/bmake/unit-tests/directive-export.exp      |   8 +-
 contrib/bmake/unit-tests/directive-for-break.exp   |   4 +-
 contrib/bmake/unit-tests/directive-for-empty.exp   |   2 +-
 contrib/bmake/unit-tests/directive-for-errors.exp  |  25 ++-
 contrib/bmake/unit-tests/directive-for-errors.mk   |  14 +-
 contrib/bmake/unit-tests/directive-for-escape.exp  |  66 ++++----
 .../unit-tests/directive-for-generating-endif.exp  |   8 +-
 contrib/bmake/unit-tests/directive-for-if.exp      |   6 +-
 contrib/bmake/unit-tests/directive-for-lines.exp   |  12 +-
 contrib/bmake/unit-tests/directive-for-null.exp    |   2 +-
 contrib/bmake/unit-tests/directive-for-null.mk     |   4 +-
 contrib/bmake/unit-tests/directive-for.exp         |  59 ++++---
 contrib/bmake/unit-tests/directive-for.mk          |  14 +-
 .../bmake/unit-tests/directive-hyphen-include.exp  |   2 +-
 .../bmake/unit-tests/directive-hyphen-include.mk   |   4 +-
 contrib/bmake/unit-tests/directive-if-nested.exp   |   2 +-
 contrib/bmake/unit-tests/directive-if.exp          |  30 ++--
 contrib/bmake/unit-tests/directive-ifmake.exp      |  14 +-
 contrib/bmake/unit-tests/directive-ifndef.exp      |   2 +-
 .../bmake/unit-tests/directive-include-fatal.exp   |   2 +-
 .../bmake/unit-tests/directive-include-guard.exp   | 168 +++++++++----------
 .../bmake/unit-tests/directive-include-guard.mk    | 168 +++++++++----------
 contrib/bmake/unit-tests/directive-include.exp     |  12 +-
 contrib/bmake/unit-tests/directive-include.mk      |   6 +-
 contrib/bmake/unit-tests/directive-info.exp        |  24 +--
 .../bmake/unit-tests/directive-misspellings.exp    |  84 +++++-----
 contrib/bmake/unit-tests/directive-sinclude.exp    |   2 +-
 contrib/bmake/unit-tests/directive-sinclude.mk     |   4 +-
 contrib/bmake/unit-tests/directive-undef.exp       |   6 +-
 contrib/bmake/unit-tests/directive-undef.mk        |   4 +-
 .../bmake/unit-tests/directive-unexport-env.exp    |   6 +-
 contrib/bmake/unit-tests/directive-unexport.exp    |   8 +-
 contrib/bmake/unit-tests/directive-warning.exp     |  16 +-
 contrib/bmake/unit-tests/directive.exp             |  14 +-
 contrib/bmake/unit-tests/error.exp                 |   6 +-
 contrib/bmake/unit-tests/include-main.exp          |  18 +--
 contrib/bmake/unit-tests/lint.exp                  |   1 +
 contrib/bmake/unit-tests/meta-cmd-cmp.exp          |  12 +-
 contrib/bmake/unit-tests/moderrs.exp               | 117 +++++++++-----
 contrib/bmake/unit-tests/moderrs.mk                |  69 ++++----
 contrib/bmake/unit-tests/opt-debug-file.exp        |   6 +-
 contrib/bmake/unit-tests/opt-debug-hash.exp        |   2 +-
 contrib/bmake/unit-tests/opt-debug-lint.exp        |  10 +-
 contrib/bmake/unit-tests/opt-debug-lint.mk         |   8 +-
 contrib/bmake/unit-tests/opt-debug-parse.exp       |  18 +--
 contrib/bmake/unit-tests/opt-debug-var.exp         |   4 +-
 contrib/bmake/unit-tests/opt-file.exp              |   2 +-
 .../bmake/unit-tests/opt-warnings-as-errors.exp    |   4 +-
 contrib/bmake/unit-tests/parse.exp                 |   6 +-
 contrib/bmake/unit-tests/posix-execution.exp       |  24 +++
 contrib/bmake/unit-tests/posix-execution.mk        |  59 +++++++
 contrib/bmake/unit-tests/posix-expansion.exp       |   1 +
 contrib/bmake/unit-tests/posix-expansion.mk        |  22 +++
 contrib/bmake/unit-tests/posix-varassign.exp       |   1 +
 contrib/bmake/unit-tests/posix-varassign.mk        |  79 +++++++++
 contrib/bmake/unit-tests/posix.exp                 |  28 +---
 contrib/bmake/unit-tests/posix.mk                  |  36 ++---
 contrib/bmake/unit-tests/recursive.exp             |   4 +-
 contrib/bmake/unit-tests/var-eval-short.exp        |   2 +-
 contrib/bmake/unit-tests/var-op-assign.exp         |   4 +-
 contrib/bmake/unit-tests/var-op-expand.exp         |   8 +-
 contrib/bmake/unit-tests/var-op-expand.mk          |   6 +-
 contrib/bmake/unit-tests/var-op-shell.exp          |   8 +-
 contrib/bmake/unit-tests/var-recursive.exp         |  19 +--
 contrib/bmake/unit-tests/var-recursive.mk          |   8 +-
 contrib/bmake/unit-tests/var-scope-cmdline.exp     |   4 +-
 contrib/bmake/unit-tests/vardebug.exp              |   5 +-
 contrib/bmake/unit-tests/vardebug.mk               |   7 +-
 contrib/bmake/unit-tests/varmisc.exp               |   9 ++
 contrib/bmake/unit-tests/varmod-assign-shell.exp   |   4 +-
 contrib/bmake/unit-tests/varmod-assign.exp         |  18 ++-
 contrib/bmake/unit-tests/varmod-assign.mk          |  20 ++-
 contrib/bmake/unit-tests/varmod-edge.exp           |  15 +-
 contrib/bmake/unit-tests/varmod-edge.mk            |  13 +-
 contrib/bmake/unit-tests/varmod-gmtime.exp         |  10 +-
 contrib/bmake/unit-tests/varmod-hash.exp           |   9 +-
 contrib/bmake/unit-tests/varmod-ifelse.exp         |  46 +++---
 contrib/bmake/unit-tests/varmod-ifelse.mk          |  16 +-
 contrib/bmake/unit-tests/varmod-indirect.exp       |  36 ++---
 contrib/bmake/unit-tests/varmod-indirect.mk        |  23 ++-
 contrib/bmake/unit-tests/varmod-localtime.exp      |  10 +-
 contrib/bmake/unit-tests/varmod-loop-delete.exp    |   2 +-
 contrib/bmake/unit-tests/varmod-loop-varname.exp   |   8 +-
 contrib/bmake/unit-tests/varmod-match-escape.exp   |   8 +-
 contrib/bmake/unit-tests/varmod-match.exp          |  20 +--
 contrib/bmake/unit-tests/varmod-match.mk           |   4 +-
 contrib/bmake/unit-tests/varmod-mtime.exp          |  12 +-
 contrib/bmake/unit-tests/varmod-mtime.mk           |   4 +-
 contrib/bmake/unit-tests/varmod-order.exp          |  26 ++-
 contrib/bmake/unit-tests/varmod-order.mk           |  28 ++--
 contrib/bmake/unit-tests/varmod-range.exp          |  13 +-
 contrib/bmake/unit-tests/varmod-range.mk           |  12 +-
 contrib/bmake/unit-tests/varmod-select-words.exp   |  36 +++--
 contrib/bmake/unit-tests/varmod-select-words.mk    |  26 +--
 contrib/bmake/unit-tests/varmod-shell.exp          |   6 +-
 contrib/bmake/unit-tests/varmod-subst-regex.exp    |  17 +-
 contrib/bmake/unit-tests/varmod-subst.exp          |   3 +-
 contrib/bmake/unit-tests/varmod-subst.mk           |   4 +-
 contrib/bmake/unit-tests/varmod-sun-shell.exp      |   4 +-
 contrib/bmake/unit-tests/varmod-sysv.exp           |   4 +-
 contrib/bmake/unit-tests/varmod-sysv.mk            |  29 +++-
 contrib/bmake/unit-tests/varmod-to-abs.exp         |   6 +-
 contrib/bmake/unit-tests/varmod-to-separator.exp   |  26 +--
 contrib/bmake/unit-tests/varmod-to-separator.mk    |  80 ++++-----
 contrib/bmake/unit-tests/varmod.exp                |  47 +++---
 contrib/bmake/unit-tests/varmod.mk                 |  91 ++++++-----
 contrib/bmake/unit-tests/varname-dollar.exp        |   8 +-
 .../bmake/unit-tests/varname-dot-make-level.exp    |  13 +-
 contrib/bmake/unit-tests/varname-dot-make-level.mk |  42 ++++-
 .../varname-dot-make-meta-ignore_filter.exp        |   2 +-
 .../varname-dot-make-meta-ignore_paths.exp         |   2 +-
 .../varname-dot-make-meta-ignore_patterns.exp      |   2 +-
 contrib/bmake/unit-tests/varname-dot-makeflags.exp |  12 +-
 contrib/bmake/unit-tests/varname-dot-newline.exp   |   6 +-
 contrib/bmake/unit-tests/varname-dot-parsedir.exp  |   6 +-
 contrib/bmake/unit-tests/varname-dot-parsefile.exp |   6 +-
 contrib/bmake/unit-tests/varname.exp               |   6 +-
 contrib/bmake/unit-tests/varparse-dynamic.exp      |   4 +-
 contrib/bmake/unit-tests/varparse-errors.exp       |  47 +++---
 contrib/bmake/unit-tests/varparse-errors.mk        |  34 +++-
 contrib/bmake/var.c                                | 178 ++++++++++-----------
 usr.bin/bmake/Makefile.config                      |   2 +-
 usr.bin/bmake/unit-tests/Makefile                  |  15 +-
 193 files changed, 2032 insertions(+), 1469 deletions(-)

diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog
index 15a58e2a0924..1ec90b7bccc8 100644
--- a/contrib/bmake/ChangeLog
+++ b/contrib/bmake/ChangeLog
@@ -1,3 +1,52 @@
+2025-04-14  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20250414
+	Merge with NetBSD make, pick up
+	o job.c: clean up job and output handling
+	o parse.c: after entering POSIX mode, don't leave it again
+
+2025-04-11  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20250411
+	Merge with NetBSD make, pick up
+	o convert more messages to file:line: format
+	o for.c: condense code for parsing variable names in .for loops
+
+2025-04-10  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20250410
+	Merge with NetBSD make, pick up
+	o cond.c: remove redundant error counter when parsing a condition
+
+2025-04-04  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20250404
+	Merge with NetBSD make, pick up
+	o make.1: better document meta mode.
+	o var.c: fix error message for undefined variable in conditional.
+
+2025-03-30  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20250330
+	Merge with NetBSD make, pick up
+	o in POSIX compatability mode, give preference to sysV style modifiers.
+	o in stack trace with details and includes, list the current file
+	o parse.c: report file location in more common file:line: format.
+	o var.c: simplify error handling for unknown modifiers
+	let the ":O" and ":t" modifiers fall back to the ":from=to" modifier
+	stop parsing after seeing an unknown modifier in an expression
+	fix error message for unclosed expression and invalid :[...]
+	add details to errors about ::= modifier
+	add details about indirect modifiers to the stack traces
+	in stack traces from target commands, add the command level
+
+2025-03-23  Simon J Gerraty  <sjg@beast.crufty.net>
+
+	* VERSION (_MAKE_VERSION): 20250323
+	Merge with NetBSD make, pick up
+	o var.c: just ignore attempts to override a read-only global with
+	the same value.
+
 2025-03-08  Simon J Gerraty  <sjg@beast.crufty.net>
 
 	* bsd.after-import.mk: by default generate makefiles
diff --git a/contrib/bmake/FILES b/contrib/bmake/FILES
index c8937c610a4d..553f3211f29c 100644
--- a/contrib/bmake/FILES
+++ b/contrib/bmake/FILES
@@ -555,6 +555,12 @@ unit-tests/parse.exp
 unit-tests/parse.mk
 unit-tests/phony-end.exp
 unit-tests/phony-end.mk
+unit-tests/posix-execution.exp
+unit-tests/posix-execution.mk
+unit-tests/posix-expansion.exp
+unit-tests/posix-expansion.mk
+unit-tests/posix-varassign.exp
+unit-tests/posix-varassign.mk
 unit-tests/posix.exp
 unit-tests/posix.mk
 unit-tests/posix1.exp
diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION
index d26469e64381..4e4949c5fd3e 100644
--- a/contrib/bmake/VERSION
+++ b/contrib/bmake/VERSION
@@ -1,2 +1,2 @@
 # keep this compatible with sh and make
-_MAKE_VERSION=20250308
+_MAKE_VERSION=20250414
diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1
index eef2d799b960..9e9f2d03a450 100644
--- a/contrib/bmake/bmake.1
+++ b/contrib/bmake/bmake.1
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.381 2024/11/14 19:30:13 sjg Exp $
+.\"	$NetBSD: make.1,v 1.384 2025/04/04 18:36:47 sjg 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 November 14, 2024
+.Dd April  4, 2025
 .Dt BMAKE 1
 .Os
 .Sh NAME
@@ -1087,11 +1087,61 @@ Puts
 into
 .Dq meta
 mode, where meta files are created for each target
-to capture the command run, the output generated, and if
+to capture the commands run, the output generated, and if
 .Xr filemon 4
 is available, the system calls which are of interest to
 .Nm .
 The captured output can be useful when diagnosing errors.
+.Pp
+.Nm
+will use the information in the meta file to help determine if
+a target is out-of-date when the normal dependency rules
+indicate it is not.
+.Pp
+First,
+the commands to be executed,
+will be compared to those captured previously,
+if any differ,
+the target is out-of-date.
+.Pp
+This allows for a huge improvement in the reliability
+and efficiency of update builds.
+It is no longer necessary for targets to depend on makefiles
+just in-case they set a variable that might be relevant.
+Mechanisms such as
+.Va .MAKE.META.CMP_FILTER
+and
+.Ic .NOMETA_CMP ,
+allow limiting or disabling that comparison on a per target basis.
+A reference to the variable
+.Va .OODATE
+can be leveraged to block comparison of certain commands.
+For example:
+.Ql ${.OODATE:M}
+will expand to nothing and have no impact on the target,
+its side-effect though,
+will be to prevent comparison of any command line it appears on.
+For documentation purposes
+.Ql ${.OODATE:MNOMETA_CMP}
+is useful.
+.Pp
+If necessary,
+.Nm
+will then use the information captured by
+.Xr filemon 4 ,
+to check the modification time of any file used in generating
+the target,
+if any is newer,
+the target is out-of-date.
+.Pp
+Such deep inspection can easily lead to cases where a target is
+.Em always
+considered out-of-date, which is why
+.Va .MAKE.META.IGNORE_FILTER ,
+.Va .MAKE.META.IGNORE_PATHS
+and
+.Va .MAKE.META.IGNORE_PATTERNS ,
+are provided to limit that inspection when necessary.
 .It Cm curdirOk= Ns Ar bf
 By default,
 .Nm
@@ -2536,6 +2586,8 @@ is run with the
 flag, only
 .Ql posix.mk
 contributes to the default rules.
+In POSIX-compatible mode, the AT&T System V UNIX style substitution
+modifier is checked first rather than as a fallback.
 .It Ic .PRECIOUS
 Apply the
 .Ic .PRECIOUS
diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1
index 7e6f25524a05..e1340e1c78e0 100644
--- a/contrib/bmake/bmake.cat1
+++ b/contrib/bmake/bmake.cat1
@@ -709,11 +709,44 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
              ccoommppaatt  Like --BB, puts bbmmaakkee into "compat" mode.
 
              mmeettaa    Puts bbmmaakkee into "meta" mode, where meta files are created
-                     for each target to capture the command run, the output
+                     for each target to capture the commands run, the output
                      generated, and if filemon(4) is available, the system
                      calls which are of interest to bbmmaakkee.  The captured
                      output can be useful when diagnosing errors.
 
+                     bbmmaakkee will use the information in the meta file to help
+                     determine if a target is out-of-date when the normal
+                     dependency rules indicate it is not.
+
+                     First, the commands to be executed, will be compared to
+                     those captured previously, if any differ, the target is
+                     out-of-date.
+
+                     This allows for a huge improvement in the reliability and
+                     efficiency of update builds.  It is no longer necessary
+                     for targets to depend on makefiles just in-case they set
+                     a variable that might be relevant.  Mechanisms such as
+                     _._M_A_K_E_._M_E_T_A_._C_M_P___F_I_L_T_E_R and ..NNOOMMEETTAA__CCMMPP, allow limiting or
+                     disabling that comparison on a per target basis.  A
+                     reference to the variable _._O_O_D_A_T_E can be leveraged to
+                     block comparison of certain commands.  For example:
+                     `${.OODATE:M}' will expand to nothing and have no impact
+                     on the target, its side-effect though, will be to prevent
+                     comparison of any command line it appears on.  For
+                     documentation purposes `${.OODATE:MNOMETA_CMP}' is
+                     useful.
+
+                     If necessary, bbmmaakkee will then use the information
+                     captured by filemon(4), to check the modification time of
+                     any file used in generating the target, if any is newer,
+                     the target is out-of-date.
+
+                     Such deep inspection can easily lead to cases where a
+                     target is _a_l_w_a_y_s considered out-of-date, which is why
+                     _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___F_I_L_T_E_R, _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___P_A_T_H_S and
+                     _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___P_A_T_T_E_R_N_S, are provided to limit that
+                     inspection when necessary.
+
              ccuurrddiirrOOkk==_b_f
                      By default, bbmmaakkee does not create _._m_e_t_a files in
                      `_._C_U_R_D_I_R'.  This can be overridden by setting _b_f to a
@@ -1618,7 +1651,9 @@ SSPPEECCIIAALL TTAARRGGEETTSS
               variable _%_P_O_S_I_X is set to the value `1003.2' and the makefile
               `<posix.mk>' is included if it exists, to provide POSIX-
               compatible default rules.  If bbmmaakkee is run with the --rr flag,
-              only `posix.mk' contributes to the default rules.
+              only `posix.mk' contributes to the default rules.  In POSIX-
+              compatible mode, the AT&T System V UNIX style substitution
+              modifier is checked first rather than as a fallback.
 
      ..PPRREECCIIOOUUSS
               Apply the ..PPRREECCIIOOUUSS attribute to any specified sources.  If no
@@ -1793,4 +1828,4 @@ BBUUGGSS
      attempt to suppress a cascade of unnecessary errors, can result in a
      seemingly unexplained `*** Error code 6'
 
-FreeBSD 14.1-RELEASE-p7        November 14, 2024       FreeBSD 14.1-RELEASE-p7
+FreeBSD 14.2-RELEASE-p1          April 4, 2025         FreeBSD 14.2-RELEASE-p1
diff --git a/contrib/bmake/cond.c b/contrib/bmake/cond.c
index a724ba7ecf26..31fe21c4c8b6 100644
--- a/contrib/bmake/cond.c
+++ b/contrib/bmake/cond.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: cond.c,v 1.371 2025/01/11 21:21:33 rillig Exp $	*/
+/*	$NetBSD: cond.c,v 1.372 2025/04/10 21:41:35 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -91,7 +91,7 @@
 #include "dir.h"
 
 /*	"@(#)cond.c	8.2 (Berkeley) 1/2/94"	*/
-MAKE_RCSID("$NetBSD: cond.c,v 1.371 2025/01/11 21:21:33 rillig Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.372 2025/04/10 21:41:35 rillig Exp $");
 
 /*
  * Conditional expressions conform to this grammar:
@@ -162,12 +162,6 @@ typedef struct CondParser {
 
 	const char *p;		/* The remaining condition to parse */
 	Token curr;		/* Single push-back token used in parsing */
-
-	/*
-	 * Whether an error message has already been printed for this
-	 * condition.
-	 */
-	bool printedError;
 } CondParser;
 
 static CondResult CondParser_Or(CondParser *, bool);
@@ -243,7 +237,7 @@ ParseWord(const char **pp, bool doEval)
 
 /* Parse the function argument, including the surrounding parentheses. */
 static char *
-ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func)
+ParseFuncArg(const char **pp, bool doEval, const char *func)
 {
 	const char *p = *pp, *argStart, *argEnd;
 	char *res;
@@ -263,7 +257,6 @@ ParseFuncArg(CondParser *par, const char **pp, bool doEval, const char *func)
 		Parse_Error(PARSE_FATAL,
 		    "Missing ')' after argument '%.*s' for '%.*s'",
 		    (int)(argEnd - argStart), argStart, len, func);
-		par->printedError = true;
 		free(res);
 		return NULL;
 	}
@@ -531,15 +524,13 @@ EvalCompareNum(double lhs, ComparisonOp op, double rhs)
 }
 
 static Token
-EvalCompareStr(CondParser *par, const char *lhs,
-	       ComparisonOp op, const char *rhs)
+EvalCompareStr(const char *lhs, ComparisonOp op, const char *rhs)
 {
 	if (op != EQ && op != NE) {
 		Parse_Error(PARSE_FATAL,
 		    "Comparison with '%s' requires both operands "
 		    "'%s' and '%s' to be numeric",
 		    opname[op], lhs, rhs);
-		par->printedError = true;
 		return TOK_ERROR;
 	}
 
@@ -549,7 +540,7 @@ EvalCompareStr(CondParser *par, const char *lhs,
 
 /* Evaluate a comparison, such as "${VAR} == 12345". */
 static Token
-EvalCompare(CondParser *par, const char *lhs, bool lhsQuoted,
+EvalCompare(const char *lhs, bool lhsQuoted,
 	    ComparisonOp op, const char *rhs, bool rhsQuoted)
 {
 	double left, right;
@@ -558,7 +549,7 @@ EvalCompare(CondParser *par, const char *lhs, bool lhsQuoted,
 		if (TryParseNumber(lhs, &left) && TryParseNumber(rhs, &right))
 			return ToToken(EvalCompareNum(left, op, right));
 
-	return EvalCompareStr(par, lhs, op, rhs);
+	return EvalCompareStr(lhs, op, rhs);
 }
 
 static bool
@@ -613,14 +604,13 @@ CondParser_Comparison(CondParser *par, bool doEval)
 	if (par->p[0] == '\0') {
 		Parse_Error(PARSE_FATAL,
 		    "Missing right-hand side of operator '%s'", opname[op]);
-		par->printedError = true;
 		goto done_lhs;
 	}
 
 	rhs = CondParser_Leaf(par, doEval, true, &rhsQuoted);
 	t = rhs.str == NULL ? TOK_ERROR
 	    : !doEval ? TOK_FALSE
-	    : EvalCompare(par, lhs.str, lhsQuoted, op, rhs.str, rhsQuoted);
+	    : EvalCompare(lhs.str, lhsQuoted, op, rhs.str, rhsQuoted);
 	FStr_Done(&rhs);
 
 done_lhs:
@@ -689,7 +679,7 @@ CondParser_FuncCall(CondParser *par, bool doEval, Token *out_token)
 	if (*p != '(')
 		return false;
 
-	arg = ParseFuncArg(par, &p, doEval, fn_name);
+	arg = ParseFuncArg(&p, doEval, fn_name);
 	*out_token = ToToken(doEval &&
 	    arg != NULL && arg[0] != '\0' && fn(arg));
 	free(arg);
@@ -779,7 +769,6 @@ CondParser_Token(CondParser *par, bool doEval)
 			par->p++;
 		else {
 			Parse_Error(PARSE_FATAL, "Unknown operator '|'");
-			par->printedError = true;
 			return TOK_ERROR;
 		}
 		return TOK_OR;
@@ -790,7 +779,6 @@ CondParser_Token(CondParser *par, bool doEval)
 			par->p++;
 		else {
 			Parse_Error(PARSE_FATAL, "Unknown operator '&'");
-			par->printedError = true;
 			return TOK_ERROR;
 		}
 		return TOK_AND;
@@ -929,15 +917,13 @@ CondEvalExpression(const char *cond, bool plain,
 	par.leftUnquotedOK = leftUnquotedOK;
 	par.p = cond;
 	par.curr = TOK_NONE;
-	par.printedError = false;
 
 	DEBUG1(COND, "CondParser_Eval: %s\n", par.p);
 	rval = CondParser_Or(&par, true);
 	if (par.curr != TOK_EOF)
 		rval = CR_ERROR;
 
-	if (rval == CR_ERROR && eprint && !par.printedError
-	    && parseErrors == parseErrorsBefore)
+	if (rval == CR_ERROR && eprint && parseErrors == parseErrorsBefore)
 		Parse_Error(PARSE_FATAL, "Malformed conditional '%s'", cond);
 
 	return rval;
diff --git a/contrib/bmake/dir.c b/contrib/bmake/dir.c
index d017a89e4753..106b475bda2a 100644
--- a/contrib/bmake/dir.c
+++ b/contrib/bmake/dir.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: dir.c,v 1.295 2024/07/07 07:50:57 rillig Exp $	*/
+/*	$NetBSD: dir.c,v 1.296 2025/04/11 17:21:31 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -132,7 +132,7 @@
 #include "job.h"
 
 /*	"@(#)dir.c	8.2 (Berkeley) 1/2/94"	*/
-MAKE_RCSID("$NetBSD: dir.c,v 1.295 2024/07/07 07:50:57 rillig Exp $");
+MAKE_RCSID("$NetBSD: dir.c,v 1.296 2025/04/11 17:21:31 rillig Exp $");
 
 /*
  * A search path is a list of CachedDir structures. A CachedDir has in it the
@@ -1365,7 +1365,7 @@ ResolveMovedDepends(GNode *gn)
 	gn->path = bmake_strdup(fullName);
 	if (!Job_RunTarget(".STALE", gn->fname))
 		fprintf(stdout,	/* XXX: Why stdout? */
-		    "%s: %s, %u: ignoring stale %s for %s, found %s\n",
+		    "%s: %s:%u: ignoring stale %s for %s, found %s\n",
 		    progname, gn->fname, gn->lineno,
 		    makeDependfile, gn->name, fullName);
 
diff --git a/contrib/bmake/for.c b/contrib/bmake/for.c
index 1563c2313963..2aa1398b1c4c 100644
--- a/contrib/bmake/for.c
+++ b/contrib/bmake/for.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: for.c,v 1.182 2024/06/07 18:57:30 rillig Exp $	*/
+/*	$NetBSD: for.c,v 1.184 2025/04/11 18:08:17 rillig Exp $	*/
 
 /*
  * Copyright (c) 1992, The Regents of the University of California.
@@ -58,7 +58,7 @@
 #include "make.h"
 
 /*	"@(#)for.c	8.1 (Berkeley) 6/6/93"	*/
-MAKE_RCSID("$NetBSD: for.c,v 1.182 2024/06/07 18:57:30 rillig Exp $");
+MAKE_RCSID("$NetBSD: for.c,v 1.184 2025/04/11 18:08:17 rillig Exp $");
 
 
 typedef struct ForLoop {
@@ -148,38 +148,23 @@ IsValidInVarname(char c)
 static void
 ForLoop_ParseVarnames(ForLoop *f, const char **pp)
 {
-	const char *p = *pp;
+	const char *p = *pp, *start;
 
 	for (;;) {
-		size_t len;
-
 		cpp_skip_whitespace(&p);
 		if (*p == '\0') {
 			Parse_Error(PARSE_FATAL, "missing `in' in for");
-			while (f->vars.len > 0)
-				free(*(char **)Vector_Pop(&f->vars));
-			return;
+			goto cleanup;
 		}
 
-		for (len = 0; p[len] != '\0' && !ch_isspace(p[len]); len++) {
-			if (!IsValidInVarname(p[len])) {
-				Parse_Error(PARSE_FATAL,
-				    "invalid character '%c' "
-				    "in .for loop variable name",
-				    p[len]);
-				while (f->vars.len > 0)
-					free(*(char **)Vector_Pop(&f->vars));
-				return;
-			}
-		}
+		for (start = p; *p != '\0' && !ch_isspace(*p); p++)
+			if (!IsValidInVarname(*p))
+				goto invalid_variable_name;
 
-		if (len == 2 && p[0] == 'i' && p[1] == 'n') {
-			p += 2;
+		if (p - start == 2 && memcmp(start, "in", 2) == 0)
 			break;
-		}
 
-		*(char **)Vector_Push(&f->vars) = bmake_strldup(p, len);
-		p += len;
+		*(char **)Vector_Push(&f->vars) = bmake_strsedup(start, p);
 	}
 
 	if (f->vars.len == 0) {
@@ -188,19 +173,27 @@ ForLoop_ParseVarnames(ForLoop *f, const char **pp)
 	}
 
 	*pp = p;
+	return;
+
+invalid_variable_name:
+	Parse_Error(PARSE_FATAL,
+	    "invalid character '%c' in .for loop variable name", *p);
+cleanup:
+	while (f->vars.len > 0)
+		free(*(char **)Vector_Pop(&f->vars));
 }
 
 static bool
 ForLoop_ParseItems(ForLoop *f, const char *p)
 {
 	char *items;
+	int parseErrorsBefore = parseErrors;
 
 	cpp_skip_whitespace(&p);
 
 	items = Var_Subst(p, SCOPE_GLOBAL, VARE_EVAL);
-	/* TODO: handle errors */
-
-	f->items = Substring_Words(items, false);
+	f->items = Substring_Words(
+	    parseErrors == parseErrorsBefore ? items : "", false);
 	free(items);
 
 	if (f->items.len == 1 && Substring_IsEmpty(f->items.words[0]))
diff --git a/contrib/bmake/job.c b/contrib/bmake/job.c
index d06b1570ba85..2e6f44f722f2 100644
--- a/contrib/bmake/job.c
+++ b/contrib/bmake/job.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: job.c,v 1.489 2025/03/08 20:15:03 rillig Exp $	*/
+/*	$NetBSD: job.c,v 1.492 2025/04/12 13:00:21 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -151,7 +151,7 @@
 #include "trace.h"
 
 /*	"@(#)job.c	8.2 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: job.c,v 1.489 2025/03/08 20:15:03 rillig Exp $");
+MAKE_RCSID("$NetBSD: job.c,v 1.492 2025/04/12 13:00:21 rillig Exp $");
 
 /*
  * A shell defines how the commands are run.  All commands for a target are
@@ -427,7 +427,7 @@ static char *shell_freeIt = NULL; /* Allocated memory for custom .SHELL */
 
 static Job *job_table;		/* The structures that describe them */
 static Job *job_table_end;	/* job_table + maxJobs */
-static unsigned int wantToken;
+static bool wantToken;
 static bool lurking_children = false;
 static bool make_suspended = false; /* Whether we've seen a SIGTSTP (etc) */
 
@@ -440,7 +440,6 @@ static Job **jobByFdIndex = NULL;
 static nfds_t fdsLen = 0;
 static void watchfd(Job *);
 static void clearfd(Job *);
-static bool readyfd(Job *);
 
 static char *targPrefix = NULL;	/* To identify a job change in the output. */
 static Job tokenWaitJob;	/* token wait pseudo-job */
@@ -1250,10 +1249,7 @@ JobFinish (Job *job, WAIT_T status)
 
 	if (aborting == ABORT_ERROR && jobTokensRunning == 0) {
 		if (shouldDieQuietly(NULL, -1)) {
-			/*
-			 * TODO: better clean up properly, to avoid killing
-			 *  child processes by SIGPIPE.
-			 */
+			Job_Wait();
 			exit(2);
 		}
 		Fatal("%d error%s", job_errors, job_errors == 1 ? "" : "s");
@@ -1387,7 +1383,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
 	if (gn->flags.fromDepend) {
 		if (!Job_RunTarget(".STALE", gn->fname))
 			fprintf(stdout,
-			    "%s: %s, %u: ignoring stale %s for %s\n",
+			    "%s: %s:%u: ignoring stale %s for %s\n",
 			    progname, gn->fname, gn->lineno, makeDependfile,
 			    gn->name);
 		return true;
@@ -2046,17 +2042,17 @@ Job_CatchOutput(void)
 
 	(void)fflush(stdout);
 
-	/* Skip the first fd in the list, as it is the job token pipe. */
 	do {
-		nready = poll(fds + 1 - wantToken, fdsLen - 1 + wantToken,
-		    POLL_MSEC);
+		/* Maybe skip the job token pipe. */
+		nfds_t skip = wantToken ? 0 : 1;
+		nready = poll(fds + skip, fdsLen - skip, POLL_MSEC);
 	} while (nready < 0 && errno == EINTR);
 
 	if (nready < 0)
 		Punt("poll: %s", strerror(errno));
 
-	if (nready > 0 && readyfd(&childExitJob)) {
-		char token = 0;
+	if (nready > 0 && childExitJob.inPollfd->revents & POLLIN) {
+		char token;
 		ssize_t count = read(childExitJob.inPipe, &token, 1);
 		if (count == 1) {
 			if (token == DO_JOB_RESUME[0])
@@ -2180,7 +2176,7 @@ Job_Init(void)
 	job_table = bmake_malloc((size_t)opts.maxJobs * sizeof *job_table);
 	memset(job_table, 0, (size_t)opts.maxJobs * sizeof *job_table);
 	job_table_end = job_table + opts.maxJobs;
-	wantToken = 0;
+	wantToken = false;
 	caught_sigchld = 0;
 
 	aborting = ABORT_NONE;
@@ -2659,14 +2655,6 @@ clearfd(Job *job)
 	job->inPollfd = NULL;
 }
 
-static bool
-readyfd(Job *job)
-{
-	if (job->inPollfd == NULL)
-		Punt("Polling unwatched job");
-	return (job->inPollfd->revents & POLLIN) != 0;
-}
-
 /*
  * Put a token (back) into the job pipe.
  * This allows a make process to start a build job.
@@ -2768,7 +2756,7 @@ Job_TokenWithdraw(void)
 	char tok, tok1;
 	ssize_t count;
 
-	wantToken = 0;
+	wantToken = false;
 	DEBUG3(JOB, "Job_TokenWithdraw(%d): aborting %d, running %d\n",
 	    getpid(), aborting, jobTokensRunning);
 
@@ -2782,7 +2770,7 @@ Job_TokenWithdraw(void)
 		if (errno != EAGAIN)
 			Fatal("job pipe read: %s", strerror(errno));
 		DEBUG1(JOB, "(%d) blocked for token\n", getpid());
-		wantToken = 1;
+		wantToken = true;
 		return false;
 	}
 
diff --git a/contrib/bmake/main.c b/contrib/bmake/main.c
index 9577fb41ee7b..3f0da61caf1d 100644
--- a/contrib/bmake/main.c
+++ b/contrib/bmake/main.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.639 2025/03/07 06:50:34 rillig Exp $	*/
+/*	$NetBSD: main.c,v 1.641 2025/03/31 14:35:22 riastradh Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -108,7 +108,7 @@
 #include "trace.h"
 
 /*	"@(#)main.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: main.c,v 1.639 2025/03/07 06:50:34 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.641 2025/03/31 14:35:22 riastradh Exp $");
 #if defined(MAKE_NATIVE)
 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
 	    "The Regents of the University of California.  "
@@ -2136,12 +2136,17 @@ PrintOnError(GNode *gn, const char *msg)
 		SetErrorVars(gn);
 
 	{
-		char *errorVarsValues = Var_Subst(
+		char *errorVarsValues;
+		enum PosixState p_s = posix_state;
+
+		posix_state = PS_TOO_LATE;
+		errorVarsValues = Var_Subst(
 		    "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
 		    SCOPE_GLOBAL, VARE_EVAL);
 		/* TODO: handle errors */
 		printf("%s", errorVarsValues);
 		free(errorVarsValues);
+		posix_state = p_s;
 	}
 
 	fflush(stdout);
@@ -2160,12 +2165,15 @@ void
 Main_ExportMAKEFLAGS(bool first)
 {
 	static bool once = true;
+	enum PosixState p_s;
 	char *flags;
 
 	if (once != first)
 		return;
 	once = false;
 
+	p_s = posix_state;
+	posix_state = PS_TOO_LATE;
 	flags = Var_Subst(
 	    "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
 	    SCOPE_CMDLINE, VARE_EVAL);
@@ -2173,6 +2181,7 @@ Main_ExportMAKEFLAGS(bool first)
 	if (flags[0] != '\0')
 		setenv("MAKEFLAGS", flags, 1);
 	free(flags);
+	posix_state = p_s;
 }
 
 char *
diff --git a/contrib/bmake/make.1 b/contrib/bmake/make.1
index 869dcea3db0c..55276503aae9 100644
--- a/contrib/bmake/make.1
+++ b/contrib/bmake/make.1
@@ -1,4 +1,4 @@
-.\"	$NetBSD: make.1,v 1.381 2024/11/14 19:30:13 sjg Exp $
+.\"	$NetBSD: make.1,v 1.384 2025/04/04 18:36:47 sjg 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 November 14, 2024
+.Dd April  4, 2025
 .Dt MAKE 1
 .Os
 .Sh NAME
@@ -1098,11 +1098,61 @@ Puts
 into
 .Dq meta
 mode, where meta files are created for each target
-to capture the command run, the output generated, and if
+to capture the commands run, the output generated, and if
 .Xr filemon 4
 is available, the system calls which are of interest to
 .Nm .
 The captured output can be useful when diagnosing errors.
+.Pp
+.Nm
+will use the information in the meta file to help determine if
+a target is out-of-date when the normal dependency rules
+indicate it is not.
+.Pp
+First,
+the commands to be executed,
+will be compared to those captured previously,
+if any differ,
+the target is out-of-date.
+.Pp
+This allows for a huge improvement in the reliability
+and efficiency of update builds.
+It is no longer necessary for targets to depend on makefiles
+just in-case they set a variable that might be relevant.
+Mechanisms such as
+.Va .MAKE.META.CMP_FILTER
+and
+.Ic .NOMETA_CMP ,
+allow limiting or disabling that comparison on a per target basis.
+A reference to the variable
+.Va .OODATE
+can be leveraged to block comparison of certain commands.
+For example:
+.Ql ${.OODATE:M}
+will expand to nothing and have no impact on the target,
+its side-effect though,
+will be to prevent comparison of any command line it appears on.
+For documentation purposes
+.Ql ${.OODATE:MNOMETA_CMP}
+is useful.
+.Pp
+If necessary,
+.Nm
+will then use the information captured by
+.Xr filemon 4 ,
+to check the modification time of any file used in generating
+the target,
+if any is newer,
+the target is out-of-date.
+.Pp
+Such deep inspection can easily lead to cases where a target is
+.Em always
+considered out-of-date, which is why
+.Va .MAKE.META.IGNORE_FILTER ,
+.Va .MAKE.META.IGNORE_PATHS
+and
+.Va .MAKE.META.IGNORE_PATTERNS ,
+are provided to limit that inspection when necessary.
 .It Cm curdirOk= Ns Ar bf
 By default,
 .Nm
@@ -2547,6 +2597,8 @@ is run with the
 flag, only
 .Ql posix.mk
 contributes to the default rules.
*** 7042 LINES SKIPPED ***


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6962c5cf.25a58.4c16f0a0>