1# $NetBSD: deptgt-posix.mk,v 1.4 2022/05/07 21:24:52 rillig Exp $
2#
3# Tests for the special target '.POSIX', which enables POSIX mode.
4#
5# As of 2022-04-18, when parsing the dependency line '.POSIX', the variable
6# '%POSIX' is defined and <posix.mk> is included, if it exists.  Other than
7# that, POSIX support is still incomplete, the exact set of supported features
8# needs to be cross-checked with the POSIX specification.
9#
10# At the point of '.POSIX:', <sys.mk> has been loaded already, unless the
11# option '-r' was given.  This means that an implementation of <posix.mk> must
12# work both with and without the system rules from <sys.mk> being in effect.
13#
14# Implementation note: this test needs to run isolated from the usual tests
15# directory to prevent unit-tests/posix.mk from interfering with the posix.mk
16# from the system directory that this test uses; since at least 1997, the
17# directive '.include <file>' has been looking in the current directory first
18# before searching the file in the system search path, as described in
19# https://gnats.netbsd.org/15163.
20#
21# See also:
22#	https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
23
24TESTTMP=	${TMPDIR:U/tmp}/make.test.deptgt-posix
25SYSDIR=		${TESTTMP}/sysdir
26MAIN_MK=	${TESTTMP}/main.mk
27INCLUDED_MK=	${TESTTMP}/included.mk
28
29all: .PHONY
30.SILENT:
31
32set-up-sysdir: .USEBEFORE
33	mkdir -p ${SYSDIR}
34	printf '%s\n' > ${SYSDIR}/sys.mk \
35	    'CC=sys-cc' \
36	    'SEEN_SYS_MK=yes'
37	printf '%s\n' > ${SYSDIR}/posix.mk \
38	    'CC=posix-cc'
39
40check-is-posix: .USE
41	printf '%s\n' >> ${MAIN_MK} \
42		'.if $${CC} != "posix-cc"' \
43		'.  error' \
44		'.endif' \
45		'.if $${%POSIX} != "1003.2"' \
46		'.  error' \
47		'.endif' \
48		'all: .PHONY'
49
50check-not-posix: .USE
51	printf '%s\n' >> ${MAIN_MK} \
52		'.if $${CC} != "sys-cc"' \
53		'.  error' \
54		'.endif' \
55		'.if defined(%POSIX)' \
56		'.  error' \
57		'.endif' \
58		'all: .PHONY'
59
60check-not-seen-sys-mk: .USE
61	printf '%s\n' >> ${MAIN_MK} \
62	    '.if defined(SEEN_SYS_MK)' \
63	    '.  error' \
64	    '.endif'
65
66run: .USE
67	(cd "${TESTTMP}" && MAKEFLAGS=${MAKEFLAGS.${.TARGET}:Q} ${MAKE} \
68	    -m "${SYSDIR}" -f ${MAIN_MK:T})
69	rm -rf ${TESTTMP}
70
71# If the main makefile has a '.for' loop as its first non-comment line, a
72# strict reading of POSIX 2018 makes the makefile non-conforming.
73all: after-for
74after-for: .PHONY set-up-sysdir check-not-posix run
75	printf '%s\n' > ${MAIN_MK} \
76	    '# comment' \
77	    '' \
78	    '.for i in once' \
79	    '.POSIX:' \
80	    '.endfor'
81
82# If the main makefile has an '.if' conditional as its first non-comment line,
83# a strict reading of POSIX 2018 makes the makefile non-conforming.
84all: after-if
85after-if: .PHONY set-up-sysdir check-not-posix run
86	printf '%s\n' > ${MAIN_MK} \
87	    '# comment' \
88	    '' \
89	    '.if 1' \
90	    '.POSIX:' \
91	    '.endif'
92
93# If the main makefile first includes another makefile and that included
94# makefile tries to switch to POSIX mode, that's too late.
95all: in-included-file
96in-included-file: .PHONY set-up-sysdir check-not-posix run
97	printf 'include included.mk\n' > ${MAIN_MK}
98	printf '.POSIX:\n' > ${INCLUDED_MK}
99
100# If the main makefile switches to POSIX mode in its very first line, before
101# and comment lines or empty lines, that works.
102all: in-first-line
103in-first-line: .PHONY set-up-sysdir check-is-posix run
104	printf '%s\n' > ${MAIN_MK} \
105	    '.POSIX:'
106
107# The only allowed lines before switching to POSIX mode are comment lines.
108# POSIX defines comment lines as "blank lines, empty lines, and lines with
109# <number-sign> ('#') as the first character".
110all: after-comment-lines
111after-comment-lines: .PHONY set-up-sysdir check-is-posix run
112	printf '%s\n' > ${MAIN_MK} \
113	    '# comment' \
114	    '' \
115	    '.POSIX:'
116
117# Running make with the option '-r' skips the builtin rules from <sys.mk>.
118# In that mode, '.POSIX:' just loads <posix.mk>, which works as well.
119MAKEFLAGS.no-builtins=	-r
120all: no-builtins
121no-builtins: .PHONY set-up-sysdir check-is-posix check-not-seen-sys-mk run
122	printf '%s\n' > ${MAIN_MK} \
123	    '.POSIX:'
124