Condider the following Makefile (where prog.c is hello-world): .POSIX: prog: prog.o echo $(%POSIX) $(CC) -o prog prog.o clean: rm -f prog prog.o When I run 'make' this is what is done: $ make cc -O -pipe -c prog.c echo 1003.2 1003.2 cc -o prog prog.o However, /usr/share/mk/sys.mk says: # from: @(#)sys.mk 8.2 (Berkeley) 3/21/94 # $Id: sys.mk,v 1.43 1998/09/15 05:24:01 obrien Exp $ unix ?= We run FreeBSD, not UNIX. # If the special target .POSIX appears (without prerequisites or # commands) before the first noncomment line in the makefile, make shall # process the makefile as specified by the Posix 1003.2 specification. # make(1) sets the special macro %POSIX in this case (to the actual # value "1003.2", for what it's worth). # # The rules below use this macro to distinguish between Posix-compliant # and default behaviour. ... .if defined(%POSIX) CC ?= c89 .else CC ?= cc .endif CFLAGS ?= -O -pipe ... Thus, I expect CC to be c89 (I can't see where CC is set from actually). What's more, as soon as c89 is used, CFLAGS must not contain non-POSIX compiler options like -pipe, because otherwise c89 rightfully barfs: $ make CC=c89 c89 -O -pipe -c prog.c Illegal option -p usage: c89 [-c] [-D name[=value]] [...] [-E] [-g] [-I directory ...] [-L directory ...] [-o outfile] [-O] [-s] [-U name ...] operand ... *** Error code 64 Stop. I tried 'make -d A' for debugging, but CC=cc seems to be set in some global place: $ make -d A Global:.MAKEFLAGS = -d Global:.MAKEFLAGS = -d A Global:.TARGETS = Caching /usr/share/mk...done expanding "sys.mk".../usr/share/mk/sys.mk Global:MAKEFILE = /usr/share/mk/sys.mk Global:unix = We run FreeBSD, not UNIX. Global:X11BASE = /usr/X11R6 Global:AR = ar Global:ARFLAGS = rl Global:RANLIB = ranlib Global:AS = as Global:AFLAGS = Global:CC = cc <----- why is this not c89? ...etc It seems the .if defined(%POSIX) doesn't work properly. Or I have overlooked something. Or something funny is going on. Regards, Jens -- Jens Schweikhardt http://www.shuttle.de/schweikh/ SIGSIG -- signature too long (core dumped)
Jens Schweikhardt wrote: > > >Number: 11114 > >Category: bin > >Synopsis: make(1) does not work as documented with .POSIX: target I didn't see any mention of the .POSIX target in make(1). What do you mean by "documented"? -- Daniel C. Sobral (8-DCS) dcs@newsguy.com dcs@freebsd.org "nothing better than the ability to perform cunning linguistics"
Responsible Changed From-To: freebsd-bugs->will Over to MAINTAINER.
Regarding Daniel's question about what I mean with documented: From make(1) I conclude that the make utility aims at POSIX conformance: COMPATIBILITY Older versions of make used MAKE instead of MAKEFLAGS. This was removed for POSIX compatibility. I have considered the quoted parts from /usr/share/mk/sys.mk as further documentation on how make behaves when .POSIX: is used. As I have demonstrated, the text in /usr/share/mk/sys.mk disagrees with how make actually behaves. Specifically, # If the special target .POSIX appears (without prerequisites or # commands) before the first noncomment line in the makefile, make shall # process the makefile as specified by the Posix 1003.2 specification. 1003.2 requires c89 (not cc) be used for compilation. sys.mk even tries to do just that with .if defined(%POSIX) CC ?= c89 .else CC ?= cc .endif but for some reason, cc is used no matter whether .POSIX: is specified or not. Regards, Jens -- Jens Schweikhardt http://www.schweikhardt.net/ SIGSIG -- signature too long (core dumped)
Responsible Changed From-To: will->freebsd-bugs I don't have time for make(1) anymore...
State Changed From-To: open->feedback Does this problem still exist?
Yes, this problem still persists. Please note that my email address has changed from schweikh@noc.dfn.de to @schweikhardt.net. hal9000:/home/schweikh/tmp # make cc -O -pipe -c prog.c echo 1003.2 1003.2 cc -o prog prog.o uname -a FreeBSD hal9000.schweikhardt.net 5.0-CURRENT FreeBSD 5.0-CURRENT #2: Tue Dec 4 22:18:01 CET 2001 toor@hal9000.schweikhardt.net:/usr/obj/src/current/sys/HAL9000 i386 Another point to take into consideration: while for POSIX 1990 CC must be c89, for the now ratified POSIX 2001 CC must be c99. Regards, Jens -- Jens Schweikhardt http://www.schweikhardt.net/ SIGSIG -- signature too long (core dumped)
State Changed From-To: feedback->open Feedback from author: yes, problem still persists identically. (BTW: modified author's email in a few places because it changed. I hope this won't confuse gnats.)
The issue here is that the .POSIX target will not have its effect until the makefile containing it is read. /usr/share/mk/sys.mk is the first file read. make(1) doesn't know about anything that you have set in your makefile yet. I have no idea if that is a bug or feature. What do the standards say (if anything)? -- Crist J. Clark | cjclark@alum.mit.edu | cjclark@jhu.edu http://people.freebsd.org/~cjc/ | cjc@freebsd.org
Crist, On Wed, Feb 20, 2002 at 08:23:16AM -0800, Crist J. Clark wrote: # The issue here is that the .POSIX target will not have its effect # until the makefile containing it is read. /usr/share/mk/sys.mk is the # first file read. make(1) doesn't know about anything that you have set # in your makefile yet. # # I have no idea if that is a bug or feature. What do the standards say # (if anything)? The POSIX 2001 Standard defines the behavior of make and mandates that the macros have the following values, when .POSIX: is specified as the first noncomment line and without prerequisites and commands: MAKE=make AR=ar ARFLAGS=-rv YACC=yacc YFLAGS= LEX=lex LFLAGS= LDFLAGS= CC=c99 CFLAGS=-O FC=fort77 FFLAGS=-O 1 GET=get GFLAGS= SCCSFLAGS= SCCSGETFLAGS=-a Regards, Jens -- Jens Schweikhardt http://www.schweikhardt.net/ SIGSIG -- signature too long (core dumped)
On Fri, Feb 22, 2002 at 08:28:50PM +0100, Jens Schweikhardt wrote: > Crist, > > On Wed, Feb 20, 2002 at 08:23:16AM -0800, Crist J. Clark wrote: > # The issue here is that the .POSIX target will not have its effect > # until the makefile containing it is read. /usr/share/mk/sys.mk is the > # first file read. make(1) doesn't know about anything that you have set > # in your makefile yet. > # > # I have no idea if that is a bug or feature. What do the standards say > # (if anything)? > > The POSIX 2001 Standard defines the behavior of make and mandates that > the macros have the following values, when .POSIX: is specified as the > first noncomment line and without prerequisites and commands: Right, but what is the exact wording? All of this does work when the ".POSIX" target is set in sys.mk. In exactly which makefile is the ".POSIX" target supposed to work? If it is in the local one, this is a real problem. Goes against the whole way makefiles are processed. -- Crist J. Clark | cjclark@alum.mit.edu | cjclark@jhu.edu http://people.freebsd.org/~cjc/ | cjc@freebsd.org
On Sat, Feb 23, 2002 at 12:04:44AM -0800, Crist J. Clark wrote: # On Fri, Feb 22, 2002 at 08:28:50PM +0100, Jens Schweikhardt wrote: # > Crist, # > # > On Wed, Feb 20, 2002 at 08:23:16AM -0800, Crist J. Clark wrote: # > # The issue here is that the .POSIX target will not have its effect # > # until the makefile containing it is read. /usr/share/mk/sys.mk is the # > # first file read. make(1) doesn't know about anything that you have set # > # in your makefile yet. # > # # > # I have no idea if that is a bug or feature. What do the standards say # > # (if anything)? # > # > The POSIX 2001 Standard defines the behavior of make and mandates that # > the macros have the following values, when .POSIX: is specified as the # > first noncomment line and without prerequisites and commands: # # Right, but what is the exact wording? ".POSIX The application shall ensure that this special target is specified without prerequisites or commands. If it appears as the first non-comment line in the makefile, make shall process the makefile as specified by this section; otherwise, the behavior of make is unspecified." Later on it mentions the list of variables and their values. # All of this does work when the # ".POSIX" target is set in sys.mk. In exactly which makefile is the # ".POSIX" target supposed to work? The application programmer's. See the example in the PR. # If it is in the local one, this is a # real problem. Goes against the whole way makefiles are processed. I'm not sure what you mean with "local makefile". Regards, Jens -- Jens Schweikhardt http://www.schweikhardt.net/ SIGSIG -- signature too long (core dumped)
Please try this patch & let me know whether it corrects the problems with the special .POSIX target. It is against HEAD, to try it on a 4.x release you will need to edit str.c and remove __DECONST macro usage. I realise it's not a particularly clean solution, and I'd be interested to hear how it could be done better. Index: main.c =================================================================== RCS file: /home/ncvs/src/usr.bin/make/main.c,v retrieving revision 1.56 diff -u -r1.56 main.c --- main.c 2002/04/13 12:20:51 1.56 +++ main.c 2002/04/18 06:25:35 @@ -113,7 +113,7 @@ GNode *DEFAULT; /* .DEFAULT node */ Boolean allPrecious; /* .PRECIOUS given on line by itself */ -static Boolean noBuiltins; /* -r flag */ +Boolean noBuiltins; /* -r flag */ static Lst makefiles; /* ordered list of makefiles to read */ static Boolean printVars; /* print value of one or more vars */ static Boolean expandVars; /* fully expand printed variables */ @@ -138,7 +138,6 @@ static void MainParseArgs(int, char **); char * chdir_verify_path(char *, char *); -static int ReadMakefile(void *, void *); static void usage(void); static char *curdir; /* startup directory */ @@ -728,22 +727,9 @@ } /* - * Read in the built-in rules first, followed by the specified - * makefile, if it was (makefile != (char *) NULL), or the default - * Makefile and makefile, in that order, if it wasn't. + * Read the specified makefile, if it was (makefile != (char *) NULL), + * or the default Makefile and makefile, in that order, if it wasn't. */ - if (!noBuiltins) { - LstNode ln; - - sysMkPath = Lst_Init (FALSE); - Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath); - if (Lst_IsEmpty(sysMkPath)) - Fatal("make: no system rules (%s).", _PATH_DEFSYSMK); - ln = Lst_Find(sysMkPath, (void *)NULL, ReadMakefile); - if (ln != NULL) - Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); - } - if (!Lst_IsEmpty(makefiles)) { LstNode ln; @@ -899,7 +885,7 @@ * Side Effects: * lots */ -static Boolean +Boolean ReadMakefile(p, q) void *p; void *q; Index: make.h =================================================================== RCS file: /home/ncvs/src/usr.bin/make/make.h,v retrieving revision 1.17 diff -u -r1.17 make.h --- make.h 2002/04/13 10:57:56 1.17 +++ make.h 2002/04/18 06:25:36 @@ -293,6 +293,8 @@ * anything, just see if the targets are out- * of-date */ +extern Boolean noBuiltins; /* TRUE if sys.mk should not be sourced */ + extern Boolean checkEnvFirst; /* TRUE if environment should be searched for * all variables before the global context */ extern Lst envFirstVars; /* List of specific variables for which the @@ -353,5 +355,6 @@ void Make_Update(GNode *); void Make_DoAllVar(GNode *); Boolean Make_Run(Lst); +int ReadMakefile(void *, void *); #endif /* _MAKE_H_ */ Index: parse.c =================================================================== RCS file: /home/ncvs/src/usr.bin/make/parse.c,v retrieving revision 1.32 diff -u -r1.32 parse.c --- parse.c 2002/04/13 10:17:17 1.32 +++ parse.c 2002/04/18 06:25:42 @@ -252,6 +252,7 @@ static char *ParseReadLine(void); static char *ParseSkipLine(int); static void ParseFinishLine(void); +static void ParseSysMk(void); /*- *---------------------------------------------------------------------- @@ -2354,6 +2355,50 @@ } } +/*- + *----------------------------------------------------------------------- + * ParseSysMk -- + * Read and parse the builtin rules file (sys.mk) + * + * Results: + * Nothing. + * + * Side Effects: + * Same as Parse_File(): dependencies added, variables set, etc. + * + *----------------------------------------------------------------------- + */ +void +ParseSysMk(void) +{ + LstNode ln; + Lst sysMkPath; + Boolean old_inLine; + int old_lineno; + char *old_fname; + FILE *old_curFILE; + + /* Save parser globals before Parse_File() clobbers them */ + old_inLine = inLine; + old_lineno = lineno; + old_fname = fname; + old_curFILE = curFILE; + + /* Parse rules from sys.mk */ + sysMkPath = Lst_Init (FALSE); + Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath); + if (Lst_IsEmpty(sysMkPath)) + Fatal("make: no system rules (%s).", _PATH_DEFSYSMK); + ln = Lst_Find(sysMkPath, (void *)NULL, ReadMakefile); + if (ln != NULL) + Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); + + /* Restore globals */ + inLine = old_inLine; + lineno = old_lineno; + curFILE = old_curFILE; + fname = old_fname; +} /*- *--------------------------------------------------------------------- @@ -2375,6 +2420,7 @@ char *name; /* the name of the file being read */ FILE * stream; /* Stream open to makefile to parse */ { + static int donesysmk; char *cp, /* pointer into the line */ *line; /* the line we're working on */ @@ -2386,6 +2432,20 @@ do { while ((line = ParseReadLine ()) != NULL) { + /* + * Read sys.mk right before we parse the first line that isn't + * either a comment, blank, or .POSIX. The .POSIX pseudo-target + * sets a variable that affects what sys.mk defines. + */ + if (!donesysmk) { + for (cp = line; isspace(*cp); cp++) + ; + if (*cp != '#' && *cp != '\0' && !noBuiltins && + strncmp(line, ".POSIX", 6) != 0) { + donesysmk = 1; + ParseSysMk(); + } + } if (*line == '.') { /* * Lines that begin with the special character are either
Responsible Changed From-To: freebsd-bugs->freebsd-standards Recategorise
On Thu, Apr 18, 2002 at 03:50:09PM +1000, Tim J. Robbins wrote: > Please try this patch & let me know whether it corrects the problems > with the special .POSIX target. It is against HEAD, to try it on a 4.x > release you will need to edit str.c and remove __DECONST macro usage. > I realise it's not a particularly clean solution, and I'd be interested > to hear how it could be done better. > I think in the current architecture of make(1), that's probably on the right track to doing it, assuming the Startup()/Cleanup() style thing cannot be done or that it won't work. Does any software include a Makefile that does the .POSIX thing? If so, check and see if this works as expected, and check that it can get through a buildworld (at least as much as normal make(1) - heh), and that there's no significant regression, and I'd say you can pretty much go this way, though you might want to add some DEBUG() stuff, as the codepath is a little obscured, to me anyway. I guess that's all I can think to say right now. -- jmallett@FreeBSD.org | C, MIPS, POSIX, UNIX, BSD, IRC Geek. http://www.FreeBSD.org | The Power to Serve "We all need mirrors to remind ourselves who we are -- I'm no different."
State Changed From-To: open->feedback Solution proposed, waiting for confirmation from originator.
Tim et al, On Thu, Apr 18, 2002 at 03:50:09PM +1000, Tim J. Robbins wrote: # Please try this patch & let me know whether it corrects the problems # with the special .POSIX target. It is against HEAD, to try it on a 4.x # release you will need to edit str.c and remove __DECONST macro usage. # I realise it's not a particularly clean solution, and I'd be interested # to hear how it could be done better. I've applied the patch on a -current system and it does the Right Thing for my test case: schweikh@hal9000:~/txt/bug $ /usr/obj/src/current/usr.bin/make/make c89 -O -g -c prog.c echo 1003.2 1003.2 c89 -o prog prog.o One thing to keep in mind: as soon as we have a c99(1) we should change the CC variable to use that instead of c89 (to comply with POSIX 2001). Regards, Jens -- Jens Schweikhardt http://www.schweikhardt.net/ SIGSIG -- signature too long (core dumped)
Responsible Changed From-To: freebsd-standards->tjr Tim, as the originator (me :-) states, the patch is good. Please commit and then close this PR. Thanks!
Responsible Changed From-To: tjr->freebsd-bugs Unassign due to lack of time and interest. Perhaps someone else will pick this up.
Responsible Changed From-To: freebsd-bugs->harti Ok, I'll work on this one.
State Changed From-To: feedback->open Feedback was received quite some time ago.
State Changed From-To: open->suspended From personal email from harti: I'm actually working on this, but this will take some time, because it requires a complete rewrite of the parser. Our current parser just cannot by made to be correct with regards to Posix. Obviously this will also require some extensive testing especially with ports. harti
This is just a pointer to bin/155000 filed on a similar issue -- Eitan Adler
Responsible Changed From-To: harti->freebsd-bugs Now that we have bmake instead of make release responsibility for this bug. I suppose bmake has the same problem. In any case it is rather hard to fix.
Add sjg@ in CC he might be interested in that bug and can actually say if bmake is inpacted
Makefile is read *after* sys.mk so .POSIX: target in Makefile has no influence over sys.mk Looks to be working as defined.