summaryrefslogtreecommitdiff
path: root/usr.bin/make/unit-tests
diff options
context:
space:
mode:
authorrillig <rillig@NetBSD.org>2022-04-18 15:06:27 +0000
committerrillig <rillig@NetBSD.org>2022-04-18 15:06:27 +0000
commit686b9d31508b5cf03b7362f4e2f8a28d78bef7d8 (patch)
treecca4fc84a4c4f12425cdf1a45acd269d02d56b3b /usr.bin/make/unit-tests
parent437e498c7a66a13ccb91525f7f4f49e68f107a3c (diff)
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 (limited to 'usr.bin/make/unit-tests')
-rw-r--r--usr.bin/make/unit-tests/Makefile3
-rw-r--r--usr.bin/make/unit-tests/deptgt-posix.exp1
-rw-r--r--usr.bin/make/unit-tests/deptgt-posix.mk116
3 files changed, 119 insertions, 1 deletions
diff --git a/usr.bin/make/unit-tests/Makefile b/usr.bin/make/unit-tests/Makefile
index d433351619b..67904fbeba8 100644
--- a/usr.bin/make/unit-tests/Makefile
+++ b/usr.bin/make/unit-tests/Makefile
@@ -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
diff --git a/usr.bin/make/unit-tests/deptgt-posix.exp b/usr.bin/make/unit-tests/deptgt-posix.exp
new file mode 100644
index 00000000000..39a9383953d
--- /dev/null
+++ b/usr.bin/make/unit-tests/deptgt-posix.exp
@@ -0,0 +1 @@
+exit status 0
diff --git a/usr.bin/make/unit-tests/deptgt-posix.mk b/usr.bin/make/unit-tests/deptgt-posix.mk
new file mode 100644
index 00000000000..0cf83acde56
--- /dev/null
+++ b/usr.bin/make/unit-tests/deptgt-posix.mk
@@ -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:'