Module Name: src
Committed By: rillig
Date: Mon Apr 18 15:06:28 UTC 2022
Modified Files:
src/distrib/sets/lists/tests: mi
src/usr.bin/make: main.c make.1 make.h parse.c
src/usr.bin/make/unit-tests: Makefile
Added Files:
src/usr.bin/make/unit-tests: deptgt-posix.exp deptgt-posix.mk
Log Message:
make: only switch to POSIX mode if '.POSIX:' is the first line
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
says that in order to make a makefile POSIX-conforming, its first
non-comment line must be the special dependency line '.POSIX:' without
any source dependencies.
Previously, make switched to POSIX mode even if such a line occurred
anywhere else, which was allowed by POSIX but was deep in the
"unspecified behavior" area. For NetBSD make, there is no big
difference since it doesn't ship any <posix.mk> file, this change mainly
affects the bmake distribution.
Previously, makefiles that contain '.POSIX:' somewhere in the middle
could fail due to <posix.mk> resetting .SUFFIXES, among other things.
Suggested by Simon J. Gerraty, who also reviewed an earlier version of
this change.
To generate a diff of this commit:
cvs rdiff -u -r1.1192 -r1.1193 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.579 -r1.580 src/usr.bin/make/main.c
cvs rdiff -u -r1.307 -r1.308 src/usr.bin/make/make.1
cvs rdiff -u -r1.299 -r1.300 src/usr.bin/make/make.h
cvs rdiff -u -r1.668 -r1.669 src/usr.bin/make/parse.c
cvs rdiff -u -r1.311 -r1.312 src/usr.bin/make/unit-tests/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.bin/make/unit-tests/deptgt-posix.exp \
src/usr.bin/make/unit-tests/deptgt-posix.mk
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.1192 src/distrib/sets/lists/tests/mi:1.1193
--- src/distrib/sets/lists/tests/mi:1.1192 Fri Apr 8 23:35:52 2022
+++ src/distrib/sets/lists/tests/mi Mon Apr 18 15:06:27 2022
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1192 2022/04/08 23:35:52 riastradh Exp $
+# $NetBSD: mi,v 1.1193 2022/04/18 15:06:27 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -5565,6 +5565,8 @@
./usr/tests/usr.bin/make/unit-tests/deptgt-path.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-phony.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-phony.mk tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/deptgt-posix.exp tests-usr.bin-tests compattestfile,atf
+./usr/tests/usr.bin/make/unit-tests/deptgt-posix.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-precious.exp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-precious.mk tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/make/unit-tests/deptgt-shell.exp tests-usr.bin-tests compattestfile,atf
Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.579 src/usr.bin/make/main.c:1.580
--- src/usr.bin/make/main.c:1.579 Tue Mar 22 23:37:09 2022
+++ src/usr.bin/make/main.c Mon Apr 18 15:06:27 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.579 2022/03/22 23:37:09 rillig Exp $ */
+/* $NetBSD: main.c,v 1.580 2022/04/18 15:06:27 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -111,7 +111,7 @@
#include "trace.h"
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: main.c,v 1.579 2022/03/22 23:37:09 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.580 2022/04/18 15:06:27 rillig Exp $");
#if defined(MAKE_NATIVE) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
"The Regents of the University of California. "
@@ -1480,6 +1480,7 @@ main_ReadFiles(void)
if (!opts.noBuiltins)
ReadBuiltinRules();
+ posix_state = PS_MAYBE_NEXT_LINE;
if (!Lst_IsEmpty(&opts.makefiles))
ReadAllMakefiles(&opts.makefiles);
else
Index: src/usr.bin/make/make.1
diff -u src/usr.bin/make/make.1:1.307 src/usr.bin/make/make.1:1.308
--- src/usr.bin/make/make.1:1.307 Sat Mar 26 15:39:58 2022
+++ src/usr.bin/make/make.1 Mon Apr 18 15:06:27 2022
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.307 2022/03/26 15:39:58 sjg Exp $
+.\" $NetBSD: make.1,v 1.308 2022/04/18 15:06:27 rillig 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 March 24, 2022
+.Dd April 18, 2022
.Dt MAKE 1
.Os
.Sh NAME
@@ -2290,17 +2290,15 @@ Apply the
.Ic .PHONY
attribute to any specified sources.
.It Ic .POSIX
-This should be the first non-comment line in a Makefile.
-It results in the variable
+If this is the first non-comment line in the main makefile,
+the variable
.Va %POSIX
-being defined with the value
-.Ql 1003.2 .
-The first time
-.Ic .POSIX
-is encountered, the makefile
-.Ql posix.mk
-will be included if possible,
-to provide POSIX compatible default rules.
+is set to the value
+.Ql 1003.2
+and the makefile
+.Ql <posix.mk>
+is included if it exists,
+to provide POSIX-compatible default rules.
If
.Nm
is run with the
Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.299 src/usr.bin/make/make.h:1.300
--- src/usr.bin/make/make.h:1.299 Sat Mar 26 14:02:40 2022
+++ src/usr.bin/make/make.h Mon Apr 18 15:06:27 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.299 2022/03/26 14:02:40 rillig Exp $ */
+/* $NetBSD: make.h,v 1.300 2022/04/18 15:06:27 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -506,6 +506,17 @@ typedef struct GNode {
unsigned lineno;
} GNode;
+/*
+ * Keep track of whether to include <posix.mk> when parsing the line
+ * '.POSIX:'.
+ */
+extern enum PosixState {
+ PS_NOT_YET,
+ PS_MAYBE_NEXT_LINE,
+ PS_NOW_OR_NEVER,
+ PS_TOO_LATE
+} posix_state;
+
/* Error levels for diagnostics during parsing. */
typedef enum ParseErrorLevel {
/*
Index: src/usr.bin/make/parse.c
diff -u src/usr.bin/make/parse.c:1.668 src/usr.bin/make/parse.c:1.669
--- src/usr.bin/make/parse.c:1.668 Fri Mar 25 21:16:04 2022
+++ src/usr.bin/make/parse.c Mon Apr 18 15:06:27 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.668 2022/03/25 21:16:04 sjg Exp $ */
+/* $NetBSD: parse.c,v 1.669 2022/04/18 15:06:27 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -106,7 +106,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.668 2022/03/25 21:16:04 sjg Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.669 2022/04/18 15:06:27 rillig Exp $");
/*
* A file being read.
@@ -294,6 +294,7 @@ static const struct {
{ ".WAIT", SP_WAIT, OP_NONE },
};
+enum PosixState posix_state = PS_NOT_YET;
static IncludedFile *
GetInclude(size_t i)
@@ -1252,23 +1253,9 @@ HandleDependencySourcesEmpty(ParseSpecia
break;
#ifdef POSIX
case SP_POSIX:
- Global_Set("%POSIX", "1003.2");
- {
- static bool first_posix = true;
-
- /*
- * Since .POSIX: should be the first
- * operative line in a makefile,
- * if '-r' flag is used, no default rules have
- * been read yet, in which case 'posix.mk' can
- * be a substiute for 'sys.mk'.
- * If '-r' is not used, then 'posix.mk' acts
- * as an extension of 'sys.mk'.
- */
- if (first_posix) {
- first_posix = false;
- IncludeFile("posix.mk", true, false, true);
- }
+ if (posix_state == PS_NOW_OR_NEVER) {
+ Global_Set("%POSIX", "1003.2");
+ IncludeFile("posix.mk", true, false, true);
}
break;
#endif
@@ -2590,6 +2577,10 @@ ReadHighLevelLine(void)
for (;;) {
line = ReadLowLevelLine(LK_NONEMPTY);
+ if (posix_state == PS_MAYBE_NEXT_LINE)
+ posix_state = PS_NOW_OR_NEVER;
+ else
+ posix_state = PS_TOO_LATE;
if (line == NULL)
return NULL;
Index: src/usr.bin/make/unit-tests/Makefile
diff -u src/usr.bin/make/unit-tests/Makefile:1.311 src/usr.bin/make/unit-tests/Makefile:1.312
--- src/usr.bin/make/unit-tests/Makefile:1.311 Sat Mar 26 12:44:57 2022
+++ src/usr.bin/make/unit-tests/Makefile Mon Apr 18 15:06:28 2022
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.311 2022/03/26 12:44:57 rillig Exp $
+# $NetBSD: Makefile,v 1.312 2022/04/18 15:06:28 rillig Exp $
#
# Unit tests for make(1)
#
@@ -143,6 +143,7 @@ TESTS+= deptgt-order
TESTS+= deptgt-path
TESTS+= deptgt-path-suffix
TESTS+= deptgt-phony
+TESTS+= deptgt-posix
TESTS+= deptgt-precious
TESTS+= deptgt-shell
TESTS+= deptgt-silent
Added files:
Index: src/usr.bin/make/unit-tests/deptgt-posix.exp
diff -u /dev/null src/usr.bin/make/unit-tests/deptgt-posix.exp:1.1
--- /dev/null Mon Apr 18 15:06:28 2022
+++ src/usr.bin/make/unit-tests/deptgt-posix.exp Mon Apr 18 15:06:28 2022
@@ -0,0 +1 @@
+exit status 0
Index: src/usr.bin/make/unit-tests/deptgt-posix.mk
diff -u /dev/null src/usr.bin/make/unit-tests/deptgt-posix.mk:1.1
--- /dev/null Mon Apr 18 15:06:28 2022
+++ src/usr.bin/make/unit-tests/deptgt-posix.mk Mon Apr 18 15:06:28 2022
@@ -0,0 +1,116 @@
+# $NetBSD: deptgt-posix.mk,v 1.1 2022/04/18 15:06:28 rillig Exp $
+#
+# Tests for the special target '.POSIX', which enables POSIX mode.
+#
+# As of 2022-04-18, this only means that the variable '%POSIX' is defined and
+# that the variables and rules specified by POSIX replace the default ones.
+# This is done by loading <posix.mk>, if available. That file is not included
+# in NetBSD, but only in the bmake distribution. As of 2022-04-18, POSIX
+# support is not complete.
+#
+# Implementation node: this test needs to be isolated from the usual test
+# to prevent unit-tests/posix.mk from interfering with the posix.mk from the
+# system directory that this test uses.
+#
+# See also:
+# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
+
+TMPDIR?= /tmp/make.test.deptgt-posix
+SYSDIR= ${TMPDIR}/sysdir
+MAIN_MK= ${TMPDIR}/main.mk
+INCLUDED_MK= ${TMPDIR}/included.mk
+
+all: .PHONY
+.SILENT:
+
+set-up-sysdir: .USEBEFORE
+ mkdir -p ${SYSDIR}
+ printf '%s\n' > ${SYSDIR}/sys.mk \
+ 'CC=sys-cc' \
+ 'SEEN_SYS_MK=yes'
+ printf '%s\n' > ${SYSDIR}/posix.mk \
+ 'CC=posix-cc'
+
+check-is-posix: .USE
+ printf '%s\n' >> ${MAIN_MK} \
+ '.if $${CC} != "posix-cc"' \
+ '. error' \
+ '.endif' \
+ '.if $${%POSIX} != "1003.2"' \
+ '. error' \
+ '.endif' \
+ 'all: .PHONY'
+
+check-not-posix: .USE
+ printf '%s\n' >> ${MAIN_MK} \
+ '.if $${CC} != "sys-cc"' \
+ '. error' \
+ '.endif' \
+ '.if defined(%POSIX)' \
+ '. error' \
+ '.endif' \
+ 'all: .PHONY'
+
+check-not-seen-sys-mk: .USE
+ printf '%s\n' >> ${MAIN_MK} \
+ '.if defined(SEEN_SYS_MK)' \
+ '. error' \
+ '.endif'
+
+run: .USE
+ (cd "${TMPDIR}" && MAKEFLAGS=${MAKEFLAGS.${.TARGET}:Q} ${MAKE} \
+ -m "${SYSDIR}" -f ${MAIN_MK:T})
+ rm -rf ${TMPDIR}
+
+# If the main makefile has a '.for' loop as its first non-comment line, a
+# strict reading of POSIX 2018 makes the makefile non-conforming.
+all: after-for
+after-for: .PHONY set-up-sysdir check-not-posix run
+ printf '%s\n' > ${MAIN_MK} \
+ '# comment' \
+ '' \
+ '.for i in once' \
+ '.POSIX:' \
+ '.endfor'
+
+# If the main makefile has an '.if' conditional as its first non-comment line,
+# a strict reading of POSIX 2018 makes the makefile non-conforming.
+all: after-if
+after-if: .PHONY set-up-sysdir check-not-posix run
+ printf '%s\n' > ${MAIN_MK} \
+ '# comment' \
+ '' \
+ '.if 1' \
+ '.POSIX:' \
+ '.endif'
+
+# If the main makefile first includes another makefile and that included
+# makefile tries to switch to POSIX mode, that's too late.
+all: in-included-file
+in-included-file: .PHONY set-up-sysdir check-not-posix run
+ printf 'include included.mk\n' > ${MAIN_MK}
+ printf '.POSIX:\n' > ${INCLUDED_MK}
+
+# If the main makefile switches to POSIX mode in its very first line, before
+# and comment lines or empty lines, that works.
+all: in-first-line
+in-first-line: .PHONY set-up-sysdir check-is-posix run
+ printf '%s\n' > ${MAIN_MK} \
+ '.POSIX:'
+
+# The only allowed lines before switching to POSIX mode are comment lines.
+# POSIX defines that empty and blank lines are called comment lines as well.
+all: after-comment-lines
+after-comment-lines: .PHONY set-up-sysdir check-is-posix run
+ printf '%s\n' > ${MAIN_MK} \
+ '# comment' \
+ '' \
+ '.POSIX:'
+
+# Running make with the option '-r' skips the builtin rules from <sys.mk>.
+# In that mode, '.POSIX:' just loads <posix.mk>, which works as well.
+MAKEFLAGS.no-builtins= -r
+all: no-builtins
+no-builtins: .PHONY set-up-sysdir check-is-posix check-not-seen-sys-mk run
+ printf '%s\n' > ${MAIN_MK} \
+ '.POSIX:'