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.
This commit is contained in:
parent
3b7543fb74
commit
ddac43c43f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
/*
|
||||
|
|
|
@ -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(ParseSpecial special, SearchPathList *paths)
|
|||
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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
exit status 0
|
|
@ -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:'
|
Loading…
Reference in New Issue