Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make/unit-tests make: only switch to POSIX mode if '...



details:   https://anonhg.NetBSD.org/src/rev/8402dbf21f56
branches:  trunk
changeset: 365696:8402dbf21f56
user:      rillig <rillig%NetBSD.org@localhost>
date:      Mon Apr 18 15:06:27 2022 +0000

description:
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.

diffstat:

 distrib/sets/lists/tests/mi              |    4 +-
 usr.bin/make/main.c                      |    5 +-
 usr.bin/make/make.1                      |   22 ++---
 usr.bin/make/make.h                      |   13 +++-
 usr.bin/make/parse.c                     |   29 ++-----
 usr.bin/make/unit-tests/Makefile         |    3 +-
 usr.bin/make/unit-tests/deptgt-posix.exp |    1 +
 usr.bin/make/unit-tests/deptgt-posix.mk  |  116 +++++++++++++++++++++++++++++++
 8 files changed, 157 insertions(+), 36 deletions(-)

diffs (truncated from 321 to 300 lines):

diff -r 7ab5ba4e0437 -r 8402dbf21f56 distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi       Mon Apr 18 14:41:42 2022 +0000
+++ b/distrib/sets/lists/tests/mi       Mon Apr 18 15:06:27 2022 +0000
@@ -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
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/main.c
--- a/usr.bin/make/main.c       Mon Apr 18 14:41:42 2022 +0000
+++ b/usr.bin/make/main.c       Mon Apr 18 15:06:27 2022 +0000
@@ -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 @@
        if (!opts.noBuiltins)
                ReadBuiltinRules();
 
+       posix_state = PS_MAYBE_NEXT_LINE;
        if (!Lst_IsEmpty(&opts.makefiles))
                ReadAllMakefiles(&opts.makefiles);
        else
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/make.1
--- a/usr.bin/make/make.1       Mon Apr 18 14:41:42 2022 +0000
+++ b/usr.bin/make/make.1       Mon Apr 18 15:06:27 2022 +0000
@@ -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 @@
 .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
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/make.h
--- a/usr.bin/make/make.h       Mon Apr 18 14:41:42 2022 +0000
+++ b/usr.bin/make/make.h       Mon Apr 18 15:06:27 2022 +0000
@@ -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 @@
        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 {
        /*
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c      Mon Apr 18 14:41:42 2022 +0000
+++ b/usr.bin/make/parse.c      Mon Apr 18 15:06:27 2022 +0000
@@ -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 @@
     { ".WAIT",         SP_WAIT,        OP_NONE },
 };
 
+enum PosixState posix_state = PS_NOT_YET;
 
 static IncludedFile *
 GetInclude(size_t i)
@@ -1252,23 +1253,9 @@
                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 @@
 
        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;
 
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/unit-tests/Makefile
--- a/usr.bin/make/unit-tests/Makefile  Mon Apr 18 14:41:42 2022 +0000
+++ b/usr.bin/make/unit-tests/Makefile  Mon Apr 18 15:06:27 2022 +0000
@@ -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-path
 TESTS+=                deptgt-path-suffix
 TESTS+=                deptgt-phony
+TESTS+=                deptgt-posix
 TESTS+=                deptgt-precious
 TESTS+=                deptgt-shell
 TESTS+=                deptgt-silent
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/unit-tests/deptgt-posix.exp
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/deptgt-posix.exp  Mon Apr 18 15:06:27 2022 +0000
@@ -0,0 +1,1 @@
+exit status 0
diff -r 7ab5ba4e0437 -r 8402dbf21f56 usr.bin/make/unit-tests/deptgt-posix.mk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.bin/make/unit-tests/deptgt-posix.mk   Mon Apr 18 15:06:27 2022 +0000
@@ -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.



Home | Main Index | Thread Index | Old Index