diff options
author | Simon J. Gerraty <sjg@FreeBSD.org> | 2024-05-03 22:45:05 +0000 |
---|---|---|
committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2024-05-03 22:48:32 +0000 |
commit | 548bfc56eb0b2cefa0fb8dc2478240bfef610309 (patch) | |
tree | 3c1c164f0f32c5a7fda2c35cfbfc5da21d00c8b7 /contrib/bmake | |
parent | 6faf65670edda1b567baa9d50bb74ecf90946082 (diff) | |
parent | 507951f55039f9d1ceae507d510f8cb68225fbc5 (diff) | |
download | src-548bfc56eb0b2cefa0fb8dc2478240bfef610309.tar.gz src-548bfc56eb0b2cefa0fb8dc2478240bfef610309.zip |
Merge bmake-20240430
Merge commit '507951f55039f9d1ceae507d510f8cb68225fbc5'
Diffstat (limited to 'contrib/bmake')
126 files changed, 2609 insertions, 1594 deletions
diff --git a/contrib/bmake/ChangeLog b/contrib/bmake/ChangeLog index fc1da62fbe54..a2dd8dd5ed14 100644 --- a/contrib/bmake/ChangeLog +++ b/contrib/bmake/ChangeLog @@ -1,3 +1,74 @@ +2024-04-30 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240430 + Merge with NetBSD make, pick up + o main.c: ensure '.include <makefile>' respects MAKESYSPATH. + Dir_FindFile will search .CURDIR first unless ".DOTLAST" is seen. + +2024-04-28 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240428 + Merge with NetBSD make, pick up + o simplify freeing of lists + o arch.c: trim pointless comments + o var.c: delay variable assignments until actually needed + don't reallocate memory after evaluating an expression, result is + almost always short-lived. + +2024-04-26 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240426 + Merge with NetBSD make, pick up + o job.c: in debug output, print the directory in which a job + failed at same time as failed target so it is more easily found in + build log. + +2024-04-24 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240424 + Merge with NetBSD make, pick up + o clean up comments, code and tests + +2024-04-23 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240422 + Merge with NetBSD make, pick up + o var.c: avoid LazyBuf for :*time modifiers. + LazyBuf's are not nul terminated so not suitable for passing to + functions that expect that. These modifiers are used sparingly so + an extra allocation is not a problem. + +2024-04-20 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240420 + Merge with NetBSD make, pick up + o provide more context information for parse/evaluate errors + +2024-04-14 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240414 + Merge with NetBSD make, pick up + o parse.c: print -dp debug info earlier so we see which + .if or .for line is being parsed. + +2024-04-04 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240404 + Merge with NetBSD make, pick up + o fix some unit tests for Cygwin + o parse.c: exit immediately after reading a null byte from a makefile + + * fix generation of bmake.cat1 + +2024-03-19 Simon J Gerraty <sjg@beast.crufty.net> + + * VERSION (_MAKE_VERSION): 20240314 + Add/Improve support for Cygwin + o uname -s output isn't useful so allow configure to + set FORCE_MAKE_OS - to force the value of .MAKE.OS + and use Cygwin which matches uname -o + o fix some unit-tests for Cygwin + 2024-03-10 Simon J Gerraty <sjg@beast.crufty.net> * boot-strap: tests can take a long time; use a cookie to @@ -2175,10 +2246,10 @@ * VERSION (_MAKE_VERSION): 20200418 - * configure.in: use_makefile=no for cygwin et al. + * configure.in: use_makefile=no for Cygwin et al. case insensitive filesystems just don't work if both makefile and Makefile exist. - NOTE: bmake does not support cygwin and likely never will, + NOTE: bmake does not support Cygwin and likely never will, but if brave souls want to try it - help them out. 2020-04-02 Simon J Gerraty <sjg@beast.crufty.net> diff --git a/contrib/bmake/Makefile b/contrib/bmake/Makefile index 3332dcdeaf2d..65730df7e3df 100644 --- a/contrib/bmake/Makefile +++ b/contrib/bmake/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.126 2024/03/10 17:46:44 sjg Exp $ +# $Id: Makefile,v 1.127 2024/03/19 16:03:23 sjg Exp $ PROG= bmake @@ -48,7 +48,7 @@ CFLAGS+= -I. -I${srcdir} ${XDEFS} -DMAKE_NATIVE CFLAGS+= ${COPTS.${.ALLSRC:M*.c:T:u}} COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\"" -.for x in FORCE_MACHINE FORCE_MACHINE_ARCH +.for x in FORCE_MAKE_OS FORCE_MACHINE FORCE_MACHINE_ARCH .ifdef $x COPTS.main.c+= "-D$x=\"${$x}\"" .endif @@ -90,7 +90,7 @@ OS := ${.MAKE.OS:U${uname -s:L:sh}} # are we 4.4BSD ? isBSD44:=${BSD44_LIST:M${OS}} -.if ${isBSD44} == "" && ${OS:NCYGWIN*:NDarwin:NLinux} != "" +.if ${isBSD44} == "" && ${OS:NCygwin:NDarwin:NLinux} != "" MANTARGET?= cat .if ${MACHINE} == "sun386" # even I don't have one of these anymore :-) diff --git a/contrib/bmake/Makefile.config.in b/contrib/bmake/Makefile.config.in index dfc26d90a02a..43ad1b9a397a 100644 --- a/contrib/bmake/Makefile.config.in +++ b/contrib/bmake/Makefile.config.in @@ -5,6 +5,7 @@ _MAKE_VERSION?=@_MAKE_VERSION@ prefix?= @prefix@ srcdir= @srcdir@ CC= @CC@ +@force_make_os@MAKE_OS?= @make_os@ @force_machine@MACHINE?= @machine@ @force_machine_arch@MACHINE_ARCH?= @machine_arch@ DEFAULT_SYS_PATH?= @default_sys_path@ diff --git a/contrib/bmake/VERSION b/contrib/bmake/VERSION index 5d6ca326700a..49a67b80073a 100644 --- a/contrib/bmake/VERSION +++ b/contrib/bmake/VERSION @@ -1,2 +1,2 @@ # keep this compatible with sh and make -_MAKE_VERSION=20240309 +_MAKE_VERSION=20240430 diff --git a/contrib/bmake/arch.c b/contrib/bmake/arch.c index caec2e148690..4e52532c780a 100644 --- a/contrib/bmake/arch.c +++ b/contrib/bmake/arch.c @@ -1,4 +1,4 @@ -/* $NetBSD: arch.c,v 1.215 2024/02/07 06:43:02 rillig Exp $ */ +/* $NetBSD: arch.c,v 1.217 2024/04/27 20:41:32 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -147,7 +147,7 @@ struct ar_hdr { #include "dir.h" /* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: arch.c,v 1.215 2024/02/07 06:43:02 rillig Exp $"); +MAKE_RCSID("$NetBSD: arch.c,v 1.217 2024/04/27 20:41:32 rillig Exp $"); typedef struct List ArchList; typedef struct ListNode ArchListNode; @@ -155,7 +155,7 @@ typedef struct ListNode ArchListNode; static ArchList archives; /* The archives we've already examined */ typedef struct Arch { - char *name; /* Name of archive */ + char *name; HashTable members; /* All the members of the archive described * by <name, struct ar_hdr *> key/value pairs */ char *fnametab; /* Extended name table strings */ @@ -199,12 +199,10 @@ static int ArchSVR4Entry(Arch *, char *, size_t, FILE *); #ifdef CLEANUP static void -ArchFree(void *ap) +ArchFree(Arch *a) { - Arch *a = ap; HashIter hi; - /* Free memory from hash entries */ HashIter_Init(&hi, &a->members); while (HashIter_Next(&hi) != NULL) free(hi.entry->value); @@ -217,32 +215,22 @@ ArchFree(void *ap) #endif /* Return "archive(member)". */ -static char * +MAKE_ATTR_NOINLINE static char * FullName(const char *archive, const char *member) { - size_t len1 = strlen(archive); - size_t len3 = strlen(member); - char *result = bmake_malloc(len1 + 1 + len3 + 1 + 1); - memcpy(result, archive, len1); - memcpy(result + len1, "(", 1); - memcpy(result + len1 + 1, member, len3); - memcpy(result + len1 + 1 + len3, ")", 1 + 1); - return result; + Buffer buf; + Buf_Init(&buf); + Buf_AddStr(&buf, archive); + Buf_AddStr(&buf, "("); + Buf_AddStr(&buf, member); + Buf_AddStr(&buf, ")"); + return Buf_DoneData(&buf); } /* * Parse an archive specification such as "archive.a(member1 member2.${EXT})", - * adding nodes for the expanded members to gns. Nodes are created as - * necessary. - * - * Input: - * pp The start of the specification. - * gns The list on which to place the nodes. - * scope The scope in which to expand variables. - * - * Output: - * return True if it was a valid specification. - * *pp Points to the first non-space after the archive spec. + * adding nodes for the expanded members to gns. If successful, advance pp + * beyond the archive specification and any trailing whitespace. */ bool Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) @@ -323,12 +311,6 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) } } - /* - * If the specification ends without a closing parenthesis, - * chances are there's something wrong (like a missing - * backslash), so it's better to return failure than allow - * such things to happen - */ if (*cp == '\0') { Parse_Error(PARSE_FATAL, "No closing parenthesis " @@ -336,9 +318,6 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) return false; } - /* - * If we didn't move anywhere, we must be done - */ if (cp == mem.str) break; @@ -375,8 +354,7 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) /* * Must contain dynamic sources, so we can't * deal with it now. Just create an ARCHV node - * for the thing and let SuffExpandChildren - * handle it. + * and let SuffExpandChildren handle it. */ gn = Targ_GetNode(fullName); gn->type |= OP_ARCHV; @@ -413,13 +391,6 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) gn = Targ_GetNode(fullname); free(fullname); - /* - * We've found the node, but have to make sure the - * rest of the world knows it's an archive member, - * without having to constantly check for parentheses, - * so we type the thing with the OP_ARCHV bit before - * we place it on the end of the provided list. - */ gn->type |= OP_ARCHV; Lst_Append(gns, gn); } @@ -431,23 +402,13 @@ Arch_ParseArchive(char **pp, GNodeList *gns, GNode *scope) FStr_Done(&lib); cp++; /* skip the ')' */ - /* We promised that pp would be set up at the next non-space. */ cpp_skip_whitespace(&cp); *pp += cp - *pp; return true; } /* - * Locate a member of an archive, given the path of the archive and the path - * of the desired member. - * - * Input: - * archive Path to the archive - * member Name of member; only its basename is used. - * addToCache True if archive should be cached if not already so. - * - * Results: - * The ar_hdr for the member, or NULL. + * Locate a member in an archive. * * See ArchFindMember for an almost identical copy of this code. */ @@ -459,15 +420,11 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) size_t size; /* Size of archive member */ char magic[SARMAG]; ArchListNode *ln; - Arch *ar; /* Archive descriptor */ - struct ar_hdr arh; /* archive-member header for reading archive */ + Arch *ar; + struct ar_hdr arh; char memName[MAXPATHLEN + 1]; /* Current member name while hashing. */ - /* - * Because of space constraints and similar things, files are archived - * using their basename, not the entire path. - */ member = str_basename(member); for (ln = archives.first; ln != NULL; ln = ln->next) { @@ -499,11 +456,8 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) if (!addToCache) { /* - * Caller doesn't want the thing cached, just use - * ArchFindMember to read the header for the member out and - * close down the stream again. Since the archive is not to be - * cached, we assume there's no need to allocate extra room - * for the header we're returning, so just declare it static. + * Since the archive is not to be cached, assume there's no + * need to allocate the header, so just declare it static. */ static struct ar_hdr sarh; @@ -515,18 +469,10 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) return &sarh; } - /* - * We don't have this archive on the list yet, so we want to find out - * everything that's in it and cache it so we can get at it quickly. - */ arch = fopen(archive, "r"); if (arch == NULL) return NULL; - /* - * We use the ARMAG string to make sure this is an archive we - * can handle... - */ if (fread(magic, SARMAG, 1, arch) != 1 || strncmp(magic, ARMAG, SARMAG) != 0) { (void)fclose(arch); @@ -543,17 +489,9 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) while (fread(&arh, sizeof arh, 1, arch) == 1) { char *nameend; - /* If the header is bogus, there's no way we can recover. */ if (strncmp(arh.AR_FMAG, ARFMAG, sizeof arh.AR_FMAG) != 0) - goto badarch; + goto bad_archive; - /* - * We need to advance the stream's pointer to the start of the - * next header. Files are padded with newlines to an even-byte - * boundary, so we need to extract the size of the file from - * the 'size' field of the header and round it up during the - * seek. - */ arh.AR_SIZE[sizeof arh.AR_SIZE - 1] = '\0'; size = (size_t)strtol(arh.AR_SIZE, NULL, 10); @@ -572,7 +510,7 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) /* svr4 magic mode; handle it */ switch (ArchSVR4Entry(ar, memName, size, arch)) { case -1: /* Invalid data */ - goto badarch; + goto bad_archive; case 0: /* List of files entry */ continue; default: /* Got the entry */ @@ -596,12 +534,12 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) memName + sizeof AR_EFMT1 - 1); if (elen > MAXPATHLEN) - goto badarch; + goto bad_archive; if (fread(memName, elen, 1, arch) != 1) - goto badarch; + goto bad_archive; memName[elen] = '\0'; if (fseek(arch, -(long)elen, SEEK_CUR) != 0) - goto badarch; + goto bad_archive; if (DEBUG(ARCH) || DEBUG(MAKE)) debug_printf( "ArchStatMember: " @@ -617,21 +555,18 @@ ArchStatMember(const char *archive, const char *member, bool addToCache) HashTable_Set(&ar->members, memName, cached_hdr); } + /* Files are padded with newlines to an even-byte boundary. */ if (fseek(arch, ((long)size + 1) & ~1, SEEK_CUR) != 0) - goto badarch; + goto bad_archive; } fclose(arch); Lst_Append(&archives, ar); - /* - * Now that the archive has been read and cached, we can look into - * the addToCache table to find the desired member's header. - */ return HashTable_FindValue(&ar->members, member); -badarch: +bad_archive: fclose(arch); HashTable_Done(&ar->members); free(ar->fnametab); @@ -736,37 +671,27 @@ ArchiveMember_HasName(const struct ar_hdr *hdr, * In archives created by GNU binutils 2.27, the member names end * with a slash. */ - if (ar_name[namelen] == '/' && - (namelen == ar_name_len || ar_name[namelen + 1] == ' ')) + if (ar_name[namelen] == '/' && ar_name[namelen + 1] == ' ') return true; return false; } /* - * Locate a member of an archive, given the path of the archive and the path - * of the desired member. - * - * Input: - * archive Path to the archive - * member Name of member. If it is a path, only the last - * component is used. - * out_arh Archive header to be filled in - * mode "r" for read-only access, "r+" for read-write access + * Load the header of an archive member. The mode is "r" for read-only + * access, "r+" for read-write access. * - * Output: - * return The archive file, positioned at the start of the - * member's struct ar_hdr, or NULL if the member doesn't - * exist. - * *out_arh The current struct ar_hdr for member. + * Upon successful return, the archive file is positioned at the start of the + * member's struct ar_hdr. In case of a failure or if the member doesn't + * exist, return NULL. * * See ArchStatMember for an almost identical copy of this code. */ static FILE * -ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh, - const char *mode) +ArchFindMember(const char *archive, const char *member, + struct ar_hdr *out_arh, const char *mode) { - FILE *arch; /* Stream to archive */ + FILE *arch; int size; /* Size of archive member */ char magic[SARMAG]; size_t len; @@ -775,32 +700,20 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh, if (arch == NULL) return NULL; - /* - * We use the ARMAG string to make sure this is an archive we - * can handle... - */ if (fread(magic, SARMAG, 1, arch) != 1 || strncmp(magic, ARMAG, SARMAG) != 0) { fclose(arch); return NULL; } - /* - * Because of space constraints and similar things, files are archived - * using their basename, not the entire path. - */ + /* Files are archived using their basename, not the entire path. */ member = str_basename(member); - len = strlen(member); while (fread(out_arh, sizeof *out_arh, 1, arch) == 1) { if (strncmp(out_arh->AR_FMAG, ARFMAG, sizeof out_arh->AR_FMAG) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ fclose(arch); return NULL; } @@ -811,14 +724,6 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh, (int)sizeof out_arh->ar_date, out_arh->ar_date); if (ArchiveMember_HasName(out_arh, member, len)) { - /* - * To make life easier for callers that want to update - * the archive, we reposition the file at the start of - * the header we just read before we return the - * stream. In a more general situation, it might be - * better to leave the file at the actual member, - * rather than its header, but not here. - */ if (fseek(arch, -(long)sizeof *out_arh, SEEK_CUR) != 0) { fclose(arch); @@ -870,15 +775,10 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh, } #endif - /* - * This isn't the member we're after, so we need to advance the - * stream's pointer to the start of the next header. Files are - * padded with newlines to an even-byte boundary, so we need to - * extract the size of the file from the 'size' field of the - * header and round it up during the seek. - */ + /* Advance to the next member. */ out_arh->AR_SIZE[sizeof out_arh->AR_SIZE - 1] = '\0'; size = (int)strtol(out_arh->AR_SIZE, NULL, 10); + /* Files are padded with newlines to an even-byte boundary. */ if (fseek(arch, (size + 1) & ~1L, SEEK_CUR) != 0) { fclose(arch); return NULL; @@ -890,17 +790,9 @@ ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh, } /* - * Touch a member of an archive, on disk. - * The GNode's modification time is left as-is. - * - * The st_mtime of the entire archive is also changed. - * For a library, it may be required to run ranlib after this. - * - * Input: - * gn Node of member to touch - * - * Results: - * The 'time' field of the member's header is updated. + * Update the ar_date of the member of an archive, on disk but not in the + * GNode. Update the st_mtime of the entire archive as well. For a library, + * it may be required to run ranlib after this. */ void Arch_Touch(GNode *gn) @@ -1015,9 +907,6 @@ Arch_UpdateMemberMTime(GNode *gn) * TARGET variable for this node to be the node's name. Otherwise, * we set the TARGET variable to be the full path of the library, * as returned by Dir_FindFile. - * - * Input: - * gn Node of library to find */ void Arch_FindLib(GNode *gn, SearchPath *path) @@ -1059,20 +948,18 @@ RanlibOODate(const GNode *gn MAKE_ATTR_UNUSED) } /* - * Decide if a node with the OP_LIB attribute is out-of-date. Called from - * GNode_IsOODate to make its life easier. + * Decide if a node with the OP_LIB attribute is out-of-date. * The library is cached if it hasn't been already. * - * There are several ways for a library to be out-of-date that are - * not available to ordinary files. In addition, there are ways - * that are open to regular files that are not available to - * libraries. + * There are several ways for a library to be out-of-date that are not + * available to ordinary files. In addition, there are ways that are open to + * regular files that are not available to libraries. * - * A library that is only used as a source is never - * considered out-of-date by itself. This does not preclude the - * library's modification time from making its parent be out-of-date. - * A library will be considered out-of-date for any of these reasons, - * given that it is a target on a dependency line somewhere: + * A library that is only used as a source is never considered out-of-date by + * itself. This does not preclude the library's modification time from making + * its parent be out-of-date. A library will be considered out-of-date for + * any of these reasons, given that it is a target on a dependency line + * somewhere: * * Its modification time is less than that of one of its sources * (gn->mtime < gn->youngestChild->mtime). @@ -1092,18 +979,16 @@ bool Arch_LibOODate(GNode *gn) { - if (gn->type & OP_PHONY) { + if (gn->type & OP_PHONY) return true; - } else if (!GNode_IsTarget(gn) && Lst_IsEmpty(&gn->children)) { + if (!GNode_IsTarget(gn) && Lst_IsEmpty(&gn->children)) return false; - } else if ((!Lst_IsEmpty(&gn->children) && gn->youngestChild == NULL) || + if ((!Lst_IsEmpty(&gn->children) && gn->youngestChild == NULL) || (gn->mtime > now) || (gn->youngestChild != NULL && - gn->mtime < gn->youngestChild->mtime)) { + gn->mtime < gn->youngestChild->mtime)) return true; - } else { - return RanlibOODate(gn); - } + return RanlibOODate(gn); } /* Initialize the archives module. */ @@ -1118,26 +1003,25 @@ void Arch_End(void) { #ifdef CLEANUP - Lst_DoneCall(&archives, ArchFree); + ArchListNode *ln; + + for (ln = archives.first; ln != NULL; ln = ln->next) + ArchFree(ln->datum); + Lst_Done(&archives); #endif } bool Arch_IsLib(GNode *gn) { - static const char armag[] = "!<arch>\n"; - char buf[sizeof armag - 1]; + char buf[8]; int fd; + bool isLib; if ((fd = open(gn->path, O_RDONLY)) == -1) return false; - - if (read(fd, buf, sizeof buf) != sizeof buf) { - (void)close(fd); - return false; - } - + isLib = read(fd, buf, sizeof buf) == sizeof buf + && memcmp(buf, "!<arch>\n", sizeof buf) == 0; (void)close(fd); - - return memcmp(buf, armag, sizeof buf) == 0; + return isLib; } diff --git a/contrib/bmake/bmake.cat1 b/contrib/bmake/bmake.cat1 index 7c50930807f4..f2b05878e7e2 100644 --- a/contrib/bmake/bmake.cat1 +++ b/contrib/bmake/bmake.cat1 @@ -1,924 +1,1783 @@ -is a program designed to simplify the maintenance of other pro- -grams. Its input is a list of specifications as to the files -upon which programs and other files depend. If no option is -given, tries to open then in order to find the specifications. -If the file exists, it is read, see This manual page is intended -as a reference document only. For a more thorough description of -and makefiles, please refer to (from 1993). prepends the con- -tents of the environment variable to the command line arguments -before parsing them. The options are as follows: Try to be back- -wards compatible by executing a single shell per command and by -making the sources of a dependency line in sequence. Change to -before reading the makefiles or doing anything else. If multiple -options are specified, each is interpreted relative to the previ- -ous one: is equivalent to Define to be 1, in the global scope. -Turn on debugging, and specify which portions of are to print de- -bugging information. Unless the flags are preceded by they are -added to the environment variable and are passed on to any child -make processes. By default, debugging information is printed to -standard error, but this can be changed using the debugging flag. -The debugging output is always unbuffered; in addition, if debug- -ging is enabled but debugging output is not directed to standard -output, the standard output is line buffered. The available are: -Print all possible debugging information; equivalent to specify- -ing all of the debugging flags. Print debugging information -about archive searching and caching. Print debugging information -about the current working directory. Print debugging information -about conditional evaluation. Print debugging information about -directory searching and caching. Print debugging information -about failed commands and targets. Specify where debugging out- -put is written. This must be the last flag, because it consumes -the remainder of the argument. If the character immediately af- -ter the flag is the file is opened in append mode; otherwise the -file is overwritten. If the file name is or debugging output is -written to the standard output or standard error output respec- -tively (and the option has no effect). Otherwise, the output is -written to the named file. If the file name ends with the is re- -placed by the pid. Print debugging information about loop evalu- -ation. Print the input graph before making anything. Print the -input graph after making everything, or before exiting on error. -Print the input graph before exiting on error. Print debugging -information about hash table operations. Print debugging infor- -mation about running multiple shells. Turn on lint checks. This -throws errors for variable assignments that do not parse cor- -rectly, at the time of assignment, so the file and line number -are available. Print commands in Makefiles regardless of whether -or not they are prefixed by or other flags. Also known as behav- -ior. Print debugging information about mode decisions about tar- -gets. Print debugging information about making targets, includ- -ing modification dates. Don't delete the temporary command -scripts created when running commands. These temporary scripts -are created in the directory referred to by the environment vari- -able, or in if is unset or set to the empty string. The tempo- -rary scripts are created by and have names of the form This can -create many files in or so use with care. Print debugging infor- -mation about makefile parsing. Print debugging information about -suffix-transformation rules. Print debugging information about -target list maintenance. Force the option to print raw values of -variables, overriding the default behavior set via Print debug- -ging information about variable assignment and expansion. Run -shell commands with so the actual commands are printed as they -are executed. Let environment variables override global vari- -ables within makefiles. Specify a makefile to read instead of -the default or If is standard input is read. Multiple makefiles -may be specified, and are read in the order specified. Specify a -directory in which to search for makefiles and included make- -files. The system makefile directory (or directories, see the -option) is automatically included as part of this list. Ignore -non-zero exit of shell commands in the makefile. Equivalent to -specifying before each command line in the makefile. This option -should be specified by the user. When the option is in use in a -recursive build, this option is passed by a make to child makes -to allow all the make processes in the build to cooperate to -avoid overloading the system. Specify the maximum number of jobs -that may have running at any one time. If is a floating point -number, or ends with then the value is multiplied by the number -of CPUs reported online by The value of is saved in Turns compat- -ibility mode off, unless the option is also specified. When com- -patibility mode is off, all commands associated with a target are -executed in a single shell invocation as opposed to the tradi- -tional one shell invocation per line. This can break traditional -scripts which change directories on each command invocation and -then expect to start with a fresh environment on the next line. -It is more efficient to correct the scripts rather than turn -backwards compatibility on. A job token pool with tokens is used -to control the total number of jobs running. Each instance of -will wait for a token from the pool before running a new job. -Continue processing after errors are encountered, but only on -those targets that do not depend on the target whose creation -caused the error. Specify a directory in which to search for and -makefiles included via the include statement. The option can be -used multiple times to form a search path. This path overrides -the default system include path Furthermore, the system include -path is appended to the search path used for include statements -(see the option). The system include path can be referenced via -the read-only variable If a directory name in the argument (or -the environment variable) starts with the string searches for the -specified file or directory named in the remaining part of the -argument string. The search starts with the current directory -and then works upward towards the root of the file system. If -the search is successful, the resulting directory replaces the -specification in the argument. This feature allows to easily -search in the current source tree for customized files (e.g., by -using as an argument). Display the commands that would have been -executed, but do not actually execute them unless the target de- -pends on the special source (see below) or the command is pre- -fixed with Display the commands that would have been executed, -but do not actually execute any of them; useful for debugging -top-level makefiles without descending into subdirectories. Do -not execute any commands, instead exit 0 if the specified targets -are up to date, and 1 otherwise. Do not use the built-in rules -specified in the system makefile. Stop processing if an error is -encountered. This is the default behavior and the opposite of Do -not echo any commands as they are executed. Equivalent to speci- -fying before each command line in the makefile. When used with -the flag, append a trace record to for each job started and com- -pleted. Rather than re-building a target as specified in the -makefile, create it or update its modification time to make it -appear up-to-date. Print the value of Do not build any targets. -Multiple instances of this option may be specified; the variables -are printed one per line, with a blank line for each null or un- -defined variable. The value printed is extracted from the global -scope after all makefiles have been read. By default, the raw -variable contents (which may include additional unexpanded vari- -able references) are shown. If contains a it is not interpreted -as a variable name but rather as an expression. Its value is ex- -panded before printing. The value is also expanded before print- -ing if is set to true and the option has not been used to over- -ride it. Note that loop-local and target-local variables, as -well as values taken temporarily by global variables during make- -file processing, are not accessible via this option. The debug -mode can be used to see these at the cost of generating substan- -tial extraneous output. Like but all printed variables are al- -ways expanded to their complete value. The last occurrence of or -decides whether all variables are expanded or not. Treat any -warnings during makefile parsing as errors. Print entering and -leaving directory messages, pre and post processing. Don't ex- -port variables passed on the command line to the environment in- -dividually. Variables passed on the command line are still ex- -ported via the environment variable. This option may be useful -on systems which have a small limit on the size of command argu- -ments. Set the value of the variable to Normally, all values -passed on the command line are also exported to sub-makes in the -environment. The flag disables this behavior. Variable assign- -ments should follow options for POSIX compatibility but no order- -ing is enforced. There are several different types of lines in a -makefile: dependency specifications, shell commands, variable as- -signments, include statements, conditional directives, for loops, -other directives, and comments. Lines may be continued from one -line to the next by ending them with a backslash The trailing -newline character and initial whitespace on the following line -are compressed into a single space. Dependency lines consist of -one or more targets, an operator, and zero or more sources. This -creates a relationship where the targets on the sources and are -customarily created from them. A target is considered out of -date if it does not exist, or if its modification time is less -than that of any of its sources. An out-of-date target is re- -created, but not until all sources have been examined and them- -selves re-created as needed. Three operators may be used: Many -dependency lines may name this target but only one may have at- -tached shell commands. All sources named in all dependency lines -are considered together, and if needed the attached shell com- -mands are run to create or re-create the target. If is inter- -rupted, the target is removed. The same, but the target is al- -ways re-created whether or not it is out of date. Any dependency -line may have attached shell commands, but each one is handled -independently: its sources are considered and the attached shell -commands are run if the target is out of date with respect to -(only) those sources. Thus, different groups of the attached -shell commands may be run depending on the circumstances. Fur- -thermore, unlike for dependency lines with no sources, the at- -tached shell commands are always run. Also unlike the target is -not removed if is interrupted. All dependency lines mentioning a -particular target must use the same operator. Targets and -sources may contain the shell wildcard values and The values and -may only be used as part of the final component of the target or -source, and only match existing files. The value need not neces- -sarily be used to describe existing files. Expansion is in di- -rectory order, not alphabetically as done in the shell. Each -target may have associated with it one or more lines of shell -commands, normally used to create the target. Each of the lines -in this script be preceded by a tab. (For historical reasons, -spaces are not accepted.) While targets can occur in many depen- -dency lines if desired, by default only one of these rules may be -followed by a creation script. If the operator is used, however, -all rules may include scripts, and the respective scripts are ex- -ecuted in the order found. Each line is treated as a separate -shell command, unless the end of line is escaped with a backslash -in which case that line and the next are combined. If the first -characters of the command are any combination of or the command -is treated specially. causes the command not to be echoed before -it is executed. causes the command to be executed even when is -given. This is similar to the effect of the special source, ex- -cept that the effect can be limited to a single line of a script. -in compatibility mode causes any non-zero exit status of the com- -mand line to be ignored. When is run in jobs mode with the en- -tire script for the target is fed to a single instance of the -shell. In compatibility (non-jobs) mode, each command is run in -a separate process. If the command contains any shell meta char- -acters it is passed to the shell; otherwise attempts direct exe- -cution. If a line starts with and the shell has ErrCtl enabled, -failure of the command line is ignored as in compatibility mode. -Otherwise affects the entire job; the script stops at the first -command line that fails, but the target is not deemed to have -failed. Makefiles should be written so that the mode of opera- -tion does not change their behavior. For example, any command -which uses or without the intention of changing the directory for -subsequent commands should be put in parentheses so it executes -in a subshell. To force the use of a single shell, escape the -line breaks so as to make the whole script one command. For ex- -ample: avoid-chdir-side-effects: @echo "Building $@ in -$$(pwd)" @(cd ${.CURDIR} && ${MAKE} $@) @echo -"Back in $$(pwd)" - -ensure-one-shell-regardless-of-mode: @echo "Building $@ -in $$(pwd)"; \ (cd ${.CURDIR} && ${MAKE} $@); \ - echo "Back in $$(pwd)" Since changes the current working -directory to before executing any targets, each child process -starts with that as its current working directory. Variables in -make behave much like macros in the C preprocessor. Variable as- -signments have the form where: is a single-word variable name, -consisting, by tradition, of all upper-case letters, is one of -the variable assignment operators described below, and is inter- -preted according to the variable assignment operator. Whitespace -around and is discarded. The five operators that assign values -to variables are: Assign the value to the variable. Any previous -value is overwritten. Append the value to the current value of -the variable, separating them by a single space. Assign the -value to the variable if it is not already defined. Expand the -value, then assign it to the variable. References to undefined -variables are expanded. This can cause problems when variable -modifiers are used. Expand the value and pass it to the shell -for execution, then assign the output from the child's standard -output to the variable. Any newlines in the result are replaced -with spaces. In most contexts where variables are expanded, ex- -pands to a single dollar sign. In other contexts (most variable -modifiers, string literals in conditions), expands to a single -dollar sign. References to variables have the form or If the -variable name consists of only a single character and the expres- -sion contains no modifiers, the surrounding curly braces or -parentheses are not required. This shorter form is not recom- -mended. If the variable name contains a dollar, the name itself -is expanded first. This allows almost arbitrary variable names, -however names containing dollar, braces, parentheses or white- -space are really best avoided. If the result of expanding a -nested variable expression contains a dollar sign the result is -subject to further expansion. Variable substitution occurs at -four distinct times, depending on where the variable is being -used. Variables in dependency lines are expanded as the line is -read. Variables in conditionals are expanded individually, but -only as far as necessary to determine the result of the condi- -tional. Variables in shell commands are expanded when the shell -command is executed. loop index variables are expanded on each -loop iteration. Note that other variables are not expanded when -composing the body of a loop, so the following example code: .for -i in 1 2 3 a+= ${i} j= ${i} b+= ${j} .endfor - -all: @echo ${a} @echo ${b} prints: 1 2 3 3 3 3 -After the loop is executed: contains which expands to contains -which expands to contains which expands to and further to The -four different classes of variables (in order of increasing -precedence) are: Variables defined as part of environment. Vari- -ables defined in the makefile or in included makefiles. Vari- -ables defined as part of the command line. Variables that are -defined specific to a certain target. Local variables can be set -on a dependency line, unless is set to The rest of the line -(which already has had global variables expanded) is the variable -value. For example: COMPILER_WRAPPERS= ccache distcc icecc - -${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,} Only -the targets are impacted by that filter (in mode) and simply en- -abling/disabling any of the compiler wrappers does not render all -of those targets out-of-date. target-local variable assignments -behave differently in that; Only appends to a previous local as- -signment for the same target and variable. Is redundant with re- -spect to global variables, which have already been expanded. The -seven built-in local variables are: The list of all sources for -this target; also known as The name of the archive file; also -known as In suffix-transformation rules, the name/path of the -source from which the target is to be transformed (the source); -also known as It is not defined in explicit rules. The name of -the archive member; also known as The list of sources for this -target that were deemed out-of-date; also known as The name of -the target with suffix (if declared in removed; also known as The -name of the target; also known as For compatibility with other -makes this is an alias for in archive member rules. The shorter -forms and are permitted for backward compatibility with histori- -cal makefiles and legacy POSIX make and are not recommended. -Variants of these variables with the punctuation followed immedi- -ately by or e.g. are legacy forms equivalent to using the and -modifiers. These forms are accepted for compatibility with make- -files and POSIX but are not recommended. Four of the local vari- -ables may be used in sources on dependency lines because they ex- -pand to the proper value for each target on the line. These -variables are and In addition, sets or knows about the following -variables: The list of all targets encountered in the makefiles. -If evaluated during makefile parsing, lists only those targets -encountered thus far. A path to the directory where was exe- -cuted. Refer to the description of for more details. Is used in -error handling, see Is used in error handling, see Is used in er- -ror handling, see Is used in error handling in mode, see Is used -in error handling, see The directory of the file this makefile -was included from. The filename of the file this makefile was -included from. The machine hardware name, see The machine -processor architecture name, see The name that was executed with -The same as for compatibility. The preferred variable to use is -the environment variable because it is more compatible with other -make variants and cannot be confused with the special target with -the same name. Names the makefile (default from which generated -dependencies are read. If set to do not print error information -at the end. A boolean that controls the default behavior of the -option. If true, variable values printed with are fully ex- -panded; if false, the raw variable contents (which may include -additional unexpanded variable references) are shown. The list -of variables exported by The top-level makefile that is currently -read, as given in the command line. The environment variable may -contain anything that may be specified on command line. Anything -specified on command line is appended to the variable, which is -then added to the environment for all programs that executes. -The numeric group ID of the user running It is read-only. If is -run with the output for each target is prefixed with a token the -first part of which can be controlled via If is empty, no token -is printed. For example, setting to would produce tokens like -making it easier to track the degree of parallelism being -achieved. The argument to the option. A read-only boolean that -indicates whether the option supports use of The recursion depth -of The top-level instance of has level 0, and each child make has -its parent level plus 1. This allows tests like: to protect -things which should only be evaluated in the top-level instance -of The name of the environment variable that stores the level of -nested calls to The ordered list of makefile names (default that -looks for. The list of makefiles read by which is useful for -tracking dependencies. Each makefile is recorded only once, re- -gardless of the number of times read. In mode, provides a list -of prefixes which match the directories controlled by If a file -that was generated outside of but within said bailiwick is miss- -ing, the current target is considered out-of-date. In mode, it -can (very rarely!) be useful to filter command lines before com- -parison. This variable can be set to a set of modifiers that are -applied to each line of the old and new command that differ, if -the filtered commands still differ, the target is considered out- -of-date. In mode, this variable contains a list of all the meta -files updated. If not empty, it can be used to trigger process- -ing of In mode, this variable contains a list of all the meta -files used (updated or not). This list can be used to process -the meta files to extract dependency information. Provides a -list of variable modifiers to apply to each pathname. Ignore if -the expansion is an empty string. Provides a list of path pre- -fixes that should be ignored; because the contents are expected -to change over time. The default list includes: Provides a list -of patterns to match against pathnames. Ignore any that match. -Defines the message printed for each meta file updated in mode. -The default value is: Processed after reading all makefiles. Af- -fects the mode that runs in. It can contain these keywords: Like -puts into mode. Puts into mode, where meta files are created for -each target to capture the command run, the output generated, and -if is available, the system calls which are of interest to The -captured output can be useful when diagnosing errors. By de- -fault, does not create files in This can be overridden by setting -to a value which represents true. If is true, a missing file -makes the target out-of-date. If is true, missing filemon data -makes the target out-of-date. Do not use For debugging, it can -be useful to include the environment in the file. If in mode, -print a clue about the target being built. This is useful if the -build is otherwise running silently. The message printed is the -expanded value of Some makefiles have commands which are simply -not stable. This keyword causes them to be ignored for determin- -ing whether a target is out of date in mode. See also If is -true, when a .meta file is created, mark the target In both com- -pat and parallel mode, do not make the targets in the usual or- -der, but instead randomize their order. This mode can be used to -detect undeclared dependencies between files. Used to create -files in a separate directory, see Used to force a separate di- -rectory for the created files, even if that directory is not -writable, see Used to create files in a separate directory, see -The name of the operating system, see It is read-only. This -variable is used to record the names of variables assigned to on -the command line, so that they may be exported as part of This -behavior can be disabled by assigning an empty value to within a -makefile. Extra variables can be exported from a makefile by ap- -pending their names to is re-exported whenever is modified. If -was built with support, this is set to the path of the device -node. This allows makefiles to test for this support. The -process ID of It is read-only. The parent process ID of It is -read-only. When stops due to an error, it sets to the name of -the target that failed, to the exit status of the failed target, -to the commands of the failed target, and in mode, it also sets -to the and to the path of the meta file (if any) describing the -failed target. It then prints its name and the value of as well -as the value of any variables named in If true, are preserved -when doing assignments. The default is false, for backwards com- -patibility. Set to true for compatability with other makes. If -set to false, becomes per normal evaluation rules. If set to ap- -parent variable assignments in dependency lines are treated as -normal sources. The numeric ID of the user running It is read- -only. This variable is simply assigned a newline character as -its value. It is read-only. This allows expansions using the -modifier to put a newline between iterations of the loop rather -than a space. For example, in case of an error, prints the vari- -able names and their values using: A path to the directory where -the targets are built. Its value is determined by trying to to -the following directories in order and using the first match: -(Only if is set in the environment or on the command line.) -(Only if is set in the environment or on the command line.) -Variable expansion is performed on the value before it is used, -so expressions such as may be used. This is especially useful -with may be modified in the makefile via the special target In -all cases, changes to the specified directory if it exists, and -sets and to that directory before executing any targets. Except -in the case of an explicit target, checks that the specified di- -rectory is writable and ignores it if not. This check can be -skipped by setting the environment variable to The directory name -of the current makefile being parsed. The basename of the cur- -rent makefile being parsed. This variable and are both set only -while the makefiles are being parsed. To retain their current -values, assign them to a variable using assignment with expansion -The space-separated list of directories that searches for files. -To update this search list, use the special target rather than -modifying the variable directly. Is set in POSIX mode, see the -special target. Alternate path to the current directory. nor- -mally sets to the canonical path given by However, if the envi- -ronment variable is set and gives a path to the current direc- -tory, sets to the value of instead. This behavior is disabled if -is set or contains a variable transform. is set to the value of -for all programs which executes. The pathname of the shell used -to run target scripts. It is read-only. The list of known suf- -fixes. It is read-only. The space-separated list of directories -that searches for makefiles, referred to as the system include -path. To update this search list, use the special target rather -than modifying the variable which is read-only. The list of tar- -gets explicitly specified on the command line, if any. The -colon-separated list of directories that searches for files. -This variable is supported for compatibility with old make pro- -grams only, use instead. The general format of a variable expan- -sion is: Each modifier begins with a colon. To escape a colon, -precede it with a backslash A list of indirect modifiers can be -specified via a variable, as follows: - -In this case, the first modifier in the does not start with a -colon, since that colon already occurs in the referencing vari- -able. If any of the modifiers in the contains a dollar sign -these must be doubled to avoid early expansion. Some modifiers -interpret the expression value as a single string, others treat -the expression value as a whitespace-separated list of words. -When splitting a string into words, whitespace can be escaped us- -ing double quotes, single quotes and backslashes, like in the -shell. The quotes and backslashes are retained in the words. -The supported modifiers are: Replaces each word with its suffix. -Replaces each word with its dirname. Selects only those words -that match The standard shell wildcard characters and may be -used. The wildcard characters may be escaped with a backslash As -a consequence of the way values are split into words, matched, -and then joined, the construct removes all leading and trailing -whitespace and normalizes the inter-word spacing to a single -space. This is the opposite of selecting all words which do -match Orders the words lexicographically. Orders the words nu- -merically. A number followed by one of or is multiplied by the -appropriate factor, which is 1024 for 1048576 for or 1073741824 -for Both upper- and lower-case letters are accepted. Orders the -words in reverse lexicographical order. Orders the words in re- -verse numerical order. Shuffles the words. The results are dif- -ferent each time you are referring to the modified variable; use -the assignment with expansion to prevent such behavior. For ex- -ample, LIST= uno due tre quattro RAN- -DOM_LIST= ${LIST:Ox} STATIC_RAN- -DOM_LIST:= ${LIST:Ox} - -all: @echo "${RANDOM_LIST}" @echo "${RAN- -DOM_LIST}" @echo "${STATIC_RANDOM_LIST}" @echo -"${STATIC_RANDOM_LIST}" may produce output similar to: quattro -due tre uno tre due quattro uno due uno quattro tre due uno quat- -tro tre Quotes every shell meta-character in the value, so that -it can be passed safely to the shell. Quotes every shell meta- -character in the value, and also doubles characters so that it -can be passed safely through recursive invocations of This is -equivalent to Replaces each word with everything but its suffix. -The value is an integer sequence representing the words of the -original value, or the supplied The value is interpreted as a -format string for using producing the formatted timestamp. Note: -the format should only be used with If a value is not provided or -is 0, the current time is used. Computes a 32-bit hash of the -value and encodes it as 8 hex digits. The value is interpreted -as a format string for using producing the formatted timestamp. -If a value is not provided or is 0, the current time is used. -Call with each word as pathname; use as the new value. If fails; -use or current time. If is set to then failure will cause an er- -ror. Attempts to convert the value to an absolute path using If -that fails, the value is unchanged. Converts the value to lower- -case letters. When joining the words after a modifier that -treats the value as words, the words are normally separated by a -space. This modifier changes the separator to the character If -is omitted, no separator is used. The common escapes (including -octal numeric codes) work as expected. Converts the value to up- -per-case letters. Causes subsequent modifiers to treat the value -as a single word (possibly containing embedded whitespace). See -also Causes the value to be treated as a list of words. See also -Modifies the first occurrence of in each word of the value, re- -placing it with If a is appended to the last delimiter of the -pattern, all occurrences in each word are replaced. If a is ap- -pended to the last delimiter of the pattern, only the first oc- -currence is affected. If a is appended to the last delimiter of -the pattern, the value is treated as a single word. If begins -with a caret is anchored at the beginning of each word. If ends -with a dollar sign it is anchored at the end of each word. In- -side an ampersand is replaced by (without the anchoring or Any -character may be used as the delimiter for the parts of the modi- -fier string. The anchoring, ampersand and delimiter characters -can be escaped with a backslash Both and may contain nested ex- -pressions. To prevent a dollar sign from starting a nested ex- -pression, escape it with a backslash. The modifier works like -the modifier except that the old and new strings, instead of be- -ing simple strings, are an extended regular expression (see and -an Normally, the first occurrence of the pattern in each word of -the value is substituted with The modifier causes the substitu- -tion to apply to at most one word; the modifier causes the sub- -stitution to apply to as many instances of the search pattern as -occur in the word or words it is found in; the modifier causes -the value to be treated as a single word (possibly containing em- -bedded whitespace). As for the modifier, the and are subjected -to variable expansion before being parsed as regular expressions. -Replaces each word with its last path component (basename). Re- -moves adjacent duplicate words (like If the variable name (not -its value), when parsed as a conditional expression, evaluates to -true, return as its value the otherwise return the Since the -variable name is used as the expression, :? must be the first -modifier after the variable name which, of course, usually con- -tains variable expansions. A common error is trying to use ex- -pressions like which actually tests defined(NUMBERS). To deter- -mine if any words match you need to use something like: This is -the style substitution. It can only be the last modifier speci- -fied, as a in either or is treated as a regular character, not as -the end of the modifier. If does not contain the pattern match- -ing character and the word ends with or equals it, that suffix is -replaced with Otherwise, the first in matches a possibly empty -substring of arbitrary characters, and if the whole pattern is -found in the word, the matching part is replaced with and the -first occurrence of in (if any) is replaced with the substring -matched by the Both and may contain nested expressions. To pre- -vent a dollar sign from starting a nested expression, escape it -with a backslash. This is the loop expansion mechanism from the -OSF Development Environment (ODE) make. Unlike loops, expansion -occurs at the time of reference. For each word in the value, as- -sign the word to the variable named and evaluate The ODE conven- -tion is that should start and end with a period, for example: -However, a single-letter variable is often more readable: Saves -the current variable value in or the named for later reference. -Example usage: M_cmpv.units = 1 1000 1000000 M_cmpv = S,., -,g:_:range:@i@+ $${_:[-$$i]} \ \* -$${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh - - -Here is used to save the result of the modifier which is later -referenced using the index values from If the variable is unde- -fined, the optional (which may be empty) is the value. If the -variable is defined, the existing value is returned. This is an- -other ODE make feature. It is handy for setting per-target -CFLAGS for instance: If a value is only required if the variable -is undefined, use: If the variable is defined, (which may be -empty) is the value. The name of the variable is the value. The -path of the node which has the same name as the variable is the -value. If no such node exists or its path is null, the name of -the variable is used. In order for this modifier to work, the -name (node) must at least have appeared on the right-hand side of -a dependency. The output of running is the value. The value is -run as a command, and the output becomes the new value. The -variable is assigned the value after substitution. This modifier -and its variations are useful in obscure situations such as want- -ing to set a variable at a point where a target's shell commands -are being parsed. These assignment modifiers always expand to -nothing. The helps avoid false matches with the style modifier -and since substitution always occurs, the form is vaguely appro- -priate. As for but only if the variable does not already have a -value. Append to the variable. Assign the output of to the -variable. Selects one or more words from the value, or performs -other operations related to the way in which the value is split -into words. An empty value, or a value that consists entirely of -white-space, is treated as a single word. For the purposes of -the modifier, the words are indexed both forwards using positive -integers (where index 1 represents the first word), and backwards -using negative integers (where index -1 represents the last -word). The is subjected to variable expansion, and the expanded -result is then interpreted as follows: Selects a single word from -the value. Selects all words from to inclusive. For example, -selects all words from the second word to the last word. If is -greater than the words are output in reverse order. For example, -selects all the words from last to first. If the list is already -ordered, this effectively reverses the list, but it is more effi- -cient to use instead of Causes subsequent modifiers to treat the -value as a single word (possibly containing embedded whitespace). -Analogous to the effect of in Bourne shell. Means the same as -Causes subsequent modifiers to treat the value as a sequence of -words delimited by whitespace. Analogous to the effect of in -Bourne shell. Returns the number of words in the value. offers -directives for including makefiles, conditionals and for loops. -All these directives are identified by a line beginning with a -single dot character, followed by the keyword of the directive, -such as or Files are included with either or Variables between -the angle brackets or double quotes are expanded to form the file -name. If angle brackets are used, the included makefile is ex- -pected to be in the system makefile directory. If double quotes -are used, the including makefile's directory and any directories -specified using the option are searched before the system make- -file directory. For compatibility with other make variants, -(without leading dot) is also accepted. If the include statement -is written as or as errors locating and/or opening include files -are ignored. If the include statement is written as not only are -errors locating and/or opening include files ignored, but stale -dependencies within the included file are ignored just like in -The directives for exporting and unexporting variables are: Ex- -port the specified global variable. If no variable list is pro- -vided, all globals are exported except for internal variables -(those that start with This is not affected by the flag, so -should be used with caution. For compatibility with other make -programs, (without leading dot) is also accepted. Appending a -variable name to is equivalent to exporting a variable. The same -as except that the variable is not appended to This allows ex- -porting a value to the environment which is different from that -used by internally. The same as except that variables in the -value are not expanded. The opposite of The specified global is -removed from If no variable list is provided, all globals are un- -exported, and deleted. Unexport all globals previously exported -and clear the environment inherited from the parent. This opera- -tion causes a memory leak of the original environment, so should -be used sparingly. Testing for being 0 would make sense. Also -note that any variables which originated in the parent environ- -ment should be explicitly preserved if desired. For example: -PATH := ${PATH} Would result in an environment containing only -which is the minimal useful environment. Actually is also pushed -into the new environment. The directives for printing messages -to the output are: The message is printed along with the name of -the makefile and line number. The message prefixed by is printed -along with the name of the makefile and line number. The message -is printed along with the name of the makefile and line number, -exits immediately. The directives for conditionals are: Test the -value of an expression. Test whether a variable is defined. -Test whether a variable is not defined. Test the target being -requested. Test the target being requested. Reverse the sense -of the last conditional. A combination of followed by A combina- -tion of followed by A combination of followed by A combination of -followed by A combination of followed by End the body of the con- -ditional. The may be any one of the following: Logical OR. Log- -ical AND; of higher precedence than only evaluates a conditional -as far as is necessary to determine its value. Parentheses can -be used to override the operator precedence. The boolean opera- -tor may be used to logically negate an expression, typically a -function call. It is of higher precedence than The value of may -be any of the following function call expressions: Evaluates to -true if the variable has been defined. Evaluates to true if the -target was specified as part of command line or was declared the -default target (either implicitly or explicitly, see before the -line containing the conditional. Evaluates to true if the expan- -sion of the variable, after applying the modifiers, results in an -empty string. Evaluates to true if the given pathname exists. -If relative, the pathname is searched for on the system search -path (see Evaluates to true if the target has been defined. -Evaluates to true if the target has been defined and has commands -associated with it. may also be an arithmetic or string compari- -son. Variable expansion is performed on both sides of the com- -parison. If both sides are numeric and neither is enclosed in -quotes, the comparison is done numerically, otherwise lexico- -graphically. A string is interpreted as a hexadecimal integer if -it is preceded by otherwise it is interpreted as a decimal float- -ing-point number; octal numbers are not supported. All compar- -isons may use the operators and Numeric comparisons may also use -the operators and If the comparison has neither a comparison op- -erator nor a right side, the expression evaluates to true if it -is nonempty and its numeric value (if any) is not zero. When is -evaluating one of these conditional expressions, and it encoun- -ters a (whitespace-separated) word it doesn't recognize, either -the or function is applied to it, depending on the form of the -conditional. If the form is or the function is applied. Simi- -larly, if the form is or the function is applied. If the condi- -tional evaluates to true, parsing of the makefile continues as -before. If it evaluates to false, the following lines until the -corresponding variant, or are skipped. For loops are typically -used to apply a set of rules to a list of files. The syntax of a -for loop is: The is expanded and then split into words. On each -iteration of the loop, one word is taken and assigned to each in -order, and these are substituted into the inside the body of the -for loop. The number of words must come out even; that is, if -there are three iteration variables, the number of words provided -must be a multiple of three. If is encountered within a loop, it -causes early termination of the loop, otherwise a parse error. -Un-define the specified global variables. Only global variables -can be un-defined. Comments begin with a hash character, any- -where but in a shell command line, and continue to the end of an -unescaped new line. Target is never out of date, but always exe- -cute commands anyway. Ignore any errors from the commands asso- -ciated with this target, exactly as if they all were preceded by -a dash Mark all sources of this target as being up to date. Exe- -cute the commands associated with this target even if the or op- -tions were specified. Normally used to mark recursive Create a -meta file for the target, even if it is flagged as or Usage in -conjunction with is the most likely case. In mode, the target is -out-of-date if the meta file is missing. Do not create a meta -file for the target. Meta files are also not created for or tar- -gets. Ignore differences in commands when deciding if target is -out of date. This is useful if the command contains a value -which always changes. If the number of commands change, though, -the target is still considered out of date. The same effect ap- -plies to any command line that uses the variable which can be -used for that purpose even when not otherwise needed or desired: - -skip-compare-for-some: @echo this is compared - @echo this is not ${.OODATE:M.NOMETA_CMP} @echo -this is also compared - -The pattern suppresses any expansion of the unwanted variable. -Do not search for the target in the directories specified by Nor- -mally selects the first target it encounters as the default tar- -get to be built if no target was specified. This source prevents -this target from being selected. If a target is marked with this -attribute and can't figure out how to create it, it ignores this -fact and assumes the file isn't needed or already exists. The -target does not correspond to an actual file; it is always con- -sidered to be out of date, and is not created with the option. -Suffix-transformation rules are not applied to targets. When is -interrupted, it normally removes any partially made targets. -This source prevents the target from being removed. Synonym for -Do not echo any of the commands associated with this target, ex- -actly as if they all were preceded by an at sign Turn the target -into version of a macro. When the target is used as a source for -another target, the other target acquires the commands, sources, -and attributes (except for of the source. If the target already -has commands, the target's commands are appended to them. Like -but instead of appending, prepend the target commands to the tar- -get. If appears in a dependency line, the sources that precede -it are made before the sources that succeed it in the line. -Since the dependents of files are not made until the file itself -could be made, this also stops the dependents being built unless -they are needed for another branch of the dependency tree. So -given: x: a .WAIT b echo x a: echo a b: b1 - echo b b1: echo b1 - -the output is always The ordering imposed by is only relevant for -parallel makes. Special targets may not be included with other -targets, i.e. they must be the only target specified. Any com- -mand lines attached to this target are executed before anything -else is done. This is sort of a rule for any target (that was -used only as a source) that can't figure out any other way to -create. Only the shell script is used. The variable of a target -that inherits commands is set to the target's own name. If this -target is present in the makefile, it globally causes make to -delete targets whose commands fail. (By default, only targets -whose commands are interrupted during execution are deleted. -This is the historical behavior.) This setting can be used to -help prevent half-finished or malformed targets from being left -around and corrupting future rebuilds. Any command lines at- -tached to this target are executed after everything else is done -successfully. Any command lines attached to this target are exe- -cuted when another target fails. See for the variables that will -be set. Mark each of the sources with the attribute. If no -sources are specified, this is the equivalent of specifying the -option. If is interrupted, the commands for this target are exe- -cuted. If no target is specified when is invoked, this target is -built. This target provides a way to specify flags for at the -time when the makefiles are read. The flags are as if typed to -the shell, though the option has no effect. Apply the attribute -to any specified sources. Disable parallel mode. Synonym for -for compatibility with other pmake variants. clear the read-only -attribute from the global variables specified as sources. The -source is a new value for If it exists, changes the current work- -ing directory to it and updates the value of In parallel mode, -the named targets are made in sequence. This ordering does not -add targets to the list of targets to be made. Since the depen- -dents of a target do not get built until the target itself could -be built, unless is built by another part of the dependency -graph, the following is a dependency loop: .ORDER: b a b: a The -sources are directories which are to be searched for files not -found in the current directory. If no sources are specified, any -previously specified directories are removed from the search -path. If the source is the special target, the current working -directory is searched last. Like but applies only to files with -a particular suffix. The suffix must have been previously de- -clared with Apply the attribute to any specified sources. If -this is the first non-comment line in the main makefile, the -variable is set to the value and the makefile is included if it -exists, to provide POSIX-compatible default rules. If is run -with the flag, only contributes to the default rules. Apply the -attribute to any specified sources. If no sources are specified, -the attribute is applied to every target in the file. set the -read-only attribute on the global variables specified as sources. -Sets the shell that uses to execute commands. The sources are a -set of pairs. This is the minimal specification, used to select -one of the built-in shell specs; and Specifies the absolute path -to the shell. Indicates whether the shell supports exit on er- -ror. The command to turn on error checking. The command to dis- -able error checking. The command to turn on echoing of commands -executed. The command to turn off echoing of commands executed. -The output to filter after issuing the command. It is typically -identical to The flag to pass the shell to enable error checking. -The flag to pass the shell to enable command echoing. The string -literal to pass the shell that results in a single newline char- -acter when used outside of any quoting characters. Example: -.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \ - check="set -e" ignore="set +e" \ echo="set -v" -quiet="set +v" filter="set +v" \ echoFlag=v errFlag=e -newline="'\n'" Apply the attribute to any specified sources. If -no sources are specified, the attribute is applied to every com- -mand in the file. This target gets run when a dependency file -contains stale entries, having set to the name of that dependency -file. Each source specifies a suffix to If no sources are speci- -fied, any previously specified suffixes are deleted. It allows -the creation of suffix-transformation rules. Example: .SUFFIXES: -.c .o .c.o: cc -o ${.TARGET} -c ${.IMPSRC} The sources -are directories which are to be added to the system include path -which searches for makefiles. If no sources are specified, any -previously specified directories are removed from the system in- -clude path. uses the following environment variables, if they -exist: and and may only be set in the environment or on the com- -mand line to and not as makefile variables; see the description -of for more details. list of dependencies first default makefile -if no makefile is specified on the command line second default -makefile if no makefile is specified on the command line system -makefile system makefile directory The basic make syntax is com- -patible between different make variants; however the special -variables, variable modifiers and conditionals are not. An in- -complete list of changes in older versions of The way that .for -loop variables are substituted changed after NetBSD 5.0 so that -they still appear to be variable expansions. In particular this -stops them being treated as syntax, and removes some obscure -problems using them in .if statements. The way that parallel -makes are scheduled changed in NetBSD 4.0 so that .ORDER and -.WAIT apply recursively to the dependent nodes. The algorithms -used may change again in the future. Other make dialects (GNU -make, SVR4 make, POSIX make, etc.) do not support most of the -features of as described in this manual. Most notably: The and -declarations and most functionality pertaining to paralleliza- -tion. (GNU make supports parallelization but lacks the features -needed to control it effectively.) Directives, including for -loops and conditionals and most of the forms of include files. -(GNU make has its own incompatible and less powerful syntax for -conditionals.) All built-in variables that begin with a dot. -Most of the special sources and targets that begin with a dot, -with the notable exception of and Variable modifiers, except for -the string substitution, which does not portably support globbing -with and historically only works on declared suffixes. The vari- -able even in its short form; most makes support this functional- -ity but its name varies. Some features are somewhat more -portable, such as assignment with and The functionality is based -on an older feature found in GNU make and many versions of SVR4 -make; however, historically its behavior is too ill-defined (and -too buggy) to rely upon. The and variables are more or less uni- -versally portable, as is the variable. Basic use of suffix rules -(for files only in the current directory, not trying to chain -transformations together, etc.) is also reasonably portable. is -derived from NetBSD It uses autoconf to facilitate portability to -other platforms. A make command appeared in This make implemen- -tation is based on Adam de Boor's pmake program, which was writ- -ten for Sprite at Berkeley. It was designed to be a parallel -distributed make running jobs on different machines using a dae- -mon called Historically the target/dependency has been used to -FoRCe rebuilding (since the target/dependency does not exist ... -unless someone creates an file). The make syntax is difficult to -parse. For instance, finding the end of a variable's use should -involve scanning each of the modifiers, using the correct termi- -nator for each field. In many places make just counts {} and () -in order to find the end of a variable expansion. There is no -way of escaping a space character in a filename. In jobs mode, -when a target fails; make will put an error token into the job -token pool. This will cause all other instances of make using -that token pool to abort the build and exit with error code 6. -Sometimes the attempt to suppress a cascade of unnecessary er- -rors, can result in a seemingly unexplained +BMAKE(1) FreeBSD General Commands Manual BMAKE(1) +NNAAMMEE + bbmmaakkee - maintain program dependencies +SSYYNNOOPPSSIISS + bbmmaakkee [--BBeeiikkNNnnqqrrSSssttWWwwXX] [--CC _d_i_r_e_c_t_o_r_y] [--DD _v_a_r_i_a_b_l_e] [--dd _f_l_a_g_s] + [--ff _m_a_k_e_f_i_l_e] [--II _d_i_r_e_c_t_o_r_y] [--JJ _p_r_i_v_a_t_e] [--jj _m_a_x___j_o_b_s] + [--mm _d_i_r_e_c_t_o_r_y] [--TT _f_i_l_e] [--VV _v_a_r_i_a_b_l_e] [--vv _v_a_r_i_a_b_l_e] + [_v_a_r_i_a_b_l_e==_v_a_l_u_e] [_t_a_r_g_e_t ...] +DDEESSCCRRIIPPTTIIOONN + bbmmaakkee is a program designed to simplify the maintenance of other + programs. Its input is a list of specifications as to the files upon + which programs and other files depend. If no --ff _m_a_k_e_f_i_l_e option is + given, bbmmaakkee tries to open `_m_a_k_e_f_i_l_e' then `_M_a_k_e_f_i_l_e' in order to find + the specifications. If the file `_._d_e_p_e_n_d' exists, it is read, see + mkdep(1). + This manual page is intended as a reference document only. For a more + thorough description of bbmmaakkee and makefiles, please refer to _P_M_a_k_e _- _A + _T_u_t_o_r_i_a_l (from 1993). + bbmmaakkee prepends the contents of the MAKEFLAGS environment variable to the + command line arguments before parsing them. + The options are as follows: + --BB Try to be backwards compatible by executing a single shell per + command and by making the sources of a dependency line in + sequence. + --CC _d_i_r_e_c_t_o_r_y + Change to _d_i_r_e_c_t_o_r_y before reading the makefiles or doing + anything else. If multiple --CC options are specified, each is + interpreted relative to the previous one: --CC _/ --CC _e_t_c is + equivalent to --CC _/_e_t_c. + --DD _v_a_r_i_a_b_l_e + Define _v_a_r_i_a_b_l_e to be 1, in the global scope. + --dd [--]_f_l_a_g_s + Turn on debugging, and specify which portions of bbmmaakkee are to + print debugging information. Unless the flags are preceded by + `-', they are added to the MAKEFLAGS environment variable and are + passed on to any child make processes. By default, debugging + information is printed to standard error, but this can be changed + using the FF debugging flag. The debugging output is always + unbuffered; in addition, if debugging is enabled but debugging + output is not directed to standard output, the standard output is + line buffered. The available _f_l_a_g_s are: + AA Print all possible debugging information; equivalent to + specifying all of the debugging flags. + aa Print debugging information about archive searching and + caching. + CC Print debugging information about the current working + directory. + cc Print debugging information about conditional evaluation. + dd Print debugging information about directory searching and + caching. + ee Print debugging information about failed commands and + targets. + + FF[++]_f_i_l_e_n_a_m_e + Specify where debugging output is written. This must be + the last flag, because it consumes the remainder of the + argument. If the character immediately after the FF flag + is `+', the file is opened in append mode; otherwise the + file is overwritten. If the file name is `stdout' or + `stderr', debugging output is written to the standard + output or standard error output respectively (and the `+' + option has no effect). Otherwise, the output is written + to the named file. If the file name ends with `.%d', the + `%d' is replaced by the pid. + + ff Print debugging information about loop evaluation. + + gg11 Print the input graph before making anything. + + gg22 Print the input graph after making everything, or before + exiting on error. + + gg33 Print the input graph before exiting on error. + + hh Print debugging information about hash table operations. + + jj Print debugging information about running multiple + shells. + + LL Turn on lint checks. This throws errors for variable + assignments that do not parse correctly, at the time of + assignment, so the file and line number are available. + + ll Print commands in Makefiles regardless of whether or not + they are prefixed by `@' or other "quiet" flags. Also + known as "loud" behavior. + + MM Print debugging information about "meta" mode decisions + about targets. + + mm Print debugging information about making targets, + including modification dates. + + nn Don't delete the temporary command scripts created when + running commands. These temporary scripts are created in + the directory referred to by the TMPDIR environment + variable, or in _/_t_m_p if TMPDIR is unset or set to the + empty string. The temporary scripts are created by + mkstemp(3), and have names of the form _m_a_k_e_X_X_X_X_X_X. _N_O_T_E: + This can create many files in TMPDIR or _/_t_m_p, so use with + care. + + pp Print debugging information about makefile parsing. + + ss Print debugging information about suffix-transformation + rules. + + tt Print debugging information about target list + maintenance. + + VV Force the --VV option to print raw values of variables, + overriding the default behavior set via + _._M_A_K_E_._E_X_P_A_N_D___V_A_R_I_A_B_L_E_S. + + vv Print debugging information about variable assignment and + expansion. + + xx Run shell commands with --xx so the actual commands are + printed as they are executed. + + --ee Let environment variables override global variables within + makefiles. + + --ff _m_a_k_e_f_i_l_e + Specify a makefile to read instead of the default _m_a_k_e_f_i_l_e or + _M_a_k_e_f_i_l_e. If _m_a_k_e_f_i_l_e is `-', standard input is read. Multiple + makefiles may be specified, and are read in the order specified. + + --II _d_i_r_e_c_t_o_r_y + Specify a directory in which to search for makefiles and included + makefiles. The system makefile directory (or directories, see + the --mm option) is automatically included as part of this list. + + --ii Ignore non-zero exit of shell commands in the makefile. + Equivalent to specifying `-' before each command line in the + makefile. + + --JJ _p_r_i_v_a_t_e + This option should _n_o_t be specified by the user. + + When the --jj option is in use in a recursive build, this option is + passed by a make to child makes to allow all the make processes + in the build to cooperate to avoid overloading the system. + + --jj _m_a_x___j_o_b_s + Specify the maximum number of jobs that bbmmaakkee may have running at + any one time. If _m_a_x___j_o_b_s is a floating point number, or ends + with `C', then the value is multiplied by the number of CPUs + reported online by sysconf(3). The value of _m_a_x___j_o_b_s is saved in + _._M_A_K_E_._J_O_B_S. Turns compatibility mode off, unless the --BB option + is also specified. When compatibility mode is off, all commands + associated with a target are executed in a single shell + invocation as opposed to the traditional one shell invocation per + line. This can break traditional scripts which change + directories on each command invocation and then expect to start + with a fresh environment on the next line. It is more efficient + to correct the scripts rather than turn backwards compatibility + on. + + A job token pool with _m_a_x___j_o_b_s tokens is used to control the + total number of jobs running. Each instance of bbmmaakkee will wait + for a token from the pool before running a new job. + + --kk Continue processing after errors are encountered, but only on + those targets that do not depend on the target whose creation + caused the error. + + --mm _d_i_r_e_c_t_o_r_y + Specify a directory in which to search for _s_y_s_._m_k and makefiles + included via the <_f_i_l_e>-style include statement. The --mm option + can be used multiple times to form a search path. This path + overrides the default system include path _/_u_s_r_/_s_h_a_r_e_/_m_k. + Furthermore, the system include path is appended to the search + path used for "_f_i_l_e"-style include statements (see the --II + option). The system include path can be referenced via the read- + only variable _._S_Y_S_P_A_T_H. + + If a directory name in the --mm argument (or the MAKESYSPATH + environment variable) starts with the string `.../', bbmmaakkee + searches for the specified file or directory named in the + remaining part of the argument string. The search starts with + the current directory and then works upward towards the root of + the file system. If the search is successful, the resulting + directory replaces the `.../' specification in the --mm argument. + This feature allows bbmmaakkee to easily search in the current source + tree for customized _s_y_s_._m_k files (e.g., by using `.../mk/sys.mk' + as an argument). + + --nn Display the commands that would have been executed, but do not + actually execute them unless the target depends on the _._M_A_K_E + special source (see below) or the command is prefixed with `++'. + + --NN Display the commands that would have been executed, but do not + actually execute any of them; useful for debugging top-level + makefiles without descending into subdirectories. + + --qq Do not execute any commands, instead exit 0 if the specified + targets are up to date, and 1 otherwise. + + --rr Do not use the built-in rules specified in the system makefile. + + --SS Stop processing if an error is encountered. This is the default + behavior and the opposite of --kk. + + --ss Do not echo any commands as they are executed. Equivalent to + specifying `@@' before each command line in the makefile. + + --TT _t_r_a_c_e_f_i_l_e + When used with the --jj flag, append a trace record to _t_r_a_c_e_f_i_l_e + for each job started and completed. + + --tt Rather than re-building a target as specified in the makefile, + create it or update its modification time to make it appear up- + to-date. + + --VV _v_a_r_i_a_b_l_e + Print the value of _v_a_r_i_a_b_l_e. Do not build any targets. Multiple + instances of this option may be specified; the variables are + printed one per line, with a blank line for each null or + undefined variable. The value printed is extracted from the + global scope after all makefiles have been read. + + By default, the raw variable contents (which may include + additional unexpanded variable references) are shown. If + _v_a_r_i_a_b_l_e contains a `$', it is not interpreted as a variable name + but rather as an expression. Its value is expanded before + printing. The value is also expanded before printing if + _._M_A_K_E_._E_X_P_A_N_D___V_A_R_I_A_B_L_E_S is set to true and the --ddVV option has not + been used to override it. + + Note that loop-local and target-local variables, as well as + values taken temporarily by global variables during makefile + processing, are not accessible via this option. The --ddvv debug + mode can be used to see these at the cost of generating + substantial extraneous output. + + --vv _v_a_r_i_a_b_l_e + Like --VV, but all printed variables are always expanded to their + complete value. The last occurrence of --VV or --vv decides whether + all variables are expanded or not. + + --WW Treat any warnings during makefile parsing as errors. + + --ww Print entering and leaving directory messages, pre and post + processing. + + --XX Don't export variables passed on the command line to the + environment individually. Variables passed on the command line + are still exported via the MAKEFLAGS environment variable. This + option may be useful on systems which have a small limit on the + size of command arguments. + + _v_a_r_i_a_b_l_e==_v_a_l_u_e + Set the value of the variable _v_a_r_i_a_b_l_e to _v_a_l_u_e. Normally, all + values passed on the command line are also exported to sub-makes + in the environment. The --XX flag disables this behavior. + Variable assignments should follow options for POSIX + compatibility but no ordering is enforced. + + There are several different types of lines in a makefile: dependency + specifications, shell commands, variable assignments, include statements, + conditional directives, for loops, other directives, and comments. + + Lines may be continued from one line to the next by ending them with a + backslash (`\'). The trailing newline character and initial whitespace + on the following line are compressed into a single space. + +FFIILLEE DDEEPPEENNDDEENNCCYY SSPPEECCIIFFIICCAATTIIOONNSS + Dependency lines consist of one or more targets, an operator, and zero or + more sources. This creates a relationship where the targets "depend" on + the sources and are customarily created from them. A target is + considered out of date if it does not exist, or if its modification time + is less than that of any of its sources. An out-of-date target is re- + created, but not until all sources have been examined and themselves re- + created as needed. Three operators may be used: + + :: Many dependency lines may name this target but only one may have + attached shell commands. All sources named in all dependency lines + are considered together, and if needed the attached shell commands + are run to create or re-create the target. If bbmmaakkee is + interrupted, the target is removed. + + !! The same, but the target is always re-created whether or not it is + out of date. + + :::: Any dependency line may have attached shell commands, but each one + is handled independently: its sources are considered and the + attached shell commands are run if the target is out of date with + respect to (only) those sources. Thus, different groups of the + attached shell commands may be run depending on the circumstances. + Furthermore, unlike ::, for dependency lines with no sources, the + attached shell commands are always run. Also unlike ::, the target + is not removed if bbmmaakkee is interrupted. + + All dependency lines mentioning a particular target must use the same + operator. + + Targets and sources may contain the shell wildcard values `?', `*', `[]', + and `{}'. The values `?', `*', and `[]' may only be used as part of the + final component of the target or source, and only match existing files. + The value `{}' need not necessarily be used to describe existing files. + Expansion is in directory order, not alphabetically as done in the shell. + +SSHHEELLLL CCOOMMMMAANNDDSS + Each target may have associated with it one or more lines of shell + commands, normally used to create the target. Each of the lines in this + script _m_u_s_t be preceded by a tab. (For historical reasons, spaces are + not accepted.) While targets can occur in many dependency lines if + desired, by default only one of these rules may be followed by a creation + script. If the `::::' operator is used, however, all rules may include + scripts, and the respective scripts are executed in the order found. + + Each line is treated as a separate shell command, unless the end of line + is escaped with a backslash `\', in which case that line and the next are + combined. If the first characters of the command are any combination of + `@@', `++', or `--', the command is treated specially. + + @@ causes the command not to be echoed before it is executed. + + ++ causes the command to be executed even when --nn is given. + This is similar to the effect of the _._M_A_K_E special source, + except that the effect can be limited to a single line of a + script. + + -- in compatibility mode causes any non-zero exit status of + the command line to be ignored. + + When bbmmaakkee is run in jobs mode with --jj _m_a_x___j_o_b_s, the entire script for + the target is fed to a single instance of the shell. In compatibility + (non-jobs) mode, each command is run in a separate process. If the + command contains any shell meta characters (`#=|^(){};&<>*?[]:$`\\n'), it + is passed to the shell; otherwise bbmmaakkee attempts direct execution. If a + line starts with `--' and the shell has ErrCtl enabled, failure of the + command line is ignored as in compatibility mode. Otherwise `--' affects + the entire job; the script stops at the first command line that fails, + but the target is not deemed to have failed. + + Makefiles should be written so that the mode of bbmmaakkee operation does not + change their behavior. For example, any command which uses "cd" or + "chdir" without the intention of changing the directory for subsequent + commands should be put in parentheses so it executes in a subshell. To + force the use of a single shell, escape the line breaks so as to make the + whole script one command. For example: + + avoid-chdir-side-effects: + @echo "Building $@ in $$(pwd)" + @(cd ${.CURDIR} && ${MAKE} $@) + @echo "Back in $$(pwd)" + + ensure-one-shell-regardless-of-mode: + @echo "Building $@ in $$(pwd)"; \ + (cd ${.CURDIR} && ${MAKE} $@); \ + echo "Back in $$(pwd)" + + Since bbmmaakkee changes the current working directory to `_._O_B_J_D_I_R' before + executing any targets, each child process starts with that as its current + working directory. +VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS + Variables in make behave much like macros in the C preprocessor. + Variable assignments have the form `_N_A_M_E _o_p _v_a_l_u_e', where: + _N_A_M_E is a single-word variable name, consisting, by tradition, + of all upper-case letters, + _o_p is one of the variable assignment operators described + below, and + _v_a_l_u_e is interpreted according to the variable assignment + operator. + Whitespace around _N_A_M_E, _o_p and _v_a_l_u_e is discarded. + VVaarriiaabbllee aassssiiggnnmmeenntt ooppeerraattoorrss + The five operators that assign values to variables are: + == Assign the value to the variable. Any previous value is + overwritten. + ++== Append the value to the current value of the variable, separating + them by a single space. + ??== Assign the value to the variable if it is not already defined. + ::== Expand the value, then assign it to the variable. + _N_O_T_E: References to undefined variables are _n_o_t expanded. This + can cause problems when variable modifiers are used. + !!== Expand the value and pass it to the shell for execution, then + assign the output from the child's standard output to the + variable. Any newlines in the result are replaced with spaces. + EExxppaannssiioonn ooff vvaarriiaabblleess + In most contexts where variables are expanded, `$$' expands to a single + dollar sign. In other contexts (most variable modifiers, string literals + in conditions), `\$' expands to a single dollar sign. + References to variables have the form $${{_n_a_m_e[::_m_o_d_i_f_i_e_r_s]}} or + $$((_n_a_m_e[::_m_o_d_i_f_i_e_r_s])). If the variable name consists of only a single + character and the expression contains no modifiers, the surrounding curly + braces or parentheses are not required. This shorter form is not + recommended. + If the variable name contains a dollar, the name itself is expanded + first. This allows almost arbitrary variable names, however names + containing dollar, braces, parentheses or whitespace are really best + avoided. + If the result of expanding a nested variable expression contains a dollar + sign (`$'), the result is subject to further expansion. + Variable substitution occurs at four distinct times, depending on where + the variable is being used. + 1. Variables in dependency lines are expanded as the line is read. + 2. Variables in conditionals are expanded individually, but only as far + as necessary to determine the result of the conditional. + 3. Variables in shell commands are expanded when the shell command is + executed. + 4. ..ffoorr loop index variables are expanded on each loop iteration. Note + that other variables are not expanded when composing the body of a + loop, so the following example code: + .for i in 1 2 3 + a+= ${i} + j= ${i} + b+= ${j} + .endfor + all: + @echo ${a} + @echo ${b} + prints: + 1 2 3 + 3 3 3 + After the loop is executed: + _a contains `${:U1} ${:U2} ${:U3}', which expands to `1 2 + 3'. + _j contains `${:U3}', which expands to `3'. + _b contains `${j} ${j} ${j}', which expands to `${:U3} + ${:U3} ${:U3}' and further to `3 3 3'. + VVaarriiaabbllee ccllaasssseess + The four different classes of variables (in order of increasing + precedence) are: + Environment variables + Variables defined as part of bbmmaakkee's environment. + Global variables + Variables defined in the makefile or in included makefiles. + Command line variables + Variables defined as part of the command line. + Local variables + Variables that are defined specific to a certain target. + Local variables can be set on a dependency line, unless + _._M_A_K_E_._T_A_R_G_E_T___L_O_C_A_L___V_A_R_I_A_B_L_E_S is set to `false'. The rest of the line + (which already has had global variables expanded) is the variable value. + For example: + COMPILER_WRAPPERS= ccache distcc icecc + ${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,} + Only the targets `${OBJS}' are impacted by that filter (in "meta" mode) + and simply enabling/disabling any of the compiler wrappers does not + render all of those targets out-of-date. + _N_O_T_E: target-local variable assignments behave differently in that; + ++== Only appends to a previous local assignment for the same + target and variable. + ::== Is redundant with respect to global variables, which have + already been expanded. + The seven built-in local variables are: + _._A_L_L_S_R_C The list of all sources for this target; also known + as `_>'. + _._A_R_C_H_I_V_E The name of the archive file; also known as `_!'. + + _._I_M_P_S_R_C In suffix-transformation rules, the name/path of the + source from which the target is to be transformed + (the "implied" source); also known as `_<'. It is not + defined in explicit rules. + + _._M_E_M_B_E_R The name of the archive member; also known as `_%'. + + _._O_O_D_A_T_E The list of sources for this target that were deemed + out-of-date; also known as `_?'. + + _._P_R_E_F_I_X The name of the target with suffix (if declared in + ..SSUUFFFFIIXXEESS) removed; also known as `_*'. + + _._T_A_R_G_E_T The name of the target; also known as `_@'. For + compatibility with other makes this is an alias for + _._A_R_C_H_I_V_E in archive member rules. + + The shorter forms (`_>', `_!', `_<', `_%', `_?', `_*', and `_@') are permitted + for backward compatibility with historical makefiles and legacy POSIX + make and are not recommended. + + Variants of these variables with the punctuation followed immediately by + `D' or `F', e.g. `$(@D)', are legacy forms equivalent to using the `:H' + and `:T' modifiers. These forms are accepted for compatibility with AT&T + System V UNIX makefiles and POSIX but are not recommended. + + Four of the local variables may be used in sources on dependency lines + because they expand to the proper value for each target on the line. + These variables are `_._T_A_R_G_E_T', `_._P_R_E_F_I_X', `_._A_R_C_H_I_V_E', and `_._M_E_M_B_E_R'. + + AAddddiittiioonnaall bbuuiilltt--iinn vvaarriiaabblleess + In addition, bbmmaakkee sets or knows about the following variables: + + _._A_L_L_T_A_R_G_E_T_S + The list of all targets encountered in the makefiles. If + evaluated during makefile parsing, lists only those targets + encountered thus far. + + _._C_U_R_D_I_R + A path to the directory where bbmmaakkee was executed. Refer to the + description of `_P_W_D' for more details. + + _._E_R_R_O_R___C_M_D + Is used in error handling, see _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R. + + _._E_R_R_O_R___C_W_D + Is used in error handling, see _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R. + + _._E_R_R_O_R___E_X_I_T + Is used in error handling, see _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R. + + _._E_R_R_O_R___M_E_T_A___F_I_L_E + Is used in error handling in "meta" mode, see + _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R. + + _._E_R_R_O_R___T_A_R_G_E_T + Is used in error handling, see _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R. + + _._I_N_C_L_U_D_E_D_F_R_O_M_D_I_R + The directory of the file this makefile was included from. + + _._I_N_C_L_U_D_E_D_F_R_O_M_F_I_L_E + The filename of the file this makefile was included from. + + _M_A_C_H_I_N_E + The machine hardware name, see uname(1). + + _M_A_C_H_I_N_E___A_R_C_H + The machine processor architecture name, see uname(1). + + _M_A_K_E The name that bbmmaakkee was executed with (_a_r_g_v_[_0_]). + + _._M_A_K_E The same as _M_A_K_E, for compatibility. The preferred variable to + use is the environment variable MAKE because it is more + compatible with other make variants and cannot be confused with + the special target with the same name. + + _._M_A_K_E_._D_E_P_E_N_D_F_I_L_E + Names the makefile (default `_._d_e_p_e_n_d') from which generated + dependencies are read. + + _._M_A_K_E_._D_I_E___Q_U_I_E_T_L_Y + If set to `true', do not print error information at the end. + + _._M_A_K_E_._E_X_P_A_N_D___V_A_R_I_A_B_L_E_S + A boolean that controls the default behavior of the --VV option. + If true, variable values printed with --VV are fully expanded; if + false, the raw variable contents (which may include additional + unexpanded variable references) are shown. + + _._M_A_K_E_._E_X_P_O_R_T_E_D + The list of variables exported by bbmmaakkee. + + _M_A_K_E_F_I_L_E + The top-level makefile that is currently read, as given in the + command line. + + _._M_A_K_E_F_L_A_G_S + The environment variable `MAKEFLAGS' may contain anything that + may be specified on bbmmaakkee's command line. Anything specified on + bbmmaakkee's command line is appended to the _._M_A_K_E_F_L_A_G_S variable, + which is then added to the environment for all programs that + bbmmaakkee executes. + + _._M_A_K_E_._G_I_D + The numeric group ID of the user running bbmmaakkee. It is read-only. + + _._M_A_K_E_._J_O_B_._P_R_E_F_I_X + If bbmmaakkee is run with --jj, the output for each target is prefixed + with a token + --- _t_a_r_g_e_t --- + the first part of which can be controlled via _._M_A_K_E_._J_O_B_._P_R_E_F_I_X. + If _._M_A_K_E_._J_O_B_._P_R_E_F_I_X is empty, no token is printed. For example, + setting _._M_A_K_E_._J_O_B_._P_R_E_F_I_X to + `${.newline}---${.MAKE:T}[${.MAKE.PID}]' would produce tokens + like + ---make[1234] _t_a_r_g_e_t --- + making it easier to track the degree of parallelism being + achieved. + + _._M_A_K_E_._J_O_B_S + The argument to the --jj option. + + _._M_A_K_E_._J_O_B_S_._C + A read-only boolean that indicates whether the --jj option supports + use of `C'. + + _._M_A_K_E_._L_E_V_E_L + The recursion depth of bbmmaakkee. The top-level instance of bbmmaakkee + has level 0, and each child make has its parent level plus 1. + This allows tests like: .if ${.MAKE.LEVEL} == 0 to protect things + which should only be evaluated in the top-level instance of + bbmmaakkee. + + _._M_A_K_E_._L_E_V_E_L_._E_N_V + The name of the environment variable that stores the level of + nested calls to bbmmaakkee. + + _._M_A_K_E_._M_A_K_E_F_I_L_E___P_R_E_F_E_R_E_N_C_E + The ordered list of makefile names (default `_m_a_k_e_f_i_l_e', + `_M_a_k_e_f_i_l_e') that bbmmaakkee looks for. + + _._M_A_K_E_._M_A_K_E_F_I_L_E_S + The list of makefiles read by bbmmaakkee, which is useful for tracking + dependencies. Each makefile is recorded only once, regardless of + the number of times read. + + _._M_A_K_E_._M_E_T_A_._B_A_I_L_I_W_I_C_K + In "meta" mode, provides a list of prefixes which match the + directories controlled by bbmmaakkee. If a file that was generated + outside of _._O_B_J_D_I_R but within said bailiwick is missing, the + current target is considered out-of-date. + + _._M_A_K_E_._M_E_T_A_._C_M_P___F_I_L_T_E_R + In "meta" mode, it can (very rarely!) be useful to filter command + lines before comparison. This variable can be set to a set of + modifiers that are applied to each line of the old and new + command that differ, if the filtered commands still differ, the + target is considered out-of-date. + + _._M_A_K_E_._M_E_T_A_._C_R_E_A_T_E_D + In "meta" mode, this variable contains a list of all the meta + files updated. If not empty, it can be used to trigger + processing of _._M_A_K_E_._M_E_T_A_._F_I_L_E_S. + + _._M_A_K_E_._M_E_T_A_._F_I_L_E_S + In "meta" mode, this variable contains a list of all the meta + files used (updated or not). This list can be used to process + the meta files to extract dependency information. + + _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___F_I_L_T_E_R + Provides a list of variable modifiers to apply to each pathname. + Ignore if the expansion is an empty string. + + _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___P_A_T_H_S + Provides a list of path prefixes that should be ignored; because + the contents are expected to change over time. The default list + includes: `_/_d_e_v _/_e_t_c _/_p_r_o_c _/_t_m_p _/_v_a_r_/_r_u_n _/_v_a_r_/_t_m_p' + + _._M_A_K_E_._M_E_T_A_._I_G_N_O_R_E___P_A_T_T_E_R_N_S + Provides a list of patterns to match against pathnames. Ignore + any that match. + + _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X + Defines the message printed for each meta file updated in "meta + verbose" mode. The default value is: + Building ${.TARGET:H:tA}/${.TARGET:T} + + _._M_A_K_E_._M_O_D_E + Processed after reading all makefiles. Affects the mode that + bbmmaakkee runs in. It can contain these keywords: + + ccoommppaatt Like --BB, puts bbmmaakkee into "compat" mode. + + mmeettaa Puts bbmmaakkee into "meta" mode, where meta files are created + for each target to capture the command run, the output + generated, and if filemon(4) is available, the system + calls which are of interest to bbmmaakkee. The captured + output can be useful when diagnosing errors. + + ccuurrddiirrOOkk==_b_f + By default, bbmmaakkee does not create _._m_e_t_a files in + `_._C_U_R_D_I_R'. This can be overridden by setting _b_f to a + value which represents true. + + mmiissssiinngg--mmeettaa==_b_f + If _b_f is true, a missing _._m_e_t_a file makes the target out- + of-date. + + mmiissssiinngg--ffiilleemmoonn==_b_f + If _b_f is true, missing filemon data makes the target out- + of-date. + + nnooffiilleemmoonn + Do not use filemon(4). + + eennvv For debugging, it can be useful to include the + environment in the _._m_e_t_a file. + + vveerrbboossee + If in "meta" mode, print a clue about the target being + built. This is useful if the build is otherwise running + silently. The message printed is the expanded value of + _._M_A_K_E_._M_E_T_A_._P_R_E_F_I_X. + + iiggnnoorree--ccmmdd + Some makefiles have commands which are simply not stable. + This keyword causes them to be ignored for determining + whether a target is out of date in "meta" mode. See also + ..NNOOMMEETTAA__CCMMPP. + + ssiilleenntt==_b_f + If _b_f is true, when a .meta file is created, mark the + target ..SSIILLEENNTT. + + rraannddoommiizzee--ttaarrggeettss + In both compat and parallel mode, do not make the targets + in the usual order, but instead randomize their order. + This mode can be used to detect undeclared dependencies + between files. + + _M_A_K_E_O_B_J_D_I_R + Used to create files in a separate directory, see _._O_B_J_D_I_R. + + _M_A_K_E___O_B_J_D_I_R___C_H_E_C_K___W_R_I_T_A_B_L_E + Used to force a separate directory for the created files, even if + that directory is not writable, see _._O_B_J_D_I_R. + + _M_A_K_E_O_B_J_D_I_R_P_R_E_F_I_X + Used to create files in a separate directory, see _._O_B_J_D_I_R. + + _._M_A_K_E_._O_S + The name of the operating system, see uname(1). It is read-only. + + _._M_A_K_E_O_V_E_R_R_I_D_E_S + This variable is used to record the names of variables assigned + to on the command line, so that they may be exported as part of + `MAKEFLAGS'. This behavior can be disabled by assigning an empty + value to `_._M_A_K_E_O_V_E_R_R_I_D_E_S' within a makefile. Extra variables can + be exported from a makefile by appending their names to + `_._M_A_K_E_O_V_E_R_R_I_D_E_S'. `MAKEFLAGS' is re-exported whenever + `_._M_A_K_E_O_V_E_R_R_I_D_E_S' is modified. + + _._M_A_K_E_._P_A_T_H___F_I_L_E_M_O_N + If bbmmaakkee was built with filemon(4) support, this is set to the + path of the device node. This allows makefiles to test for this + support. + + _._M_A_K_E_._P_I_D + The process ID of bbmmaakkee. It is read-only. + + _._M_A_K_E_._P_P_I_D + The parent process ID of bbmmaakkee. It is read-only. + + _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R + When bbmmaakkee stops due to an error, it sets `_._E_R_R_O_R___T_A_R_G_E_T' to the + name of the target that failed, `_._E_R_R_O_R___E_X_I_T' to the exit status + of the failed target, `_._E_R_R_O_R___C_M_D' to the commands of the failed + target, and in "meta" mode, it also sets `_._E_R_R_O_R___C_W_D' to the + getcwd(3), and `_._E_R_R_O_R___M_E_T_A___F_I_L_E' to the path of the meta file + (if any) describing the failed target. It then prints its name + and the value of `_._C_U_R_D_I_R' as well as the value of any variables + named in `_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R'. + + _._M_A_K_E_._S_A_V_E___D_O_L_L_A_R_S + If true, `$$' are preserved when doing `:=' assignments. The + default is false, for backwards compatibility. Set to true for + compatability with other makes. If set to false, `$$' becomes + `$' per normal evaluation rules. + + _._M_A_K_E_._T_A_R_G_E_T___L_O_C_A_L___V_A_R_I_A_B_L_E_S + If set to `false', apparent variable assignments in dependency + lines are treated as normal sources. + + _._M_A_K_E_._U_I_D + The numeric ID of the user running bbmmaakkee. It is read-only. + + _._n_e_w_l_i_n_e + This variable is simply assigned a newline character as its + value. It is read-only. This allows expansions using the ::@@ + modifier to put a newline between iterations of the loop rather + than a space. For example, in case of an error, bbmmaakkee prints the + variable names and their values using: + ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} + + _._O_B_J_D_I_R + A path to the directory where the targets are built. Its value + is determined by trying to chdir(2) to the following directories + in order and using the first match: + + 1. $${{MMAAKKEEOOBBJJDDIIRRPPRREEFFIIXX}}$${{..CCUURRDDIIRR}} + + (Only if `MAKEOBJDIRPREFIX' is set in the environment or on + the command line.) + + 2. $${{MMAAKKEEOOBBJJDDIIRR}} + + (Only if `MAKEOBJDIR' is set in the environment or on the + command line.) + + 3. $${{..CCUURRDDIIRR}}_/_o_b_j_.$${{MMAACCHHIINNEE}} + + 4. $${{..CCUURRDDIIRR}}_/_o_b_j + + 5. _/_u_s_r_/_o_b_j_/$${{..CCUURRDDIIRR}} + + 6. $${{..CCUURRDDIIRR}} + + Variable expansion is performed on the value before it is used, + so expressions such as $${{..CCUURRDDIIRR::SS,,^^//uussrr//ssrrcc,,//vvaarr//oobbjj,,}} may be + used. This is especially useful with `MAKEOBJDIR'. + + `_._O_B_J_D_I_R' may be modified in the makefile via the special target + `..OOBBJJDDIIRR'. In all cases, bbmmaakkee changes to the specified + directory if it exists, and sets `_._O_B_J_D_I_R' and `_P_W_D' to that + directory before executing any targets. + + Except in the case of an explicit `..OOBBJJDDIIRR' target, bbmmaakkee checks + that the specified directory is writable and ignores it if not. + This check can be skipped by setting the environment variable + `MAKE_OBJDIR_CHECK_WRITABLE' to "no". + + _._P_A_R_S_E_D_I_R + The directory name of the current makefile being parsed. + + _._P_A_R_S_E_F_I_L_E + The basename of the current makefile being parsed. This variable + and `_._P_A_R_S_E_D_I_R' are both set only while the makefiles are being + parsed. To retain their current values, assign them to a + variable using assignment with expansion `::=='. + + _._P_A_T_H The space-separated list of directories that bbmmaakkee searches for + files. To update this search list, use the special target + `..PPAATTHH' rather than modifying the variable directly. + + _%_P_O_S_I_X Is set in POSIX mode, see the special `_._P_O_S_I_X' target. + + _P_W_D Alternate path to the current directory. bbmmaakkee normally sets + `_._C_U_R_D_I_R' to the canonical path given by getcwd(3). However, if + the environment variable `PWD' is set and gives a path to the + current directory, bbmmaakkee sets `_._C_U_R_D_I_R' to the value of `PWD' + instead. This behavior is disabled if `MAKEOBJDIRPREFIX' is set + or `MAKEOBJDIR' contains a variable transform. `_P_W_D' is set to + the value of `_._O_B_J_D_I_R' for all programs which bbmmaakkee executes. + + _._S_H_E_L_L The pathname of the shell used to run target scripts. It is + read-only. + + _._S_U_F_F_I_X_E_S + The list of known suffixes. It is read-only. + + _._S_Y_S_P_A_T_H + The space-separated list of directories that bbmmaakkee searches for + makefiles, referred to as the system include path. To update + this search list, use the special target `..SSYYSSPPAATTHH' rather than + modifying the variable which is read-only. + + _._T_A_R_G_E_T_S + The list of targets explicitly specified on the command line, if + any. + + _V_P_A_T_H The colon-separated (":") list of directories that bbmmaakkee searches + for files. This variable is supported for compatibility with old + make programs only, use `_._P_A_T_H' instead. + + VVaarriiaabbllee mmooddiiffiieerrss + The general format of a variable expansion is: + + $${{_v_a_r_i_a_b_l_e[::_m_o_d_i_f_i_e_r[::...]]}} + + Each modifier begins with a colon. To escape a colon, precede it with a + backslash `\'. + + A list of indirect modifiers can be specified via a variable, as follows: + + _m_o_d_i_f_i_e_r___v_a_r_i_a_b_l_e = _m_o_d_i_f_i_e_r[::...] + + $${{_v_a_r_i_a_b_l_e::$${{_m_o_d_i_f_i_e_r___v_a_r_i_a_b_l_e}}[::...]}} + + In this case, the first modifier in the _m_o_d_i_f_i_e_r___v_a_r_i_a_b_l_e does not start + with a colon, since that colon already occurs in the referencing + variable. If any of the modifiers in the _m_o_d_i_f_i_e_r___v_a_r_i_a_b_l_e contains a + dollar sign (`$'), these must be doubled to avoid early expansion. + + Some modifiers interpret the expression value as a single string, others + treat the expression value as a whitespace-separated list of words. When + splitting a string into words, whitespace can be escaped using double + quotes, single quotes and backslashes, like in the shell. The quotes and + backslashes are retained in the words. + + The supported modifiers are: + + ::EE Replaces each word with its suffix. + + ::HH Replaces each word with its dirname. + + ::MM_p_a_t_t_e_r_n + Selects only those words that match _p_a_t_t_e_r_n. The standard shell + wildcard characters (`*', `?', and `[]') may be used. The wildcard + characters may be escaped with a backslash (`\'). As a consequence + of the way values are split into words, matched, and then joined, + the construct `${VAR:M*}' removes all leading and trailing + whitespace and normalizes the inter-word spacing to a single space. + + ::NN_p_a_t_t_e_r_n + This is the opposite of `::MM', selecting all words which do _n_o_t match + _p_a_t_t_e_r_n. + + ::OO Orders the words lexicographically. + + ::OOnn Orders the words numerically. A number followed by one of `k', `M' + or `G' is multiplied by the appropriate factor, which is 1024 for + `k', 1048576 for `M', or 1073741824 for `G'. Both upper- and lower- + case letters are accepted. + + ::OOrr Orders the words in reverse lexicographical order. + + ::OOrrnn + Orders the words in reverse numerical order. + + ::OOxx Shuffles the words. The results are different each time you are + referring to the modified variable; use the assignment with + expansion `::==' to prevent such behavior. For example, + + LIST= uno due tre quattro + RANDOM_LIST= ${LIST:Ox} + STATIC_RANDOM_LIST:= ${LIST:Ox} + + all: + @echo "${RANDOM_LIST}" + @echo "${RANDOM_LIST}" + @echo "${STATIC_RANDOM_LIST}" + @echo "${STATIC_RANDOM_LIST}" + may produce output similar to: + + quattro due tre uno + tre due quattro uno + due uno quattro tre + due uno quattro tre + + ::QQ Quotes every shell meta-character in the value, so that it can be + passed safely to the shell. + + ::qq Quotes every shell meta-character in the value, and also doubles `$' + characters so that it can be passed safely through recursive + invocations of bbmmaakkee. This is equivalent to `::SS//\\$$//&&&&//gg::QQ'. + + ::RR Replaces each word with everything but its suffix. + + ::rraannggee[==_c_o_u_n_t] + The value is an integer sequence representing the words of the + original value, or the supplied _c_o_u_n_t. + + ::ggmmttiimmee[==_t_i_m_e_s_t_a_m_p] + The value is interpreted as a format string for strftime(3), using + gmtime(3), producing the formatted timestamp. Note: the `%s' format + should only be used with `::llooccaallttiimmee'. If a _t_i_m_e_s_t_a_m_p value is not + provided or is 0, the current time is used. + + ::hhaasshh + Computes a 32-bit hash of the value and encodes it as 8 hex digits. + + ::llooccaallttiimmee[==_t_i_m_e_s_t_a_m_p] + The value is interpreted as a format string for strftime(3), using + localtime(3), producing the formatted timestamp. If a _t_i_m_e_s_t_a_m_p + value is not provided or is 0, the current time is used. + + ::mmttiimmee[==_t_i_m_e_s_t_a_m_p] + Call stat(2) with each word as pathname; use `st_mtime' as the new + value. If stat(2) fails; use _t_i_m_e_s_t_a_m_p or current time. If + _t_i_m_e_s_t_a_m_p is set to `error', then stat(2) failure will cause an + error. + + ::ttAA Attempts to convert the value to an absolute path using realpath(3). + If that fails, the value is unchanged. + + ::ttll Converts the value to lower-case letters. + + ::ttss_c + When joining the words after a modifier that treats the value as + words, the words are normally separated by a space. This modifier + changes the separator to the character _c. If _c is omitted, no + separator is used. The common escapes (including octal numeric + codes) work as expected. + + ::ttuu Converts the value to upper-case letters. + + ::ttWW Causes subsequent modifiers to treat the value as a single word + (possibly containing embedded whitespace). See also `::[[**]]'. + + ::ttww Causes the value to be treated as a list of words. See also `::[[@@]]'. + + ::SS/_o_l_d___s_t_r_i_n_g/_n_e_w___s_t_r_i_n_g/[11ggWW] + Modifies the first occurrence of _o_l_d___s_t_r_i_n_g in each word of the + value, replacing it with _n_e_w___s_t_r_i_n_g. If a `g' is appended to the + last delimiter of the pattern, all occurrences in each word are + replaced. If a `1' is appended to the last delimiter of the + pattern, only the first occurrence is affected. If a `W' is + appended to the last delimiter of the pattern, the value is treated + as a single word. If _o_l_d___s_t_r_i_n_g begins with a caret (`^'), + _o_l_d___s_t_r_i_n_g is anchored at the beginning of each word. If _o_l_d___s_t_r_i_n_g + ends with a dollar sign (`$'), it is anchored at the end of each + word. Inside _n_e_w___s_t_r_i_n_g, an ampersand (`&') is replaced by + _o_l_d___s_t_r_i_n_g (without the anchoring `^' or `$'). Any character may be + used as the delimiter for the parts of the modifier string. The + anchoring, ampersand and delimiter characters can be escaped with a + backslash (`\'). + + Both _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g may contain nested expressions. To + prevent a dollar sign from starting a nested expression, escape it + with a backslash. + + ::CC/_p_a_t_t_e_r_n/_r_e_p_l_a_c_e_m_e_n_t/[11ggWW] + The ::CC modifier works like the ::SS modifier except that the old and + new strings, instead of being simple strings, are an extended + regular expression _p_a_t_t_e_r_n (see regex(3)) and an ed(1)-style + _r_e_p_l_a_c_e_m_e_n_t. Normally, the first occurrence of the pattern _p_a_t_t_e_r_n + in each word of the value is substituted with _r_e_p_l_a_c_e_m_e_n_t. The `1' + modifier causes the substitution to apply to at most one word; the + `g' modifier causes the substitution to apply to as many instances + of the search pattern _p_a_t_t_e_r_n as occur in the word or words it is + found in; the `W' modifier causes the value to be treated as a + single word (possibly containing embedded whitespace). + + As for the ::SS modifier, the _p_a_t_t_e_r_n and _r_e_p_l_a_c_e_m_e_n_t are subjected to + variable expansion before being parsed as regular expressions. + + ::TT Replaces each word with its last path component (basename). + + ::uu Removes adjacent duplicate words (like uniq(1)). + + ::??_t_r_u_e___s_t_r_i_n_g::_f_a_l_s_e___s_t_r_i_n_g + If the variable name (not its value), when parsed as a ..iiff + conditional expression, evaluates to true, return as its value the + _t_r_u_e___s_t_r_i_n_g, otherwise return the _f_a_l_s_e___s_t_r_i_n_g. Since the variable + name is used as the expression, :? must be the first modifier after + the variable name itself--which, of course, usually contains + variable expansions. A common error is trying to use expressions + like + ${NUMBERS:M42:?match:no} + which actually tests defined(NUMBERS). To determine if any words + match "42", you need to use something like: + ${"${NUMBERS:M42}" != "":?match:no}. + + ::_o_l_d___s_t_r_i_n_g==_n_e_w___s_t_r_i_n_g + This is the AT&T System V UNIX style substitution. It can only be + the last modifier specified, as a `:' in either _o_l_d___s_t_r_i_n_g or + _n_e_w___s_t_r_i_n_g is treated as a regular character, not as the end of the + modifier. + + If _o_l_d___s_t_r_i_n_g does not contain the pattern matching character `%', + and the word ends with _o_l_d___s_t_r_i_n_g or equals it, that suffix is + replaced with _n_e_w___s_t_r_i_n_g. + + Otherwise, the first `%' in _o_l_d___s_t_r_i_n_g matches a possibly empty + substring of arbitrary characters, and if the whole pattern is found + in the word, the matching part is replaced with _n_e_w___s_t_r_i_n_g, and the + first occurrence of `%' in _n_e_w___s_t_r_i_n_g (if any) is replaced with the + substring matched by the `%'. + + Both _o_l_d___s_t_r_i_n_g and _n_e_w___s_t_r_i_n_g may contain nested expressions. To + prevent a dollar sign from starting a nested expression, escape it + with a backslash. + + ::@@_v_a_r_n_a_m_e@@_s_t_r_i_n_g@@ + This is the loop expansion mechanism from the OSF Development + Environment (ODE) make. Unlike ..ffoorr loops, expansion occurs at the + time of reference. For each word in the value, assign the word to + the variable named _v_a_r_n_a_m_e and evaluate _s_t_r_i_n_g. The ODE convention + is that _v_a_r_n_a_m_e should start and end with a period, for example: + ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@} + + However, a single-letter variable is often more readable: + ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} + + ::__[==_v_a_r] + Saves the current variable value in `$_' or the named _v_a_r for later + reference. Example usage: + + M_cmpv.units = 1 1000 1000000 + M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \ + \* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh + + .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}} + + Here `$_' is used to save the result of the `:S' modifier which is + later referenced using the index values from `:range'. + + ::UU_n_e_w_v_a_l + If the variable is undefined, the optional _n_e_w_v_a_l (which may be + empty) is the value. If the variable is defined, the existing value + is returned. This is another ODE make feature. It is handy for + setting per-target CFLAGS for instance: + ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}} + If a value is only required if the variable is undefined, use: + ${VAR:D:Unewval} + + ::DD_n_e_w_v_a_l + If the variable is defined, _n_e_w_v_a_l (which may be empty) is the + value. + + ::LL The name of the variable is the value. + + ::PP The path of the node which has the same name as the variable is the + value. If no such node exists or its path is null, the name of the + variable is used. In order for this modifier to work, the name + (node) must at least have appeared on the right-hand side of a + dependency. + + ::!!_c_m_d!! + The output of running _c_m_d is the value. + + ::sshh The value is run as a command, and the output becomes the new value. + + ::::==_s_t_r + The variable is assigned the value _s_t_r after substitution. This + modifier and its variations are useful in obscure situations such as + wanting to set a variable at a point where a target's shell commands + are being parsed. These assignment modifiers always expand to + nothing. + + The `::::' helps avoid false matches with the AT&T System V UNIX style + `:=' modifier and since substitution always occurs, the `::=' form + is vaguely appropriate. + + ::::??==_s_t_r + As for ::::== but only if the variable does not already have a value. + + ::::++==_s_t_r + Append _s_t_r to the variable. + + ::::!!==_c_m_d + Assign the output of _c_m_d to the variable. + + ::[[_r_a_n_g_e]] + Selects one or more words from the value, or performs other + operations related to the way in which the value is split into + words. + + An empty value, or a value that consists entirely of white-space, is + treated as a single word. For the purposes of the `::[[]]' modifier, + the words are indexed both forwards using positive integers (where + index 1 represents the first word), and backwards using negative + integers (where index -1 represents the last word). + + The _r_a_n_g_e is subjected to variable expansion, and the expanded + result is then interpreted as follows: + + _i_n_d_e_x Selects a single word from the value. + + _s_t_a_r_t...._e_n_d + Selects all words from _s_t_a_r_t to _e_n_d, inclusive. For example, + `::[[22....--11]]' selects all words from the second word to the last + word. If _s_t_a_r_t is greater than _e_n_d, the words are output in + reverse order. For example, `::[[--11....11]]' selects all the words + from last to first. If the list is already ordered, this + effectively reverses the list, but it is more efficient to + use `::OOrr' instead of `::OO::[[--11....11]]'. + + ** Causes subsequent modifiers to treat the value as a single + word (possibly containing embedded whitespace). Analogous to + the effect of $* in Bourne shell. + + 0 Means the same as `::[[**]]'. + + @@ Causes subsequent modifiers to treat the value as a sequence + of words delimited by whitespace. Analogous to the effect of + $@ in Bourne shell. + + ## Returns the number of words in the value. + +DDIIRREECCTTIIVVEESS + bbmmaakkee offers directives for including makefiles, conditionals and for + loops. All these directives are identified by a line beginning with a + single dot (`.') character, followed by the keyword of the directive, + such as iinncclluuddee or iiff. + + FFiillee iinncclluussiioonn + Files are included with either ..iinncclluuddee <<_f_i_l_e>> or ..iinncclluuddee ""_f_i_l_e"". + Variables between the angle brackets or double quotes are expanded to + form the file name. If angle brackets are used, the included makefile is + expected to be in the system makefile directory. If double quotes are + used, the including makefile's directory and any directories specified + using the --II option are searched before the system makefile directory. + + For compatibility with other make variants, `iinncclluuddee _f_i_l_e ...' (without + leading dot) is also accepted. + + If the include statement is written as ..--iinncclluuddee or as ..ssiinncclluuddee, errors + locating and/or opening include files are ignored. + + If the include statement is written as ..ddiinncclluuddee, not only are errors + locating and/or opening include files ignored, but stale dependencies + within the included file are ignored just like in _._M_A_K_E_._D_E_P_E_N_D_F_I_L_E. + + EExxppoorrttiinngg vvaarriiaabblleess + The directives for exporting and unexporting variables are: + + ..eexxppoorrtt _v_a_r_i_a_b_l_e ... + Export the specified global variable. If no variable list is + provided, all globals are exported except for internal variables + (those that start with `.'). This is not affected by the --XX + flag, so should be used with caution. For compatibility with + other make programs, eexxppoorrtt _v_a_r_i_a_b_l_e==_v_a_l_u_e (without leading dot) + is also accepted. + + Appending a variable name to _._M_A_K_E_._E_X_P_O_R_T_E_D is equivalent to + exporting a variable. + + ..eexxppoorrtt--eennvv _v_a_r_i_a_b_l_e ... + The same as `.export', except that the variable is not appended + to _._M_A_K_E_._E_X_P_O_R_T_E_D. This allows exporting a value to the + environment which is different from that used by bbmmaakkee + internally. + + ..eexxppoorrtt--lliitteerraall _v_a_r_i_a_b_l_e ... + The same as `.export-env', except that variables in the value are + not expanded. + + ..uunneexxppoorrtt _v_a_r_i_a_b_l_e ... + The opposite of `.export'. The specified global _v_a_r_i_a_b_l_e is + removed from _._M_A_K_E_._E_X_P_O_R_T_E_D. If no variable list is provided, + all globals are unexported, and _._M_A_K_E_._E_X_P_O_R_T_E_D deleted. + + ..uunneexxppoorrtt--eennvv + Unexport all globals previously exported and clear the + environment inherited from the parent. This operation causes a + memory leak of the original environment, so should be used + sparingly. Testing for _._M_A_K_E_._L_E_V_E_L being 0 would make sense. + Also note that any variables which originated in the parent + environment should be explicitly preserved if desired. For + example: + + .if ${.MAKE.LEVEL} == 0 + PATH := ${PATH} + .unexport-env + .export PATH + .endif + + Would result in an environment containing only `PATH', which is + the minimal useful environment. Actually `_._M_A_K_E_._L_E_V_E_L' is also + pushed into the new environment. + + MMeessssaaggeess + The directives for printing messages to the output are: + + ..iinnffoo _m_e_s_s_a_g_e + The message is printed along with the name of the makefile and + line number. + + ..wwaarrnniinngg _m_e_s_s_a_g_e + The message prefixed by `warning:' is printed along with the name + of the makefile and line number. + + ..eerrrroorr _m_e_s_s_a_g_e + The message is printed along with the name of the makefile and + line number, bbmmaakkee exits immediately. + + CCoonnddiittiioonnaallss + The directives for conditionals are: + + ..iiff [!!]_e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n ...] + Test the value of an expression. + + ..iiffddeeff [!!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e ...] + Test whether a variable is defined. + + ..iiffnnddeeff [!!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e ...] + Test whether a variable is not defined. + + ..iiffmmaakkee [!!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t ...] + Test the target being requested. + + ..iiffnnmmaakkee [!!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t ...] + Test the target being requested. + + ..eellssee Reverse the sense of the last conditional. + + ..eelliiff [!!]_e_x_p_r_e_s_s_i_o_n [_o_p_e_r_a_t_o_r _e_x_p_r_e_s_s_i_o_n ...] + A combination of `..eellssee' followed by `..iiff'. + + ..eelliiffddeeff [!!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e ...] + A combination of `..eellssee' followed by `..iiffddeeff'. + + ..eelliiffnnddeeff [!!]_v_a_r_i_a_b_l_e [_o_p_e_r_a_t_o_r _v_a_r_i_a_b_l_e ...] + A combination of `..eellssee' followed by `..iiffnnddeeff'. + + ..eelliiffmmaakkee [!!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t ...] + A combination of `..eellssee' followed by `..iiffmmaakkee'. + + ..eelliiffnnmmaakkee [!!]_t_a_r_g_e_t [_o_p_e_r_a_t_o_r _t_a_r_g_e_t ...] + A combination of `..eellssee' followed by `..iiffnnmmaakkee'. + + ..eennddiiff End the body of the conditional. + + The _o_p_e_r_a_t_o_r may be any one of the following: + + |||| Logical OR. + + &&&& Logical AND; of higher precedence than `||||'. + + bbmmaakkee only evaluates a conditional as far as is necessary to determine + its value. Parentheses can be used to override the operator precedence. + The boolean operator `!!' may be used to logically negate an expression, + typically a function call. It is of higher precedence than `&&&&'. + + The value of _e_x_p_r_e_s_s_i_o_n may be any of the following function call + expressions: + + ddeeffiinneedd(_v_a_r_n_a_m_e) + Evaluates to true if the variable _v_a_r_n_a_m_e has been defined. + + mmaakkee(_t_a_r_g_e_t) + Evaluates to true if the target was specified as part of bbmmaakkee's + command line or was declared the default target (either + implicitly or explicitly, see _._M_A_I_N) before the line containing + the conditional. + + eemmppttyy(_v_a_r_n_a_m_e[:_m_o_d_i_f_i_e_r_s]) + Evaluates to true if the expansion of the variable, after + applying the modifiers, results in an empty string. + + eexxiissttss(_p_a_t_h_n_a_m_e) + Evaluates to true if the given pathname exists. If relative, the + pathname is searched for on the system search path (see _._P_A_T_H). + + ttaarrggeett(_t_a_r_g_e_t) + Evaluates to true if the target has been defined. + + ccoommmmaannddss(_t_a_r_g_e_t) + Evaluates to true if the target has been defined and has commands + associated with it. + + _E_x_p_r_e_s_s_i_o_n may also be an arithmetic or string comparison. Variable + expansion is performed on both sides of the comparison. If both sides + are numeric and neither is enclosed in quotes, the comparison is done + numerically, otherwise lexicographically. A string is interpreted as a + hexadecimal integer if it is preceded by 0x, otherwise it is interpreted + as a decimal floating-point number; octal numbers are not supported. + + All comparisons may use the operators `====' and `!!=='. Numeric comparisons + may also use the operators `<<', `<<==', `>>' and `>>=='. + + If the comparison has neither a comparison operator nor a right side, the + expression evaluates to true if it is nonempty and its numeric value (if + any) is not zero. + + When bbmmaakkee is evaluating one of these conditional expressions, and it + encounters a (whitespace-separated) word it doesn't recognize, either the + "make" or "defined" function is applied to it, depending on the form of + the conditional. If the form is `..iiffddeeff', `..iiffnnddeeff' or `..iiff', the + "defined" function is applied. Similarly, if the form is `..iiffmmaakkee' or + `..iiffnnmmaakkee', the "make" function is applied. + + If the conditional evaluates to true, parsing of the makefile continues + as before. If it evaluates to false, the following lines until the + corresponding `..eelliiff' variant, `..eellssee' or `..eennddiiff' are skipped. + + FFoorr llooooppss + For loops are typically used to apply a set of rules to a list of files. + The syntax of a for loop is: + + ..ffoorr _v_a_r_i_a_b_l_e [_v_a_r_i_a_b_l_e ...] iinn _e_x_p_r_e_s_s_i_o_n + <_m_a_k_e_-_l_i_n_e_s> + ..eennddffoorr + + The _e_x_p_r_e_s_s_i_o_n is expanded and then split into words. On each iteration + of the loop, one word is taken and assigned to each _v_a_r_i_a_b_l_e, in order, + and these _v_a_r_i_a_b_l_e_s are substituted into the _m_a_k_e_-_l_i_n_e_s inside the body + of the for loop. The number of words must come out even; that is, if + there are three iteration variables, the number of words provided must be + a multiple of three. + + If `..bbrreeaakk' is encountered within a ..ffoorr loop, it causes early + termination of the loop, otherwise a parse error. + + OOtthheerr ddiirreeccttiivveess + ..uunnddeeff _v_a_r_i_a_b_l_e ... + Un-define the specified global variables. Only global variables + can be un-defined. + +CCOOMMMMEENNTTSS + Comments begin with a hash (`#') character, anywhere but in a shell + command line, and continue to the end of an unescaped new line. + +SSPPEECCIIAALL SSOOUURRCCEESS ((AATTTTRRIIBBUUTTEESS)) + ..EEXXEECC Target is never out of date, but always execute commands + anyway. + + ..IIGGNNOORREE Ignore any errors from the commands associated with this + target, exactly as if they all were preceded by a dash (`-'). + + ..MMAADDEE Mark all sources of this target as being up to date. + + ..MMAAKKEE Execute the commands associated with this target even if the --nn + or --tt options were specified. Normally used to mark recursive + bbmmaakkees. + + ..MMEETTAA Create a meta file for the target, even if it is flagged as + ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL. Usage in conjunction with ..MMAAKKEE is + the most likely case. In "meta" mode, the target is out-of- + date if the meta file is missing. + + ..NNOOMMEETTAA Do not create a meta file for the target. Meta files are also + not created for ..PPHHOONNYY, ..MMAAKKEE, or ..SSPPEECCIIAALL targets. + + ..NNOOMMEETTAA__CCMMPP + Ignore differences in commands when deciding if target is out + of date. This is useful if the command contains a value which + always changes. If the number of commands change, though, the + target is still considered out of date. The same effect + applies to any command line that uses the variable _._O_O_D_A_T_E, + which can be used for that purpose even when not otherwise + needed or desired: + + + skip-compare-for-some: + @echo this is compared + @echo this is not ${.OODATE:M.NOMETA_CMP} + @echo this is also compared + + The ::MM pattern suppresses any expansion of the unwanted + variable. + + ..NNOOPPAATTHH Do not search for the target in the directories specified by + _._P_A_T_H. + + ..NNOOTTMMAAIINN Normally bbmmaakkee selects the first target it encounters as the + default target to be built if no target was specified. This + source prevents this target from being selected. + + ..OOPPTTIIOONNAALL + If a target is marked with this attribute and bbmmaakkee can't + figure out how to create it, it ignores this fact and assumes + the file isn't needed or already exists. + + ..PPHHOONNYY The target does not correspond to an actual file; it is always + considered to be out of date, and is not created with the --tt + option. Suffix-transformation rules are not applied to ..PPHHOONNYY + targets. + + ..PPRREECCIIOOUUSS + When bbmmaakkee is interrupted, it normally removes any partially + made targets. This source prevents the target from being + removed. + + ..RREECCUURRSSIIVVEE + Synonym for ..MMAAKKEE. + + ..SSIILLEENNTT Do not echo any of the commands associated with this target, + exactly as if they all were preceded by an at sign (`@'). + + ..UUSSEE Turn the target into bbmmaakkee's version of a macro. When the + target is used as a source for another target, the other target + acquires the commands, sources, and attributes (except for + ..UUSSEE) of the source. If the target already has commands, the + ..UUSSEE target's commands are appended to them. + + ..UUSSEEBBEEFFOORREE + Like ..UUSSEE, but instead of appending, prepend the ..UUSSEEBBEEFFOORREE + target commands to the target. + + ..WWAAIITT If ..WWAAIITT appears in a dependency line, the sources that precede + it are made before the sources that succeed it in the line. + Since the dependents of files are not made until the file + itself could be made, this also stops the dependents being + built unless they are needed for another branch of the + dependency tree. So given: + + x: a .WAIT b + echo x + a: + echo a + b: b1 + echo b + b1: + echo b1 + + the output is always `a', `b1', `b', `x'. + + The ordering imposed by ..WWAAIITT is only relevant for parallel + makes. + +SSPPEECCIIAALL TTAARRGGEETTSS + Special targets may not be included with other targets, i.e. they must be + the only target specified. + + ..BBEEGGIINN Any command lines attached to this target are executed before + anything else is done. + + ..DDEEFFAAUULLTT + This is sort of a ..UUSSEE rule for any target (that was used only + as a source) that bbmmaakkee can't figure out any other way to + create. Only the shell script is used. The _._I_M_P_S_R_C variable of + a target that inherits ..DDEEFFAAUULLTT's commands is set to the + target's own name. + + ..DDEELLEETTEE__OONN__EERRRROORR + If this target is present in the makefile, it globally causes + make to delete targets whose commands fail. (By default, only + targets whose commands are interrupted during execution are + deleted. This is the historical behavior.) This setting can be + used to help prevent half-finished or malformed targets from + being left around and corrupting future rebuilds. + + ..EENNDD Any command lines attached to this target are executed after + everything else is done successfully. + + ..EERRRROORR Any command lines attached to this target are executed when + another target fails. See _M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R for the + variables that will be set. + + ..IIGGNNOORREE Mark each of the sources with the ..IIGGNNOORREE attribute. If no + sources are specified, this is the equivalent of specifying the + --ii option. + + ..IINNTTEERRRRUUPPTT + If bbmmaakkee is interrupted, the commands for this target are + executed. + + ..MMAAIINN If no target is specified when bbmmaakkee is invoked, this target is + built. + + ..MMAAKKEEFFLLAAGGSS + This target provides a way to specify flags for bbmmaakkee at the + time when the makefiles are read. The flags are as if typed to + the shell, though the --ff option has no effect. + + ..NNOOPPAATTHH Apply the ..NNOOPPAATTHH attribute to any specified sources. + + ..NNOOTTPPAARRAALLLLEELL + Disable parallel mode. + + ..NNOO__PPAARRAALLLLEELL + Synonym for ..NNOOTTPPAARRAALLLLEELL, for compatibility with other pmake + variants. + + ..NNOORREEAADDOONNLLYY + clear the read-only attribute from the global variables + specified as sources. + + ..OOBBJJDDIIRR The source is a new value for `_._O_B_J_D_I_R'. If it exists, bbmmaakkee + changes the current working directory to it and updates the + value of `_._O_B_J_D_I_R'. + + ..OORRDDEERR In parallel mode, the named targets are made in sequence. This + ordering does not add targets to the list of targets to be made. + + Since the dependents of a target do not get built until the + target itself could be built, unless `a' is built by another + part of the dependency graph, the following is a dependency + loop: + + .ORDER: b a + b: a + + ..PPAATTHH The sources are directories which are to be searched for files + not found in the current directory. If no sources are + specified, any previously specified directories are removed from + the search path. If the source is the special ..DDOOTTLLAASSTT target, + the current working directory is searched last. + + ..PPAATTHH.._s_u_f_f_i_x + Like ..PPAATTHH but applies only to files with a particular suffix. + The suffix must have been previously declared with ..SSUUFFFFIIXXEESS. + + ..PPHHOONNYY Apply the ..PPHHOONNYY attribute to any specified sources. + + ..PPOOSSIIXX If this is the first non-comment line in the main makefile, the + variable _%_P_O_S_I_X is set to the value `1003.2' and the makefile + `<posix.mk>' is included if it exists, to provide POSIX- + compatible default rules. If bbmmaakkee is run with the --rr flag, + only `posix.mk' contributes to the default rules. + + ..PPRREECCIIOOUUSS + Apply the ..PPRREECCIIOOUUSS attribute to any specified sources. If no + sources are specified, the ..PPRREECCIIOOUUSS attribute is applied to + every target in the file. + + ..RREEAADDOONNLLYY + set the read-only attribute on the global variables specified as + sources. + + ..SSHHEELLLL Sets the shell that bbmmaakkee uses to execute commands. The sources + are a set of _f_i_e_l_d==_v_a_l_u_e pairs. + + name This is the minimal specification, used to + select one of the built-in shell specs; sh, ksh, + and csh. + + path Specifies the absolute path to the shell. + + hasErrCtl Indicates whether the shell supports exit on + error. + + check The command to turn on error checking. + + ignore The command to disable error checking. + + echo The command to turn on echoing of commands + executed. + + quiet The command to turn off echoing of commands + executed. + + filter The output to filter after issuing the quiet + command. It is typically identical to quiet. + + errFlag The flag to pass the shell to enable error + checking. + + echoFlag The flag to pass the shell to enable command + echoing. + + newline The string literal to pass the shell that + results in a single newline character when used + outside of any quoting characters. + Example: + + .SHELL: name=ksh path=/bin/ksh hasErrCtl=true \ + check="set -e" ignore="set +e" \ + echo="set -v" quiet="set +v" filter="set +v" \ + echoFlag=v errFlag=e newline="'\n'" + + ..SSIILLEENNTT Apply the ..SSIILLEENNTT attribute to any specified sources. If no + sources are specified, the ..SSIILLEENNTT attribute is applied to every + command in the file. + + ..SSTTAALLEE This target gets run when a dependency file contains stale + entries, having _._A_L_L_S_R_C set to the name of that dependency file. + + ..SSUUFFFFIIXXEESS + Each source specifies a suffix to bbmmaakkee. If no sources are + specified, any previously specified suffixes are deleted. It + allows the creation of suffix-transformation rules. + + Example: + + .SUFFIXES: .c .o + .c.o: + cc -o ${.TARGET} -c ${.IMPSRC} + + ..SSYYSSPPAATTHH + The sources are directories which are to be added to the system + include path which bbmmaakkee searches for makefiles. If no sources + are specified, any previously specified directories are removed + from the system include path. + +EENNVVIIRROONNMMEENNTT + bbmmaakkee uses the following environment variables, if they exist: MACHINE, + MACHINE_ARCH, MAKE, MAKEFLAGS, MAKEOBJDIR, MAKEOBJDIRPREFIX, MAKESYSPATH, + PWD, and TMPDIR. + + MAKEOBJDIRPREFIX and MAKEOBJDIR may only be set in the environment or on + the command line to bbmmaakkee and not as makefile variables; see the + description of `_._O_B_J_D_I_R' for more details. + +FFIILLEESS + .depend list of dependencies + makefile first default makefile if no makefile is specified on the + command line + Makefile second default makefile if no makefile is specified on the + command line + sys.mk system makefile + /usr/share/mk system makefile directory + +CCOOMMPPAATTIIBBIILLIITTYY + The basic make syntax is compatible between different make variants; + however the special variables, variable modifiers and conditionals are + not. + + OOllddeerr vveerrssiioonnss + An incomplete list of changes in older versions of bbmmaakkee: + + The way that .for loop variables are substituted changed after NetBSD 5.0 + so that they still appear to be variable expansions. In particular this + stops them being treated as syntax, and removes some obscure problems + using them in .if statements. + + The way that parallel makes are scheduled changed in NetBSD 4.0 so that + .ORDER and .WAIT apply recursively to the dependent nodes. The + algorithms used may change again in the future. + + OOtthheerr mmaakkee ddiiaalleeccttss + Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not + support most of the features of bbmmaakkee as described in this manual. Most + notably: + + ++oo The ..WWAAIITT and ..OORRDDEERR declarations and most functionality + pertaining to parallelization. (GNU make supports + parallelization but lacks the features needed to control it + effectively.) + + ++oo Directives, including for loops and conditionals and most of + the forms of include files. (GNU make has its own incompatible + and less powerful syntax for conditionals.) + + ++oo All built-in variables that begin with a dot. + + ++oo Most of the special sources and targets that begin with a dot, + with the notable exception of ..PPHHOONNYY, ..PPRREECCIIOOUUSS, and ..SSUUFFFFIIXXEESS. + + ++oo Variable modifiers, except for the `:old=new' string + substitution, which does not portably support globbing with `%' + and historically only works on declared suffixes. + + ++oo The $$>> variable even in its short form; most makes support this + functionality but its name varies. + + Some features are somewhat more portable, such as assignment with ++==, ??==, + and !!==. The _._P_A_T_H functionality is based on an older feature VVPPAATTHH found + in GNU make and many versions of SVR4 make; however, historically its + behavior is too ill-defined (and too buggy) to rely upon. + + The $$@@ and $$<< variables are more or less universally portable, as is the + $$((MMAAKKEE)) variable. Basic use of suffix rules (for files only in the + current directory, not trying to chain transformations together, etc.) is + also reasonably portable. + +SSEEEE AALLSSOO + mkdep(1) + +HHIISSTTOORRYY + bbmmaakkee is derived from NetBSD make(1). It uses autoconf to facilitate + portability to other platforms. + + A make command appeared in Version 7 AT&T UNIX. This make implementation + is based on Adam de Boor's pmake program, which was written for Sprite at + Berkeley. It was designed to be a parallel distributed make running jobs + on different machines using a daemon called "customs". + + Historically the target/dependency FFRRCC has been used to FoRCe rebuilding + (since the target/dependency does not exist ... unless someone creates an + _F_R_C file). + +BBUUGGSS + The make syntax is difficult to parse. For instance, finding the end of + a variable's use should involve scanning each of the modifiers, using the + correct terminator for each field. In many places make just counts {} + and () in order to find the end of a variable expansion. + + There is no way of escaping a space character in a filename. + + In jobs mode, when a target fails; make will put an error token into the + job token pool. This will cause all other instances of make using that + token pool to abort the build and exit with error code 6. Sometimes the + attempt to suppress a cascade of unnecessary errors, can result in a + seemingly unexplained `*** Error code 6' + +FreeBSD 13.2-RELEASE-p10 March 9, 2024 FreeBSD 13.2-RELEASE-p10 diff --git a/contrib/bmake/buf.c b/contrib/bmake/buf.c index fdc6c8ec2b60..8f4de0c3e2bc 100644 --- a/contrib/bmake/buf.c +++ b/contrib/bmake/buf.c @@ -1,4 +1,4 @@ -/* $NetBSD: buf.c,v 1.57 2023/12/19 19:33:39 rillig Exp $ */ +/* $NetBSD: buf.c,v 1.58 2024/04/28 15:10:19 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -75,7 +75,7 @@ #include "make.h" /* "@(#)buf.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: buf.c,v 1.57 2023/12/19 19:33:39 rillig Exp $"); +MAKE_RCSID("$NetBSD: buf.c,v 1.58 2024/04/28 15:10:19 rillig Exp $"); /* Make space in the buffer for adding at least 16 more bytes. */ void @@ -187,30 +187,3 @@ Buf_DoneData(Buffer *buf) return data; } - -#ifndef BUF_COMPACT_LIMIT -# define BUF_COMPACT_LIMIT 128 /* worthwhile saving */ -#endif - -/* - * Return the data from the buffer. - * Leave the buffer itself in an indeterminate state. - * - * If the buffer size is much greater than its content, - * a new buffer will be allocated and the old one freed. - */ -char * -Buf_DoneDataCompact(Buffer *buf) -{ -#if BUF_COMPACT_LIMIT > 0 - if (buf->cap - buf->len >= BUF_COMPACT_LIMIT) { - /* We trust realloc to be smart */ - char *data = bmake_realloc(buf->data, buf->len + 1); - buf->data = NULL; - data[buf->len] = '\0'; /* XXX: unnecessary */ - Buf_Done(buf); - return data; - } -#endif - return Buf_DoneData(buf); -} diff --git a/contrib/bmake/buf.h b/contrib/bmake/buf.h index c5e7d539de9e..fad36e932616 100644 --- a/contrib/bmake/buf.h +++ b/contrib/bmake/buf.h @@ -1,4 +1,4 @@ -/* $NetBSD: buf.h,v 1.49 2023/12/19 19:33:39 rillig Exp $ */ +/* $NetBSD: buf.h,v 1.50 2024/04/28 15:10:19 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -124,6 +124,5 @@ void Buf_Init(Buffer *); void Buf_InitSize(Buffer *, size_t); void Buf_Done(Buffer *); char *Buf_DoneData(Buffer *) MAKE_ATTR_USE; -char *Buf_DoneDataCompact(Buffer *) MAKE_ATTR_USE; #endif diff --git a/contrib/bmake/compat.c b/contrib/bmake/compat.c index 05c6ea0e7ec8..3a8b1c4b2640 100644 --- a/contrib/bmake/compat.c +++ b/contrib/bmake/compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: compat.c,v 1.254 2024/03/10 02:53:37 sjg Exp $ */ +/* $NetBSD: compat.c,v 1.255 2024/04/20 10:18:55 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -94,7 +94,7 @@ #include "pathnames.h" /* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: compat.c,v 1.254 2024/03/10 02:53:37 sjg Exp $"); +MAKE_RCSID("$NetBSD: compat.c,v 1.255 2024/04/20 10:18:55 rillig Exp $"); static GNode *curTarg = NULL; static pid_t compatChild; @@ -237,7 +237,9 @@ Compat_RunCommand(const char *cmdp, GNode *gn, StringListNode *ln) errCheck = !(gn->type & OP_IGNORE); doIt = false; + EvalStack_Push(gn->name, NULL, NULL); cmdStart = Var_Subst(cmd, gn, VARE_WANTRES); + EvalStack_Pop(); /* TODO: handle errors */ if (cmdStart[0] == '\0') { diff --git a/contrib/bmake/cond.c b/contrib/bmake/cond.c index f8d31fc9c160..5001677303e2 100644 --- a/contrib/bmake/cond.c +++ b/contrib/bmake/cond.c @@ -1,4 +1,4 @@ -/* $NetBSD: cond.c,v 1.362 2024/02/07 07:21:22 rillig Exp $ */ +/* $NetBSD: cond.c,v 1.363 2024/04/23 22:51:28 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -91,7 +91,7 @@ #include "dir.h" /* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ -MAKE_RCSID("$NetBSD: cond.c,v 1.362 2024/02/07 07:21:22 rillig Exp $"); +MAKE_RCSID("$NetBSD: cond.c,v 1.363 2024/04/23 22:51:28 rillig Exp $"); /* * Conditional expressions conform to this grammar: @@ -424,13 +424,12 @@ CondParser_StringExpr(CondParser *par, const char *start, * Parse a string from an expression or an optionally quoted string, * on the left-hand and right-hand sides of comparisons. * - * Results: - * Returns the string without any enclosing quotes, or NULL on error. - * Sets out_quoted if the leaf was a quoted string literal. + * Return the string without any enclosing quotes, or NULL on error. + * Sets out_quoted if the leaf was a quoted string literal. */ -static void +static FStr CondParser_Leaf(CondParser *par, bool doEval, bool unquotedOK, - FStr *out_str, bool *out_quoted) + bool *out_quoted) { Buffer buf; FStr str; @@ -492,7 +491,7 @@ return_buf: buf.data = NULL; return_str: Buf_Done(&buf); - *out_str = str; + return str; } /* @@ -602,7 +601,7 @@ CondParser_Comparison(CondParser *par, bool doEval) ComparisonOp op; bool lhsQuoted, rhsQuoted; - CondParser_Leaf(par, doEval, par->leftUnquotedOK, &lhs, &lhsQuoted); + lhs = CondParser_Leaf(par, doEval, par->leftUnquotedOK, &lhsQuoted); if (lhs.str == NULL) goto done_lhs; @@ -622,7 +621,7 @@ CondParser_Comparison(CondParser *par, bool doEval) goto done_lhs; } - CondParser_Leaf(par, doEval, true, &rhs, &rhsQuoted); + rhs = CondParser_Leaf(par, doEval, true, &rhsQuoted); t = rhs.str == NULL ? TOK_ERROR : !doEval ? TOK_FALSE : EvalCompare(par, lhs.str, lhsQuoted, op, rhs.str, rhsQuoted); diff --git a/contrib/bmake/configure b/contrib/bmake/configure index 0b4084b26ed4..08a550f3cf86 100755 --- a/contrib/bmake/configure +++ b/contrib/bmake/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for bmake 20240212. +# Generated by GNU Autoconf 2.71 for bmake 20240314. # # Report bugs to <sjg@NetBSD.org>. # @@ -610,8 +610,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bmake' PACKAGE_TARNAME='bmake' -PACKAGE_VERSION='20240212' -PACKAGE_STRING='bmake 20240212' +PACKAGE_VERSION='20240314' +PACKAGE_STRING='bmake 20240314' PACKAGE_BUGREPORT='sjg@NetBSD.org' PACKAGE_URL='' @@ -664,6 +664,8 @@ force_machine_arch machine_arch force_machine machine +force_make_os +make_os egrep LIBOBJS bmake_path_max @@ -1291,7 +1293,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures bmake 20240212 to adapt to many kinds of systems. +\`configure' configures bmake 20240314 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1353,7 +1355,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bmake 20240212:";; + short | recursive ) echo "Configuration of bmake 20240314:";; esac cat <<\_ACEOF @@ -1463,7 +1465,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bmake configure 20240212 +bmake configure 20240314 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1970,7 +1972,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bmake $as_me 20240212, which was +It was created by bmake $as_me 20240314, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -2784,10 +2786,21 @@ no) ;; esac fi +FORCE_MAKE_OS= +make_os= case "$OS" in -CYGWIN*|Darwin|MINGW*) use_makefile=no;; +CYGWIN*) + use_makefile=no + OS=Cygwin + FORCE_MAKE_OS=$OS + ;; +Darwin|MINGW*) use_makefile=no;; *) use_makefile=yes;; esac +if test "x$FORCE_MAKE_OS" != x; then + force_make_os=FORCE_ + make_os=${FORCE_MAKE_OS} +fi # Check whether --with-makefile was given. if test ${with_makefile+y} @@ -2871,9 +2884,12 @@ Minix) CPPFLAGS="${CPPFLAGS} -D_NETBSD_SOURCE" ;; SCO_SV) # /bin/sh is not usable ALT_DEF_SHELLS="/bin/lsh /usr/bin/bash /bin/ksh" - CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL" + FORCE_USE_SHELL=1 ;; esac +if test "x$FORCE_USE_SHELL" != x; then + CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL" +fi # Not everyone groks TZ=Europe/Berlin # which is used by the localtime tests echo $ECHO_N "checking whether system has timezone Europe/Berlin... $ECHO_C" >&6 @@ -7076,6 +7092,8 @@ esac + + bm_outfiles="Makefile.config unit-tests/Makefile.config make-bootstrap.sh" if test $use_makefile = yes; then bm_outfiles="makefile $bm_outfiles" @@ -7594,7 +7612,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bmake $as_me 20240212, which was +This file was extended by bmake $as_me 20240314, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -7658,7 +7676,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -bmake config.status 20240212 +bmake config.status 20240314 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/contrib/bmake/configure.in b/contrib/bmake/configure.in index 7979a0c0bb5c..0796e9afdc8d 100644 --- a/contrib/bmake/configure.in +++ b/contrib/bmake/configure.in @@ -1,11 +1,11 @@ dnl dnl RCSid: -dnl $Id: configure.in,v 1.103 2024/02/16 17:54:38 sjg Exp $ +dnl $Id: configure.in,v 1.105 2024/03/19 19:08:20 sjg Exp $ dnl dnl Process this file with autoconf to produce a configure script dnl AC_PREREQ([2.71]) -AC_INIT([bmake],[20240212],[sjg@NetBSD.org]) +AC_INIT([bmake],[20240314],[sjg@NetBSD.org]) AC_CONFIG_HEADERS(config.h) dnl make srcdir absolute @@ -61,10 +61,22 @@ no) ;; *) use_defshell $with_defshell;; esac]) dnl +dnl sometimes uname -s output is not useful +FORCE_MAKE_OS= +make_os= case "$OS" in -CYGWIN*|Darwin|MINGW*) use_makefile=no;; +CYGWIN*) + use_makefile=no + OS=Cygwin + FORCE_MAKE_OS=$OS + ;; +Darwin|MINGW*) use_makefile=no;; *) use_makefile=yes;; esac +if test "x$FORCE_MAKE_OS" != x; then + force_make_os=FORCE_ + make_os=${FORCE_MAKE_OS} +fi AC_ARG_WITH(makefile, [ --without-makefile disable use of generated makefile], [case "${withval}" in @@ -141,9 +153,12 @@ Minix) CPPFLAGS="${CPPFLAGS} -D_NETBSD_SOURCE" ;; SCO_SV) # /bin/sh is not usable ALT_DEF_SHELLS="/bin/lsh /usr/bin/bash /bin/ksh" - CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL" + FORCE_USE_SHELL=1 ;; esac +if test "x$FORCE_USE_SHELL" != x; then + CPPFLAGS="${CPPFLAGS} -DFORCE_USE_SHELL" +fi dnl # Not everyone groks TZ=Europe/Berlin # which is used by the localtime tests @@ -549,6 +564,8 @@ bmake) egrep=egrep;; esac dnl AC_SUBST(egrep) +AC_SUBST(make_os) +AC_SUBST(force_make_os) AC_SUBST(machine) AC_SUBST(force_machine) AC_SUBST(machine_arch) diff --git a/contrib/bmake/for.c b/contrib/bmake/for.c index a995caa6be70..91d9b8e13ce6 100644 --- a/contrib/bmake/for.c +++ b/contrib/bmake/for.c @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.178 2024/01/21 15:02:17 rillig Exp $ */ +/* $NetBSD: for.c,v 1.179 2024/04/01 12:33:27 rillig Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -58,7 +58,7 @@ #include "make.h" /* "@(#)for.c 8.1 (Berkeley) 6/6/93" */ -MAKE_RCSID("$NetBSD: for.c,v 1.178 2024/01/21 15:02:17 rillig Exp $"); +MAKE_RCSID("$NetBSD: for.c,v 1.179 2024/04/01 12:33:27 rillig Exp $"); typedef struct ForLoop { @@ -196,11 +196,7 @@ ForLoop_ParseItems(ForLoop *f, const char *p) cpp_skip_whitespace(&p); items = Var_Subst(p, SCOPE_GLOBAL, VARE_WANTRES); - if (items == var_Error) { - /* TODO: Make this part of the code reachable. */ - Parse_Error(PARSE_FATAL, "Error in .for loop items"); - return false; - } + /* TODO: handle errors */ f->items = Substring_Words(items, false); free(items); @@ -490,12 +486,11 @@ ForLoop_SubstBody(ForLoop *f, unsigned int firstItem, Buffer *body) p += 2; ForLoop_SubstVarLong(f, firstItem, body, &p, endc, &mark); - } else if (p[1] != '\0') { + } else { ForLoop_SubstVarShort(f, firstItem, body, p + 1, &mark); p += 2; - } else - break; + } } Buf_AddRange(body, mark, end); diff --git a/contrib/bmake/job.c b/contrib/bmake/job.c index 4cce19e89f87..6f50c78169b2 100644 --- a/contrib/bmake/job.c +++ b/contrib/bmake/job.c @@ -1,4 +1,4 @@ -/* $NetBSD: job.c,v 1.467 2024/03/10 02:53:37 sjg Exp $ */ +/* $NetBSD: job.c,v 1.470 2024/04/27 20:41:32 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -154,7 +154,7 @@ #include "trace.h" /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: job.c,v 1.467 2024/03/10 02:53:37 sjg Exp $"); +MAKE_RCSID("$NetBSD: job.c,v 1.470 2024/04/27 20:41:32 rillig Exp $"); /* * A shell defines how the commands are run. All commands for a target are @@ -930,7 +930,9 @@ JobWriteCommand(Job *job, ShellWriter *wr, StringListNode *ln, const char *ucmd) run = GNode_ShouldExecute(job->node); + EvalStack_Push(job->node->name, NULL, NULL); xcmd = Var_Subst(ucmd, job->node, VARE_WANTRES); + EvalStack_Pop(); /* TODO: handle errors */ xcmdStart = xcmd; @@ -1057,7 +1059,9 @@ JobSaveCommands(Job *job) * variables such as .TARGET, .IMPSRC. It is not intended to * expand the other variables as well; see deptgt-end.mk. */ + EvalStack_Push(job->node->name, NULL, NULL); expanded_cmd = Var_Subst(cmd, job->node, VARE_WANTRES); + EvalStack_Pop(); /* TODO: handle errors */ Lst_Append(&Targ_GetEndNode()->commands, expanded_cmd); } @@ -1087,6 +1091,7 @@ DebugFailedJob(const Job *job) debug_printf("\n"); debug_printf("*** Failed target: %s\n", job->node->name); + debug_printf("*** In directory: %s\n", curdir); debug_printf("*** Failed commands:\n"); for (ln = job->node->commands.first; ln != NULL; ln = ln->next) { const char *cmd = ln->datum; @@ -1784,7 +1789,7 @@ JobStart(GNode *gn, bool special) * itself. */ static char * -PrintFilteredOutput(char *p, char *endp) /* XXX: should all be const */ +PrintFilteredOutput(char *p, const char *endp) /* XXX: p should be const */ { char *ep; /* XXX: should be const */ diff --git a/contrib/bmake/lst.c b/contrib/bmake/lst.c index 7a7c08200947..ae57ba101845 100644 --- a/contrib/bmake/lst.c +++ b/contrib/bmake/lst.c @@ -1,4 +1,4 @@ -/* $NetBSD: lst.c,v 1.107 2023/12/29 20:43:58 rillig Exp $ */ +/* $NetBSD: lst.c,v 1.108 2024/04/27 17:33:46 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -34,7 +34,7 @@ #include "make.h" -MAKE_RCSID("$NetBSD: lst.c,v 1.107 2023/12/29 20:43:58 rillig Exp $"); +MAKE_RCSID("$NetBSD: lst.c,v 1.108 2024/04/27 17:33:46 rillig Exp $"); static ListNode * LstNodeNew(ListNode *prev, ListNode *next, void *datum) @@ -60,13 +60,13 @@ Lst_Done(List *list) } void -Lst_DoneCall(List *list, LstFreeProc freeProc) +Lst_DoneFree(List *list) { ListNode *ln, *next; for (ln = list->first; ln != NULL; ln = next) { next = ln->next; - freeProc(ln->datum); + free(ln->datum); free(ln); } } diff --git a/contrib/bmake/lst.h b/contrib/bmake/lst.h index 59f8f201192f..7640366d8261 100644 --- a/contrib/bmake/lst.h +++ b/contrib/bmake/lst.h @@ -1,4 +1,4 @@ -/* $NetBSD: lst.h,v 1.104 2023/12/29 20:43:58 rillig Exp $ */ +/* $NetBSD: lst.h,v 1.105 2024/04/27 17:33:46 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -103,13 +103,10 @@ struct List { ListNode *last; }; -/* Free the datum of a node, called before freeing the node itself. */ -typedef void LstFreeProc(void *); - -/* Free the list nodes, but not the list itself. */ +/* Free the list nodes. */ void Lst_Done(List *); -/* Free the list nodes, freeing the node data using the given function. */ -void Lst_DoneCall(List *, LstFreeProc); +/* Free the list nodes, as well as each node's datum. */ +void Lst_DoneFree(List *); #define LST_INIT { NULL, NULL } diff --git a/contrib/bmake/main.c b/contrib/bmake/main.c index 25ec3630e649..ea834bf669ed 100644 --- a/contrib/bmake/main.c +++ b/contrib/bmake/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.612 2024/03/10 02:53:37 sjg Exp $ */ +/* $NetBSD: main.c,v 1.614 2024/04/30 16:13:33 sjg 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.612 2024/03/10 02:53:37 sjg Exp $"); +MAKE_RCSID("$NetBSD: main.c,v 1.614 2024/04/30 16:13:33 sjg Exp $"); #if defined(MAKE_NATIVE) __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " "The Regents of the University of California. " @@ -1174,6 +1174,8 @@ InitDefSysIncPath(char *syspath) else syspath = bmake_strdup(syspath); + /* do NOT search .CURDIR first for .include <makefile> */ + SearchPath_Add(defSysIncPath, ".DOTLAST"); for (start = syspath; *start != '\0'; start = p) { for (p = start; *p != '\0' && *p != ':'; p++) continue; @@ -1217,7 +1219,7 @@ ReadBuiltinRules(void) Fatal("%s: cannot open %s.", progname, (const char *)sysMkFiles.first->datum); - Lst_DoneCall(&sysMkFiles, free); + Lst_DoneFree(&sysMkFiles); } static void @@ -1359,7 +1361,11 @@ main_Init(int argc, char **argv) /* Just in case MAKEOBJDIR wants us to do something tricky. */ Targ_Init(); Var_Init(); +#ifdef FORCE_MAKE_OS + Global_Set_ReadOnly(".MAKE.OS", FORCE_MAKE_OS); +#else Global_Set_ReadOnly(".MAKE.OS", utsname.sysname); +#endif Global_Set("MACHINE", machine); Global_Set("MACHINE_ARCH", machine_arch); #ifdef MAKE_VERSION @@ -1582,9 +1588,9 @@ static void main_CleanUp(void) { #ifdef CLEANUP - Lst_DoneCall(&opts.variables, free); - Lst_DoneCall(&opts.makefiles, free); - Lst_DoneCall(&opts.create, free); + Lst_DoneFree(&opts.variables); + Lst_DoneFree(&opts.makefiles); + Lst_DoneFree(&opts.create); #endif if (DEBUG(GRAPH2)) diff --git a/contrib/bmake/make-bootstrap.sh.in b/contrib/bmake/make-bootstrap.sh.in index e00805cd7ef5..d4f3c0a39c89 100755 --- a/contrib/bmake/make-bootstrap.sh.in +++ b/contrib/bmake/make-bootstrap.sh.in @@ -19,6 +19,7 @@ MAKE_VERSION=@_MAKE_VERSION@ MDEFS="-DMAKE_VERSION=\"$MAKE_VERSION\" \ -D@force_machine@MACHINE=\"@machine@\" \ -D@force_machine_arch@MACHINE_ARCH=\"@machine_arch@\" \ +-D@force_make_os@MAKE_OS=\"@make_os@\" \ -D_PATH_DEFSYSPATH=\"${DEFAULT_SYS_PATH}\"" diff --git a/contrib/bmake/make.h b/contrib/bmake/make.h index 86c198cb55f0..ff85ae4f41db 100644 --- a/contrib/bmake/make.h +++ b/contrib/bmake/make.h @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.329 2024/03/10 02:53:37 sjg Exp $ */ +/* $NetBSD: make.h,v 1.332 2024/04/27 20:41:32 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -141,6 +141,12 @@ #define MAKE_ATTR_USE /* delete */ #endif +#if MAKE_GNUC_PREREQ(8, 0) +#define MAKE_ATTR_NOINLINE __attribute__((__noinline__)) +#else +#define MAKE_ATTR_NOINLINE /* delete */ +#endif + #if __STDC_VERSION__ >= 199901L || defined(lint) #define MAKE_INLINE static inline MAKE_ATTR_UNUSED #else @@ -422,7 +428,7 @@ typedef struct SearchPath { /* * A graph node represents a target that can possibly be made, including its - * relation to other targets and a lot of other details. + * relation to other targets. */ typedef struct GNode { /* The target's name, such as "clean" or "make.c" */ @@ -604,8 +610,8 @@ extern GNode *SCOPE_GLOBAL; extern GNode *SCOPE_CMDLINE; /* - * Value returned by Var_Parse when an error is encountered. It actually - * points to an empty string, so naive callers needn't worry about it. + * Value returned by Var_Parse when an error is encountered. It points to an + * empty string, so naive callers needn't worry about it. */ extern char var_Error[]; @@ -701,11 +707,11 @@ typedef enum PrintVarsMode { /* Command line options */ typedef struct CmdOpts { - /* -B: whether we are make compatible */ + /* -B: whether to be compatible to traditional make */ bool compatMake; /* - * -d: debug control: There is one bit per module. It is up to the + * -d: debug control: There is one flag per module. It is up to the * module what debug information to print. */ DebugFlags debug; @@ -1046,6 +1052,10 @@ void Global_Append(const char *, const char *); void Global_Delete(const char *); void Global_Set_ReadOnly(const char *, const char *); +void EvalStack_Push(const char *, const char *, const char *); +void EvalStack_Pop(void); +const char *EvalStack_Details(void); + /* util.c */ typedef void (*SignalProc)(int); SignalProc bmake_signal(int, SignalProc); diff --git a/contrib/bmake/meta.c b/contrib/bmake/meta.c index b9103a620e49..dea3ed12d965 100644 --- a/contrib/bmake/meta.c +++ b/contrib/bmake/meta.c @@ -1,4 +1,4 @@ -/* $NetBSD: meta.c,v 1.207 2023/12/17 09:02:26 rillig Exp $ */ +/* $NetBSD: meta.c,v 1.208 2024/04/27 17:33:46 rillig Exp $ */ /* * Implement 'meta' mode. @@ -1602,7 +1602,7 @@ meta_oodate(GNode *gn, bool oodate) } } - Lst_DoneCall(&missingFiles, free); + Lst_DoneFree(&missingFiles); if (oodate && needOODATE) { /* diff --git a/contrib/bmake/mk/ChangeLog b/contrib/bmake/mk/ChangeLog index c37feedf4353..ee65ea0fadc1 100644 --- a/contrib/bmake/mk/ChangeLog +++ b/contrib/bmake/mk/ChangeLog @@ -1,3 +1,39 @@ +2024-04-24 Simon J Gerraty <sjg@beast.crufty.net> + + * meta.autodep.mk: do not override start_utc + +2024-04-18 Simon J Gerraty <sjg@beast.crufty.net> + + * sys.dirdeps.mk: set defaults for DEP_* at level 0 too. + These help when first include of Makefile.depend happens in a leaf + dir. + + * install-mk (MK_VERSION): 20240414 + +2024-04-09 Simon J Gerraty <sjg@beast.crufty.net> + + * install-mk (MK_VERSION): 20240408 + + * init.mk: allow for _ as well as . to join V + and Q from QUALIFIED_VAR_LIST and VAR_QUALIFIER_LIST. + + * progs.mk: avoid overlap between PROG_VARS and + init.mk's QUALIFIED_VAR_LIST since PROG would also + match its VAR_QUALIFIER_LIST, + libs.mk does not have the same issue. + + * subdir.mk: _SUBDIRUSE for realinstall should run install + remove include of ${.CURDIR}/Makefile.inc that can be done via + local.subdir.mk where needed + + * own.mk: do not conflict with man.mk + +2024-03-19 Simon J Gerraty <sjg@beast.crufty.net> + + * install-mk (MK_VERSION): 20240314 + + * add sys/Cygwin.mk from Christian Franke + 2024-03-09 Simon J Gerraty <sjg@beast.crufty.net> * install-mk (MK_VERSION): 20240309 diff --git a/contrib/bmake/mk/FILES b/contrib/bmake/mk/FILES index efe9691ffe58..39ac101d36f4 100644 --- a/contrib/bmake/mk/FILES +++ b/contrib/bmake/mk/FILES @@ -54,6 +54,7 @@ sys.dependfile.mk sys.dirdeps.mk sys.vars.mk sys/AIX.mk +sys/Cygwin.mk sys/Darwin.mk sys/Generic.mk sys/HP-UX.mk diff --git a/contrib/bmake/mk/init.mk b/contrib/bmake/mk/init.mk index 86dc577371cb..b6619721c943 100644 --- a/contrib/bmake/mk/init.mk +++ b/contrib/bmake/mk/init.mk @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# $Id: init.mk,v 1.37 2024/02/25 19:12:13 sjg Exp $ +# $Id: init.mk,v 1.38 2024/04/09 17:18:24 sjg Exp $ # # @(#) Copyright (c) 2002-2024, Simon J. Gerraty # @@ -72,7 +72,7 @@ QUALIFIED_VAR_LIST += \ # a final :U avoids errors if someone uses := .for V in ${QUALIFIED_VAR_LIST:O:u:@q@$q $q_LAST@} .for Q in ${VAR_QUALIFIER_LIST:u} -$V += ${$V.$Q:U} ${$V.$Q.${COMPILER_TYPE}:U} +$V += ${$V_$Q:U${$V.$Q:U}} ${V_$Q_${COMPILER_TYPE}:U${$V.$Q.${COMPILER_TYPE}:U}} .endfor .endfor diff --git a/contrib/bmake/mk/install-mk b/contrib/bmake/mk/install-mk index c9941bb4247e..97874ac49016 100755 --- a/contrib/bmake/mk/install-mk +++ b/contrib/bmake/mk/install-mk @@ -59,9 +59,9 @@ # Simon J. Gerraty <sjg@crufty.net> # RCSid: -# $Id: install-mk,v 1.250 2024/03/10 02:57:17 sjg Exp $ +# $Id: install-mk,v 1.253 2024/04/18 17:18:31 sjg Exp $ # -# @(#) Copyright (c) 1994-2023 Simon J. Gerraty +# @(#) Copyright (c) 1994-2024 Simon J. Gerraty # # This file is provided in the hope that it will # be of use. There is absolutely NO WARRANTY. @@ -74,7 +74,7 @@ # sjg@crufty.net # -MK_VERSION=20240309 +MK_VERSION=20240414 OWNER= GROUP= MODE=444 diff --git a/contrib/bmake/mk/meta.autodep.mk b/contrib/bmake/mk/meta.autodep.mk index 9824570ecc43..55f2d66e56aa 100644 --- a/contrib/bmake/mk/meta.autodep.mk +++ b/contrib/bmake/mk/meta.autodep.mk @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# $Id: meta.autodep.mk,v 1.62 2024/02/17 17:26:57 sjg Exp $ +# $Id: meta.autodep.mk,v 1.63 2024/04/24 18:56:41 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -308,7 +308,9 @@ CLEANFILES += *.meta filemon.* *.db # these make it easy to gather some stats now_utc ?= ${%s:L:localtime} +.if !defined(start_utc) start_utc := ${now_utc} +.endif meta_stats= meta=${empty(.MAKE.META.FILES):?0:${.MAKE.META.FILES:[#]}} \ created=${empty(.MAKE.META.CREATED):?0:${.MAKE.META.CREATED:[#]}} diff --git a/contrib/bmake/mk/meta.subdir.mk b/contrib/bmake/mk/meta.subdir.mk index e2ece24515a4..aee8a1a9a39b 100644 --- a/contrib/bmake/mk/meta.subdir.mk +++ b/contrib/bmake/mk/meta.subdir.mk @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# $Id: meta.subdir.mk,v 1.14 2024/02/17 17:26:57 sjg Exp $ +# $Id: meta.subdir.mk,v 1.15 2024/04/19 15:10:22 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -70,7 +70,6 @@ DIRDEPS := ${DIRDEPS:S,^./,,:S,/./,/,g:${SUBDIRDEPS_FILTER:Uu}} # dirdeps.mk will compute some interesting combinations. .undef ALL_MACHINES -DEP_RELDIR = ${RELDIR} .include <dirdeps.mk> .endif .endif diff --git a/contrib/bmake/mk/own.mk b/contrib/bmake/mk/own.mk index efadd3469a8d..72b2f70d4bbe 100644 --- a/contrib/bmake/mk/own.mk +++ b/contrib/bmake/mk/own.mk @@ -1,4 +1,4 @@ -# $Id: own.mk,v 1.47 2024/02/19 00:06:19 sjg Exp $ +# $Id: own.mk,v 1.48 2024/04/09 21:52:52 sjg Exp $ # should be set properly in sys.mk _this ?= ${.PARSEFILE:S,bsd.,,} @@ -136,8 +136,7 @@ INCDIR?= ${INCLUDEDIR} # Define MANZ to have the man pages compressed (gzip) #MANZ= 1 -MANTARGET?= cat -MANDIR?= ${prefix}/share/man/${MANTARGET} +MANDIR?= ${prefix}/share/man MANGRP?= ${BINGRP} MANOWN?= ${BINOWN} MANMODE?= ${NONBINMODE} diff --git a/contrib/bmake/mk/progs.mk b/contrib/bmake/mk/progs.mk index 815449f331b5..ada942db8621 100644 --- a/contrib/bmake/mk/progs.mk +++ b/contrib/bmake/mk/progs.mk @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# $Id: progs.mk,v 1.17 2024/02/17 17:26:57 sjg Exp $ +# $Id: progs.mk,v 1.18 2024/04/09 17:18:24 sjg Exp $ # # @(#) Copyright (c) 2006, Simon J. Gerraty # @@ -39,16 +39,26 @@ PROG ?= $t # just one of many PROG_VARS += \ BINDIR \ - CFLAGS \ - COPTS \ - CPPFLAGS \ CXXFLAGS \ DPADD \ DPLIBS \ LDADD \ - LDFLAGS \ MAN \ - SRCS + +.ifndef SYS_OS_MK +# assume we are not using init.mk, otherwise +# we need to avoid overlap with its +# QUALIFIED_VAR_LIST which includes these and its +# VAR_QUALIFIER_LIST includes .TARGET which +# would match PROG +PROG_VARS += \ + CFLAGS \ + COPTS \ + CPPFLAGS \ + LDFLAGS \ + SRCS \ + +.endif .for v in ${PROG_VARS:O:u} .if defined(${v}.${PROG}) || defined(${v}_${PROG}) diff --git a/contrib/bmake/mk/subdir.mk b/contrib/bmake/mk/subdir.mk index 4ae21065c865..0feb63af44d2 100644 --- a/contrib/bmake/mk/subdir.mk +++ b/contrib/bmake/mk/subdir.mk @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# $Id: subdir.mk,v 1.22 2024/02/19 00:06:19 sjg Exp $ +# $Id: subdir.mk,v 1.24 2024/04/10 01:47:23 sjg Exp $ # # @(#) Copyright (c) 2002-2024, Simon J. Gerraty # @@ -37,7 +37,6 @@ __${_this}__: .NOTMAIN _SUBDIRUSE: .elif !commands(_SUBDIRUSE) && !defined(NO_SUBDIR) && !defined(NOSUBDIR) .-include <local.subdir.mk> -.-include <${.CURDIR}/Makefile.inc> .if !target(.MAIN) .MAIN: all .endif @@ -82,7 +81,7 @@ realinstall: beforeinstall _SUBDIRUSE # the interface from others # this may require additions to SUBDIR_TAREGTS -_SUBDIRUSE: .USE subdir-${.TARGET} +_SUBDIRUSE: .USE subdir-${.TARGET:C/-.*//:S/real//:S/.depend/depend/} SUBDIR_TARGETS += \ all \ @@ -93,7 +92,6 @@ SUBDIR_TARGETS += \ depend \ lint \ obj \ - realinstall \ tags \ etags diff --git a/contrib/bmake/mk/sys.dirdeps.mk b/contrib/bmake/mk/sys.dirdeps.mk index 1e3363c22339..4d2dfa8416fa 100644 --- a/contrib/bmake/mk/sys.dirdeps.mk +++ b/contrib/bmake/mk/sys.dirdeps.mk @@ -1,6 +1,6 @@ # SPDX-License-Identifier: BSD-2-Clause # -# $Id: sys.dirdeps.mk,v 1.14 2024/02/25 19:12:13 sjg Exp $ +# $Id: sys.dirdeps.mk,v 1.15 2024/04/18 17:18:31 sjg Exp $ # # @(#) Copyright (c) 2012-2023, Simon J. Gerraty # @@ -196,11 +196,10 @@ RELSRCTOP?= ${RELTOP} # just in case .MAKE.DEPENDFILE ?= Makefile.depend -.if ${.MAKE.LEVEL} > 0 -# Makefile.depend* also get read at level 1+ -# and often refer to DEP_MACHINE etc, -# so ensure DEP_* (for TARGET_SPEC_VARS anyway) are set -.for V in ${TARGET_SPEC_VARS} -DEP_$V = ${$V} +# Makefile.depend* often refer to DEP_MACHINE etc, +# we need defaults for both first include in a leaf dir +# and when level > 0 +# so ensure DEP_* for TARGET_SPEC_VARS and RELDIR are set +.for V in ${TARGET_SPEC_VARS} RELDIR +DEP_$V ?= ${$V} .endfor -.endif diff --git a/contrib/bmake/mk/sys/Cygwin.mk b/contrib/bmake/mk/sys/Cygwin.mk new file mode 100644 index 000000000000..ffc479ad9ef3 --- /dev/null +++ b/contrib/bmake/mk/sys/Cygwin.mk @@ -0,0 +1,21 @@ +# Minimal adjustments for Cygwin +# SPDX-License-Identifier: BSD-2-Clause + +OS ?= Cygwin +unix ?= We run ${OS}. + +.ifndef ROOT_GROUP +# Cygwin maps local admin SID S-1-5-32-544 to GID 544. +# /etc/group does no longer exist in a base installation. +ROOT_GROUP != /usr/bin/getent group 544 2>/dev/null +ROOT_GROUP := ${ROOT_GROUP:C,:.*$,,} +.endif + +.LIBS: .a + +AR ?= ar +RANLIB ?= ranlib +TSORT ?= tsort -q + +# egrep is deprecated +EGREP ?= grep -E diff --git a/contrib/bmake/os.sh b/contrib/bmake/os.sh index 78b2de95a679..648ea1d5993c 100755 --- a/contrib/bmake/os.sh +++ b/contrib/bmake/os.sh @@ -17,7 +17,7 @@ # Simon J. Gerraty <sjg@crufty.net> # RCSid: -# $Id: os.sh,v 1.63 2023/05/22 20:44:47 sjg Exp $ +# $Id: os.sh,v 1.64 2024/03/19 16:03:23 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -91,6 +91,10 @@ AIX) # everyone loves to be different... PS_AXC=-e SHARE_ARCH=$OS/$OSMAJOR.X ;; +CYGWIN*) # uname -s not very useful + # uname -o produces just Cygwin which is better + OS=Cygwin + ;; Darwin) # this is more explicit (arm64 vs arm) HOST_ARCH=$MACHINE ;; diff --git a/contrib/bmake/parse.c b/contrib/bmake/parse.c index d6d1c9ba9874..54f29ba5ff13 100644 --- a/contrib/bmake/parse.c +++ b/contrib/bmake/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.717 2024/02/07 06:43:02 rillig Exp $ */ +/* $NetBSD: parse.c,v 1.722 2024/04/27 17:33:46 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -121,7 +121,7 @@ #include "pathnames.h" /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: parse.c,v 1.717 2024/02/07 06:43:02 rillig Exp $"); +MAKE_RCSID("$NetBSD: parse.c,v 1.722 2024/04/27 17:33:46 rillig Exp $"); /* Detects a multiple-inclusion guard in a makefile. */ typedef enum { @@ -537,6 +537,7 @@ ParseVErrorInternal(FILE *f, bool useVars, const GNode *gn, (void)fprintf(f, "%s: ", progname); PrintLocation(f, useVars, gn); + fprintf(f, "%s", EvalStack_Details()); if (level == PARSE_WARNING) (void)fprintf(f, "warning: "); (void)vfprintf(f, fmt, ap); @@ -1637,10 +1638,10 @@ ParseDependencySources(char *p, GNodeType targetAttr, * Transformation rules such as '.c.o' are also handled here, see * Suff_AddTransform. * - * Upon return, the value of the line is unspecified. + * Upon return, the value of expandedLine is unspecified. */ static void -ParseDependency(char *line, const char *unexpanded_line) +ParseDependency(char *expandedLine, const char *unexpandedLine) { char *p; SearchPathList *paths; /* search paths to alter when parsing a list @@ -1651,14 +1652,14 @@ ParseDependency(char *line, const char *unexpanded_line) * vice versa */ GNodeType op; - DEBUG1(PARSE, "ParseDependency(%s)\n", line); - p = line; + DEBUG1(PARSE, "ParseDependency(%s)\n", expandedLine); + p = expandedLine; paths = NULL; targetAttr = OP_NONE; special = SP_NOT; - if (!ParseDependencyTargets(&p, line, &special, &targetAttr, &paths, - unexpanded_line)) + if (!ParseDependencyTargets(&p, expandedLine, &special, &targetAttr, + &paths, unexpandedLine)) goto out; if (!Lst_IsEmpty(targets)) @@ -1666,7 +1667,7 @@ ParseDependency(char *line, const char *unexpanded_line) op = ParseDependencyOp(&p); if (op == OP_NONE) { - InvalidLineType(line, unexpanded_line); + InvalidLineType(expandedLine, unexpandedLine); goto out; } ApplyDependencyOperator(op); @@ -2384,7 +2385,7 @@ ParseRawLine(IncludedFile *curFile, char **out_line, char **out_line_end, ch = *p; if (ch == '\0' || (ch == '\\' && p[1] == '\0')) { Parse_Error(PARSE_FATAL, "Zero byte read from file"); - return PRLR_ERROR; + exit(2); } /* Treat next character after '\' as literal. */ @@ -2623,6 +2624,7 @@ ReadHighLevelLine(void) if (line == NULL) return NULL; + DEBUG2(PARSE, "Parsing line %u: %s\n", curFile->lineno, line); if (curFile->guardState != GS_NO && ((curFile->guardState == GS_START && line[0] != '.') || curFile->guardState == GS_DONE)) @@ -2945,8 +2947,6 @@ Parse_File(const char *name, int fd) do { while ((line = ReadHighLevelLine()) != NULL) { - DEBUG2(PARSE, "Parsing line %u: %s\n", - CurFile()->lineno, line); ParseLine(line); } } while (ParseEOF()); @@ -2982,7 +2982,7 @@ Parse_End(void) #ifdef CLEANUP HashIter hi; - Lst_DoneCall(&targCmds, free); + Lst_DoneFree(&targCmds); assert(targets == NULL); SearchPath_Free(defSysIncPath); SearchPath_Free(sysIncPath); diff --git a/contrib/bmake/str.c b/contrib/bmake/str.c index 1349831af2f1..1153d0f029fc 100644 --- a/contrib/bmake/str.c +++ b/contrib/bmake/str.c @@ -1,4 +1,4 @@ -/* $NetBSD: str.c,v 1.102 2024/01/05 23:22:06 rillig Exp $ */ +/* $NetBSD: str.c,v 1.103 2024/04/14 15:21:20 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -71,7 +71,7 @@ #include "make.h" /* "@(#)str.c 5.8 (Berkeley) 6/1/90" */ -MAKE_RCSID("$NetBSD: str.c,v 1.102 2024/01/05 23:22:06 rillig Exp $"); +MAKE_RCSID("$NetBSD: str.c,v 1.103 2024/04/14 15:21:20 rillig Exp $"); static HashTable interned_strings; @@ -297,26 +297,6 @@ Str_Words(const char *str, bool expand) } /* - * XXX: In the extreme edge case that one of the characters is from the basic - * execution character set and the other isn't, the result of the comparison - * differs depending on whether plain char is signed or unsigned. - * - * An example is the character range from \xE4 to 'a', where \xE4 may come - * from U+00E4 'Latin small letter A with diaeresis'. - * - * If char is signed, \xE4 evaluates to -28, the first half of the condition - * becomes -28 <= '0' && '0' <= 'a', which evaluates to true. - * - * If char is unsigned, \xE4 evaluates to 228, the second half of the - * condition becomes 'a' <= '0' && '0' <= 228, which evaluates to false. - */ -static bool -in_range(char e1, char c, char e2) -{ - return (e1 <= c && c <= e2) || (e2 <= c && c <= e1); -} - -/* * Test if a string matches a pattern like "*.[ch]". The pattern matching * characters are '*', '?' and '[]', as in fnmatch(3). * @@ -360,7 +340,11 @@ match_fixed_length: return res; } if (pat[1] == '-') { - if (in_range(pat[0], *str, pat[2])) + unsigned char e1 = (unsigned char)pat[0]; + unsigned char c = (unsigned char)*str; + unsigned char e2 = (unsigned char)pat[2]; + if ((e1 <= c && c <= e2) + || (e2 <= c && c <= e1)) goto end_of_char_list; pat += 2; } diff --git a/contrib/bmake/targ.c b/contrib/bmake/targ.c index 14c7faba1f2b..35745cd21fe0 100644 --- a/contrib/bmake/targ.c +++ b/contrib/bmake/targ.c @@ -1,4 +1,4 @@ -/* $NetBSD: targ.c,v 1.180 2024/03/10 02:53:37 sjg Exp $ */ +/* $NetBSD: targ.c,v 1.181 2024/04/27 17:33:47 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -107,7 +107,7 @@ #include "dir.h" /* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: targ.c,v 1.180 2024/03/10 02:53:37 sjg Exp $"); +MAKE_RCSID("$NetBSD: targ.c,v 1.181 2024/04/27 17:33:47 rillig Exp $"); /* * All target nodes that appeared on the left-hand side of one of the @@ -119,7 +119,7 @@ static HashTable allTargetsByName; #ifdef CLEANUP static GNodeList allNodes = LST_INIT; -static void GNode_Free(void *); +static void GNode_Free(GNode *); #endif void @@ -131,11 +131,16 @@ Targ_Init(void) void Targ_End(void) { +#ifdef CLEANUP + GNodeListNode *ln; +#endif Targ_Stats(); #ifdef CLEANUP Lst_Done(&allTargets); HashTable_Done(&allTargetsByName); - Lst_DoneCall(&allNodes, GNode_Free); + for (ln = allNodes.first; ln != NULL; ln = ln->next) + GNode_Free(ln->datum); + Lst_Done(&allNodes); #endif } @@ -212,10 +217,8 @@ GNode_New(const char *name) #ifdef CLEANUP static void -GNode_Free(void *gnp) +GNode_Free(GNode *gn) { - GNode *gn = gnp; - free(gn->name); free(gn->uname); free(gn->path); diff --git a/contrib/bmake/unit-tests/Makefile b/contrib/bmake/unit-tests/Makefile index 6c41bf811dcf..5960a0621ddd 100644 --- a/contrib/bmake/unit-tests/Makefile +++ b/contrib/bmake/unit-tests/Makefile @@ -1,6 +1,6 @@ -# $Id: Makefile,v 1.211 2024/03/10 17:46:44 sjg Exp $ +# $Id: Makefile,v 1.216 2024/04/30 16:42:50 sjg Exp $ # -# $NetBSD: Makefile,v 1.342 2024/01/07 02:07:44 sjg Exp $ +# $NetBSD: Makefile,v 1.344 2024/04/30 16:41:32 sjg Exp $ # # Unit tests for make(1) # @@ -474,20 +474,11 @@ BROKEN_TESTS+= sh-flags BROKEN_TESTS+= varmod-localtime .endif -.if ${.MAKE.OS:NCYGWIN*} == "" -BROKEN_TESTS+= \ - export \ - opt-chdir \ - opt-keep-going-indirect \ - -.endif - - .if ${.MAKE.OS:NDarwin} == "" BROKEN_TESTS+= shell-ksh .endif -.if ${.MAKE.OS:MIRIX*} != "" +.if ${.MAKE.OS:NIRIX*} == "" BROKEN_TESTS+= \ cmd-interrupt \ deptgt-interrupt \ @@ -573,6 +564,9 @@ SED_CMDS.directive-include-guard= \ -e '/^ParseDependency/d' \ -e '/^ParseEOF:/d' SED_CMDS.export= -e '/^[^=_A-Za-z0-9]*=/d' +.if ${.MAKE.OS:NCygwin} == "" +SED_CMDS.export+= -e '/^WINDIR=/d' -e '/^SYSTEMROOT=/d' +.endif SED_CMDS.export-all= ${SED_CMDS.export} SED_CMDS.export-env= ${SED_CMDS.export} SED_CMDS.cmdline= -e 's,uid${.MAKE.UID}/,,' @@ -625,7 +619,7 @@ SED_CMDS.var-op-shell+= ${STD_SED_CMDS.shell} SED_CMDS.var-op-shell+= -e '/command/s,No such.*,not found,' SED_CMDS.var-op-shell+= ${STD_SED_CMDS.white-space} SED_CMDS.vardebug+= -e 's,${.SHELL},</path/to/shell>,' -SED_CMDS.varmod-mtime+= -e "s,': .*,': <ENOENT>," +SED_CMDS.varmod-mtime+= -e "s,\(.*\)': .*,\1': <ENOENT>," SED_CMDS.varmod-subst-regex+= ${STD_SED_CMDS.regex} SED_CMDS.varparse-errors+= ${STD_SED_CMDS.timestamp} SED_CMDS.varname-dot-make-meta-ignore_filter+= ${SED_CMDS.meta-ignore} @@ -655,8 +649,9 @@ unexport-env.rawout: export.mk # In tests that use the debugging option -dd, ignore debugging output that is # only logged in -DCLEANUP mode. -STD_SED_CMDS.dd= -e '/^OpenDirs_Done:/d' -STD_SED_CMDS.dd+= -e '/^CachedDir /d' +STD_SED_CMDS.dd= -e '/^OpenDirs_Done:/d' +STD_SED_CMDS.dd+= -e '/^CachedDir /d' +STD_SED_CMDS.dd+= -e 's, ${DEFSYSPATH:U/usr/share/mk} , <defsyspath> ,' # Omit details such as process IDs from the output of the -dg1 option. STD_SED_CMDS.dg1= -e '/\#.* \.$$/d' @@ -762,12 +757,10 @@ TOOL_TR?= tr TOOL_DIFF?= diff DIFF_FLAGS?= -u -.if defined(.PARSEDIR) # ensure consistent results from sort(1) LC_ALL= C LANG= C .export LANG LC_ALL -.endif .if ${.MAKE.MODE:Unormal:Mmeta} != "" # we don't need the noise diff --git a/contrib/bmake/unit-tests/archive.exp b/contrib/bmake/unit-tests/archive.exp index 645add4f5899..5cf847388544 100644 --- a/contrib/bmake/unit-tests/archive.exp +++ b/contrib/bmake/unit-tests/archive.exp @@ -25,4 +25,12 @@ depend-on-existing-member Making remove-archive rm -f libprog.a +begin library +Examining libbad.a...up-to-date. +Examining -lbad...up-to-date. +Examining libgood.a...library...up-to-date. +Examining -lgood...library...up-to-date. +Examining library...nonexistent....PHONY node...out-of-date. +Examining .END...nonexistent...nonexistent and no sources...out-of-date. +end library exit status 0 diff --git a/contrib/bmake/unit-tests/archive.mk b/contrib/bmake/unit-tests/archive.mk index 2cd43a99e9ad..eef64396f419 100644 --- a/contrib/bmake/unit-tests/archive.mk +++ b/contrib/bmake/unit-tests/archive.mk @@ -1,4 +1,4 @@ -# $NetBSD: archive.mk,v 1.12 2021/04/09 14:42:00 christos Exp $ +# $NetBSD: archive.mk,v 1.13 2024/04/27 20:23:22 rillig Exp $ # # Very basic demonstration of handling archives, based on the description # in PSD.doc/tutorial.ms. @@ -24,6 +24,12 @@ all: @${MAKE} -f ${MAKEFILE} depend-on-existing-member @${MAKE} -f ${MAKEFILE} depend-on-nonexistent-member @${MAKE} -f ${MAKEFILE} remove-archive + @${MAKE} -f ${MAKEFILE} set-up-library + @${MAKE} -f ${MAKEFILE} -dm library 2>&1 \ + | sed -n '/^Examining/p' \ + | sed 's,\.\.\.modified[^.]*,,' + @${MAKE} -f ${MAKEFILE} tear-down-library + create-archive: ${ARCHIVE} pre post @@ -58,3 +64,28 @@ pre: .USEBEFORE @echo Making ${.TARGET} ${.OODATE:C,.+,out-of-date,W} ${.OODATE:O} post: .USE @echo + + +set-up-library: .PHONY + @echo "member" > member.txt + @echo "not a library" > libbad.a + @ar cr libgood.a member.txt + @echo "begin library" + +.if make(library) +.SUFFIXES: .a +.LIBS: .a +.endif +# The two lines for libgood contain the word "library", the two lines for +# libbad don't. +# +# expect: Examining libbad.a...up-to-date. +# expect: Examining -lbad...up-to-date. +# expect: Examining libgood.a...library...up-to-date. +# expect: Examining -lgood...library...up-to-date. +library: .PHONY libbad.a -lbad libgood.a -lgood + : Making ${.TARGET} from ${.ALLSRC} + +tear-down-library: .PHONY + @echo "end library" + @rm member.txt libbad.a libgood.a diff --git a/contrib/bmake/unit-tests/cmd-errors-jobs.exp b/contrib/bmake/unit-tests/cmd-errors-jobs.exp index d0a6e51eb84d..c8e483a9609b 100644 --- a/contrib/bmake/unit-tests/cmd-errors-jobs.exp +++ b/contrib/bmake/unit-tests/cmd-errors-jobs.exp @@ -1,9 +1,9 @@ : undefined--eol -make: Unclosed variable "UNCLOSED" -: unclosed-variable- +make: in target "unclosed-expression": Unclosed variable "UNCLOSED" +: unclosed-expression- make: Unclosed expression, expecting '}' for "UNCLOSED" : unclosed-modifier- -make: Unknown modifier "Z" +make: in target "unknown-modifier": while evaluating variable "UNKNOWN": Unknown modifier "Z" : unknown-modifier--eol : end-eol exit status 0 diff --git a/contrib/bmake/unit-tests/cmd-errors-jobs.mk b/contrib/bmake/unit-tests/cmd-errors-jobs.mk index b3dc982de35f..7a82c0b416e8 100644 --- a/contrib/bmake/unit-tests/cmd-errors-jobs.mk +++ b/contrib/bmake/unit-tests/cmd-errors-jobs.mk @@ -1,32 +1,39 @@ -# $NetBSD: cmd-errors-jobs.mk,v 1.2 2022/09/25 12:51:37 rillig Exp $ +# $NetBSD: cmd-errors-jobs.mk,v 1.4 2024/04/23 22:51:28 rillig Exp $ # -# Demonstrate how errors in variable expansions affect whether the commands +# Demonstrate how errors in expressions affect whether the commands # are actually executed in jobs mode. .MAKEFLAGS: -j1 -all: undefined unclosed-variable unclosed-modifier unknown-modifier end +all: undefined unclosed-expression unclosed-modifier unknown-modifier end -# Undefined variables are not an error. They expand to empty strings. +# Undefined variables in expressions are not an error. They expand to empty +# strings. +# expect: : undefined--eol undefined: : $@-${UNDEFINED}-eol -# XXX: As of 2020-11-01, this command is executed even though it contains -# parse errors. -unclosed-variable: +# XXX: This command is executed even though it contains parse errors. +# expect: make: in target "unclosed-expression": Unclosed variable "UNCLOSED" +# expect: : unclosed-expression- +unclosed-expression: : $@-${UNCLOSED -# XXX: As of 2020-11-01, this command is executed even though it contains -# parse errors. +# XXX: This command is executed even though it contains parse errors. +# expect: make: Unclosed expression, expecting '}' for "UNCLOSED" +# expect: : unclosed-modifier- unclosed-modifier: : $@-${UNCLOSED: -# XXX: As of 2020-11-01, this command is executed even though it contains -# parse errors. +# XXX: This command is executed even though it contains parse errors. +# expect: make: in target "unknown-modifier": while evaluating variable "UNKNOWN": Unknown modifier "Z" +# expect: : unknown-modifier--eol unknown-modifier: : $@-${UNKNOWN:Z}-eol +# expect: : end-eol end: : $@-eol -# XXX: As of 2020-11-02, despite the parse errors, the exit status is 0. +# XXX: Despite the parse errors, the exit status is 0. +# expect: exit status 0 diff --git a/contrib/bmake/unit-tests/cmd-errors-lint.exp b/contrib/bmake/unit-tests/cmd-errors-lint.exp index bdf4ae1a17e8..d489c6be57c9 100644 --- a/contrib/bmake/unit-tests/cmd-errors-lint.exp +++ b/contrib/bmake/unit-tests/cmd-errors-lint.exp @@ -1,9 +1,9 @@ : undefined -make: Unclosed variable "UNCLOSED" -: unclosed-variable +make: in target "unclosed-expression": Unclosed variable "UNCLOSED" +: unclosed-expression make: Unclosed expression, expecting '}' for "UNCLOSED" : unclosed-modifier -make: Unknown modifier "Z" +make: in target "unknown-modifier": while evaluating variable "UNKNOWN": Unknown modifier "Z" : unknown-modifier : end exit status 2 diff --git a/contrib/bmake/unit-tests/cmd-errors-lint.mk b/contrib/bmake/unit-tests/cmd-errors-lint.mk index 371e12af0f4f..2e7d537f5f1f 100644 --- a/contrib/bmake/unit-tests/cmd-errors-lint.mk +++ b/contrib/bmake/unit-tests/cmd-errors-lint.mk @@ -1,20 +1,21 @@ -# $NetBSD: cmd-errors-lint.mk,v 1.1 2020/11/02 20:43:27 rillig Exp $ +# $NetBSD: cmd-errors-lint.mk,v 1.2 2024/04/23 22:51:28 rillig Exp $ # -# Demonstrate how errors in variable expansions affect whether the commands +# Demonstrate how errors in expressions affect whether the commands # are actually executed. .MAKEFLAGS: -dL -all: undefined unclosed-variable unclosed-modifier unknown-modifier end +all: undefined unclosed-expression unclosed-modifier unknown-modifier end -# Undefined variables are not an error. They expand to empty strings. +# Undefined variables in expressions are not an error. They expand to empty +# strings. undefined: : $@ ${UNDEFINED} # XXX: As of 2020-11-01, this obvious syntax error is not detected. # XXX: As of 2020-11-01, this command is executed even though it contains # parse errors. -unclosed-variable: +unclosed-expression: : $@ ${UNCLOSED # XXX: As of 2020-11-01, this obvious syntax error is not detected. diff --git a/contrib/bmake/unit-tests/cmd-errors.exp b/contrib/bmake/unit-tests/cmd-errors.exp index d0a6e51eb84d..c8e483a9609b 100644 --- a/contrib/bmake/unit-tests/cmd-errors.exp +++ b/contrib/bmake/unit-tests/cmd-errors.exp @@ -1,9 +1,9 @@ : undefined--eol -make: Unclosed variable "UNCLOSED" -: unclosed-variable- +make: in target "unclosed-expression": Unclosed variable "UNCLOSED" +: unclosed-expression- make: Unclosed expression, expecting '}' for "UNCLOSED" : unclosed-modifier- -make: Unknown modifier "Z" +make: in target "unknown-modifier": while evaluating variable "UNKNOWN": Unknown modifier "Z" : unknown-modifier--eol : end-eol exit status 0 diff --git a/contrib/bmake/unit-tests/cmd-errors.mk b/contrib/bmake/unit-tests/cmd-errors.mk index 6d3880684bcf..d1125d444fcd 100644 --- a/contrib/bmake/unit-tests/cmd-errors.mk +++ b/contrib/bmake/unit-tests/cmd-errors.mk @@ -1,17 +1,18 @@ -# $NetBSD: cmd-errors.mk,v 1.5 2022/09/25 12:51:37 rillig Exp $ +# $NetBSD: cmd-errors.mk,v 1.6 2024/04/23 22:51:28 rillig Exp $ # -# Demonstrate how errors in variable expansions affect whether the commands +# Demonstrate how errors in expressions affect whether the commands # are actually executed in compat mode. -all: undefined unclosed-variable unclosed-modifier unknown-modifier end +all: undefined unclosed-expression unclosed-modifier unknown-modifier end -# Undefined variables are not an error. They expand to empty strings. +# Undefined variables in expressions are not an error. They expand to empty +# strings. undefined: : $@-${UNDEFINED}-eol # XXX: As of 2020-11-01, this command is executed even though it contains # parse errors. -unclosed-variable: +unclosed-expression: : $@-${UNCLOSED # XXX: As of 2020-11-01, this command is executed even though it contains diff --git a/contrib/bmake/unit-tests/cmdline-undefined.mk b/contrib/bmake/unit-tests/cmdline-undefined.mk index 81b44518dd41..e7c0400ad1e1 100644 --- a/contrib/bmake/unit-tests/cmdline-undefined.mk +++ b/contrib/bmake/unit-tests/cmdline-undefined.mk @@ -1,6 +1,6 @@ -# $NetBSD: cmdline-undefined.mk,v 1.4 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: cmdline-undefined.mk,v 1.5 2024/04/23 22:51:28 rillig Exp $ # -# Tests for undefined expressions in the command line. +# Tests for undefined variables in expressions in the command line. all: # When the command line is parsed, variable assignments using the diff --git a/contrib/bmake/unit-tests/cmdline.mk b/contrib/bmake/unit-tests/cmdline.mk index a24d46208e52..40a0d7ccddbb 100644 --- a/contrib/bmake/unit-tests/cmdline.mk +++ b/contrib/bmake/unit-tests/cmdline.mk @@ -1,4 +1,4 @@ -# $NetBSD: cmdline.mk,v 1.4 2022/06/10 18:58:07 rillig Exp $ +# $NetBSD: cmdline.mk,v 1.5 2024/04/23 22:51:28 rillig Exp $ # # Tests for command line parsing and related special variables. @@ -24,7 +24,7 @@ makeobjdir-direct: @${MAKE_CMD} MAKEOBJDIR=${DIR2} show-objdir # The .OBJDIR can be set via the MAKEOBJDIR command line variable, -# and that variable could even contain the usual modifiers. +# and expressions based on that variable can contain the usual modifiers. # Since the .OBJDIR=MAKEOBJDIR assignment happens very early, # the SUB2 variable in the modifier is not defined yet and is therefore empty. # The SUB1 in the resulting path comes from the environment variable TMPBASE, diff --git a/contrib/bmake/unit-tests/comment.mk b/contrib/bmake/unit-tests/comment.mk index a3bf781b9a67..fea0f0b3d817 100644 --- a/contrib/bmake/unit-tests/comment.mk +++ b/contrib/bmake/unit-tests/comment.mk @@ -1,4 +1,4 @@ -# $NetBSD: comment.mk,v 1.6 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: comment.mk,v 1.7 2024/04/23 22:51:28 rillig Exp $ # # Demonstrate how comments are written in makefiles. @@ -53,9 +53,9 @@ VAR= \# # Both in the assignment. . error .endif -# Since 2012-03-24 the variable modifier :[#] does not need to be escaped. -# To keep the parsing code simple, any "[#" does not start a comment, even -# outside of an expression. +# Since 2012-03-24 the modifier :[#] does not need to be escaped. +# To keep the parsing code simple, the "#" in "[#" does not start a comment, +# regardless of the syntactical context it appears in. WORDS= ${VAR:[#]} [# .if ${WORDS} != "1 [#" . error diff --git a/contrib/bmake/unit-tests/cond-cmp-string.mk b/contrib/bmake/unit-tests/cond-cmp-string.mk index 7b13ebf2212b..e3346e08b5a0 100644 --- a/contrib/bmake/unit-tests/cond-cmp-string.mk +++ b/contrib/bmake/unit-tests/cond-cmp-string.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-cmp-string.mk,v 1.18 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: cond-cmp-string.mk,v 1.19 2024/04/23 22:51:28 rillig Exp $ # # Tests for string comparisons in .if conditions. @@ -20,12 +20,12 @@ . error .endif -# The left-hand side of the comparison requires that any expression -# is defined. +# An expression that occurs on the left-hand side of the comparison must be +# defined. # # The variable named "" is never defined, nevertheless it can be used as a -# starting point for expressions. Applying the :U modifier to such -# an undefined expression turns it into a defined expression. +# starting point for an expression. Applying the :U modifier to such an +# undefined expression turns it into a defined expression. # # See ApplyModifier_Defined and DEF_DEFINED. .if ${:Ustr} != "str" @@ -69,8 +69,9 @@ .endif # Between 2003-01-01 (maybe even earlier) and 2020-10-30, adding one of the -# characters " \t!=><" directly after an expression resulted in a -# "Malformed conditional", even though the string was well-formed. +# characters " \t!=><" directly after an expression in a string literal +# resulted in a "Malformed conditional", even though the string was +# well-formed. .if ${:Uword } != "${:Uword} " . error .endif @@ -94,8 +95,7 @@ . error .endif -# Adding a space at the beginning of the quoted expression works -# though. +# Adding a space at the beginning of the quoted expression works though. .if ${:U word } != " ${:Uword} " . error .endif @@ -145,7 +145,7 @@ . error .endif -# Two variables with different values compare unequal. +# Two expressions with different values compare unequal. VAR1= value1 VAR2= value2 .if ${VAR1} != ${VAR2} diff --git a/contrib/bmake/unit-tests/cond-func-defined.exp b/contrib/bmake/unit-tests/cond-func-defined.exp index d556f3b982b3..1d4243f9eddd 100644 --- a/contrib/bmake/unit-tests/cond-func-defined.exp +++ b/contrib/bmake/unit-tests/cond-func-defined.exp @@ -1,8 +1,5 @@ make: "cond-func-defined.mk" line 24: Missing closing parenthesis for defined() make: "cond-func-defined.mk" line 34: Missing closing parenthesis for defined() -make: "cond-func-defined.mk" line 47: In .for loops, expressions for the loop variables are -make: "cond-func-defined.mk" line 49: substituted at evaluation time. There is no actual variable -make: "cond-func-defined.mk" line 51: involved, even if it feels like it. make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/cond-func-defined.mk b/contrib/bmake/unit-tests/cond-func-defined.mk index 14597398bc62..6b24182c11c1 100644 --- a/contrib/bmake/unit-tests/cond-func-defined.mk +++ b/contrib/bmake/unit-tests/cond-func-defined.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-func-defined.mk,v 1.11 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: cond-func-defined.mk,v 1.12 2024/04/23 22:51:28 rillig Exp $ # # Tests for the defined() function in .if conditions. @@ -43,12 +43,9 @@ ${:UA B}= variable name with spaces . if defined(var) . error . else -# expect+1: In .for loops, expressions for the loop variables are -. info In .for loops, expressions for the loop variables are -# expect+1: substituted at evaluation time. There is no actual variable -. info substituted at evaluation time. There is no actual variable -# expect+1: involved, even if it feels like it. -. info involved, even if it feels like it. +# In .for loops, expressions based on the loop variables are substituted at +# evaluation time. There is no actual variable involved, even if the code in +# the makefiles looks like it. . endif .endfor diff --git a/contrib/bmake/unit-tests/cond-token-string.exp b/contrib/bmake/unit-tests/cond-token-string.exp index db07adcb2d09..4fbafc5e1986 100644 --- a/contrib/bmake/unit-tests/cond-token-string.exp +++ b/contrib/bmake/unit-tests/cond-token-string.exp @@ -1,4 +1,4 @@ -make: "cond-token-string.mk" line 15: Unknown modifier "Z" +make: "cond-token-string.mk" line 15: while evaluating "${:Uvalue:Z}"": Unknown modifier "Z" make: "cond-token-string.mk" line 15: Malformed conditional ("" != "${:Uvalue:Z}") make: "cond-token-string.mk" line 25: xvalue is not defined. make: "cond-token-string.mk" line 32: Malformed conditional (x${:Uvalue} == "") diff --git a/contrib/bmake/unit-tests/cond-token-string.mk b/contrib/bmake/unit-tests/cond-token-string.mk index d13c68da134a..edc9936b7d53 100644 --- a/contrib/bmake/unit-tests/cond-token-string.mk +++ b/contrib/bmake/unit-tests/cond-token-string.mk @@ -1,4 +1,4 @@ -# $NetBSD: cond-token-string.mk,v 1.9 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: cond-token-string.mk,v 1.10 2024/04/20 10:18:55 rillig Exp $ # # Tests for quoted string literals in .if conditions. # @@ -11,7 +11,7 @@ # Cover the code in CondParser_String that frees the memory after parsing # an expression based on an undefined variable. # expect+2: Malformed conditional ("" != "${:Uvalue:Z}") -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:Uvalue:Z}"": Unknown modifier "Z" .if "" != "${:Uvalue:Z}" . error .else diff --git a/contrib/bmake/unit-tests/depsrc-end.mk b/contrib/bmake/unit-tests/depsrc-end.mk index eb7543d5dfad..1bfe50d98620 100644 --- a/contrib/bmake/unit-tests/depsrc-end.mk +++ b/contrib/bmake/unit-tests/depsrc-end.mk @@ -1,6 +1,6 @@ -# $NetBSD: depsrc-end.mk,v 1.1 2020/10/23 19:23:01 rillig Exp $ +# $NetBSD: depsrc-end.mk,v 1.2 2024/04/27 20:41:32 rillig Exp $ # -# Demonstrate the edge case that .BEGIN depends on .END, which sounds a bit +# Demonstrate an edge case in which .BEGIN depends on .END, which sounds a bit # paradox but works since these special nodes are not in the dependency # hierarchy where the cycles are detected. diff --git a/contrib/bmake/unit-tests/depsrc-nopath.exp b/contrib/bmake/unit-tests/depsrc-nopath.exp index 39a9383953dd..01295d8df7f5 100644 --- a/contrib/bmake/unit-tests/depsrc-nopath.exp +++ b/contrib/bmake/unit-tests/depsrc-nopath.exp @@ -1 +1,3 @@ +: Making test-regular from depsrc-nopath.dir/regular.file +: Making test-nopath from nopath.file exit status 0 diff --git a/contrib/bmake/unit-tests/depsrc-nopath.mk b/contrib/bmake/unit-tests/depsrc-nopath.mk index 052c6f10db66..8d9ce93c16b9 100644 --- a/contrib/bmake/unit-tests/depsrc-nopath.mk +++ b/contrib/bmake/unit-tests/depsrc-nopath.mk @@ -1,8 +1,27 @@ -# $NetBSD: depsrc-nopath.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $ +# $NetBSD: depsrc-nopath.mk,v 1.3 2024/04/27 20:41:32 rillig Exp $ # # Tests for the special source .NOPATH in dependency declarations. -# TODO: Implementation +.if !target(test-*) +_!= rm -rf depsrc-nopath.dir +_!= mkdir depsrc-nopath.dir +_!= touch depsrc-nopath.dir/regular.file +_!= touch depsrc-nopath.dir/nopath.file +.endif all: - @:; + @${MAKE} -f ${MAKEFILE} test-regular + @${MAKE} -f ${MAKEFILE} test-nopath || echo "should have failed" + @rm -rf depsrc-nopath.dir + +.PATH: depsrc-nopath.dir + +test-regular: regular.file + : Making ${.TARGET} from ${.ALLSRC} +test-nopath: nopath.file + : Making ${.TARGET} from ${.ALLSRC} + +nopath.file: .NOPATH + +# expect: : Making test-regular from depsrc-nopath.dir/regular.file +# expect: : Making test-nopath from nopath.file diff --git a/contrib/bmake/unit-tests/depsrc-phony.mk b/contrib/bmake/unit-tests/depsrc-phony.mk index c41efac369a8..9df1eb570ab4 100644 --- a/contrib/bmake/unit-tests/depsrc-phony.mk +++ b/contrib/bmake/unit-tests/depsrc-phony.mk @@ -1,9 +1,10 @@ -# $NetBSD: depsrc-phony.mk,v 1.3 2020/09/05 15:57:12 rillig Exp $ +# $NetBSD: depsrc-phony.mk,v 1.4 2024/04/27 20:41:32 rillig Exp $ # # Tests for the special source .PHONY in dependency declarations, # which executes the commands for the target even if a file of the same # name exists and would be considered up to date. # Without the .PHONY, this target would be "up to date". +# expect: : depsrc-phony.mk is made. ${MAKEFILE}: .PHONY : ${.TARGET:T} is made. diff --git a/contrib/bmake/unit-tests/deptgt-phony.exp b/contrib/bmake/unit-tests/deptgt-phony.exp index 1c379b32a33b..e943091e4cef 100644 --- a/contrib/bmake/unit-tests/deptgt-phony.exp +++ b/contrib/bmake/unit-tests/deptgt-phony.exp @@ -2,7 +2,7 @@ Expanding "depsrc-phony-pr-15164-*-wildcard"... Expanding "deptgt-phony-pr-15164-*-wildcard"... Searching for .depend ... failed. -Searching for .depend ... +Searching for .depend ...[dot last]... . ... failed. Wildcard expanding "all"... diff --git a/contrib/bmake/unit-tests/deptgt.exp b/contrib/bmake/unit-tests/deptgt.exp index 00d312685de9..90213fe44fb5 100644 --- a/contrib/bmake/unit-tests/deptgt.exp +++ b/contrib/bmake/unit-tests/deptgt.exp @@ -8,7 +8,7 @@ ParseDependency(: empty-source) Parsing line 39: : command for empty targets list Parsing line 40: .MAKEFLAGS: -d0 ParseDependency(.MAKEFLAGS: -d0) -make: "deptgt.mk" line 49: Unknown modifier "Z" +make: "deptgt.mk" line 49: while evaluating "${:U:Z}:": Unknown modifier "Z" make: "deptgt.mk" line 52: warning: Extra target 'ordinary' ignored make: "deptgt.mk" line 55: warning: Extra target (ordinary) ignored make: "deptgt.mk" line 58: warning: Special and mundane targets don't mix. Mundane ones ignored diff --git a/contrib/bmake/unit-tests/deptgt.mk b/contrib/bmake/unit-tests/deptgt.mk index 30b8399191bd..eb948918abb7 100644 --- a/contrib/bmake/unit-tests/deptgt.mk +++ b/contrib/bmake/unit-tests/deptgt.mk @@ -1,4 +1,4 @@ -# $NetBSD: deptgt.mk,v 1.16 2023/12/17 09:44:00 rillig Exp $ +# $NetBSD: deptgt.mk,v 1.17 2024/04/20 10:18:55 rillig Exp $ # # Tests for special targets like .BEGIN or .SUFFIXES in dependency # declarations. @@ -45,7 +45,7 @@ ${:U}: empty-source # expansion would be to use the variable modifier '::=' to modify the # targets. This in turn would be such an extreme and unreliable edge case # that nobody uses it. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:U:Z}:": Unknown modifier "Z" $$$$$$$${:U:Z}: # expect+1: warning: Extra target 'ordinary' ignored diff --git a/contrib/bmake/unit-tests/directive-export-impl.exp b/contrib/bmake/unit-tests/directive-export-impl.exp index fada441f5e92..7daf1f45b0cb 100644 --- a/contrib/bmake/unit-tests/directive-export-impl.exp +++ b/contrib/bmake/unit-tests/directive-export-impl.exp @@ -10,6 +10,7 @@ Pattern for ':N' is "*" ModifyWords: split "<>" into 1 word Result of ${UT_VAR:N*} is "" ParseDependency(: ) +Parsing line 42: .if ${:!echo "\$UT_VAR"!} != "<>" CondParser_Eval: ${:!echo "\$UT_VAR"!} != "<>" Var_Parse: ${:!echo "\$UT_VAR"!} != "<>" (eval-defined) Evaluating modifier ${:!...} on value "" (eval-defined, undefined) @@ -34,6 +35,7 @@ Result of ${UT_VAR:N*} is "" ParseDependency(: ) Parsing line 54: REF= defined Global: REF = defined +Parsing line 58: .if ${:!echo "\$UT_VAR"!} != "<defined>" CondParser_Eval: ${:!echo "\$UT_VAR"!} != "<defined>" Var_Parse: ${:!echo "\$UT_VAR"!} != "<defined>" (eval-defined) Evaluating modifier ${:!...} on value "" (eval-defined, undefined) diff --git a/contrib/bmake/unit-tests/directive-for-errors.exp b/contrib/bmake/unit-tests/directive-for-errors.exp index 115a6af5b069..9c1aa5c0b1ed 100644 --- a/contrib/bmake/unit-tests/directive-for-errors.exp +++ b/contrib/bmake/unit-tests/directive-for-errors.exp @@ -8,7 +8,7 @@ make: "directive-for-errors.mk" line 44: invalid character '$' in .for loop vari make: "directive-for-errors.mk" line 52: no iteration variables in for make: "directive-for-errors.mk" line 64: Wrong number of words (5) in .for substitution list with 3 variables make: "directive-for-errors.mk" line 78: missing `in' in for -make: "directive-for-errors.mk" line 89: Unknown modifier "Z" +make: "directive-for-errors.mk" line 89: while evaluating "${:U3:Z} 4": Unknown modifier "Z" make: "directive-for-errors.mk" line 90: warning: Should not be reached. make: "directive-for-errors.mk" line 90: warning: Should not be reached. make: "directive-for-errors.mk" line 90: warning: Should not be reached. diff --git a/contrib/bmake/unit-tests/directive-for-errors.mk b/contrib/bmake/unit-tests/directive-for-errors.mk index 94362847cdfd..1bd4f31d383a 100644 --- a/contrib/bmake/unit-tests/directive-for-errors.mk +++ b/contrib/bmake/unit-tests/directive-for-errors.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-for-errors.mk,v 1.9 2023/12/19 19:33:40 rillig Exp $ +# $NetBSD: directive-for-errors.mk,v 1.10 2024/04/20 10:18:55 rillig Exp $ # # Tests for error handling in .for loops. @@ -85,7 +85,7 @@ ${:U\\}= backslash # see whether the "variable" '\' is local # # XXX: As of 2020-12-31, Var_Subst doesn't report any errors, therefore # the loop body is expanded as if no error had happened. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:U3:Z} 4": Unknown modifier "Z" .for i in 1 2 ${:U3:Z} 4 . warning Should not be reached. .endfor diff --git a/contrib/bmake/unit-tests/directive-for-escape.exp b/contrib/bmake/unit-tests/directive-for-escape.exp index 6c84b7780e84..1f4305185d65 100644 --- a/contrib/bmake/unit-tests/directive-for-escape.exp +++ b/contrib/bmake/unit-tests/directive-for-escape.exp @@ -106,6 +106,7 @@ make: "directive-for-escape.mk" line 228: long: " " For: end for 1 For: loop body with i = " ": +Parsing line 244: .for i in "${.newline}" For: end for 1 Parse_PushInput: .for loop in directive-for-escape.mk, line 244 make: "directive-for-escape.mk" line 244: newline in .for value diff --git a/contrib/bmake/unit-tests/directive-for-null.exp b/contrib/bmake/unit-tests/directive-for-null.exp index dee26de25e63..d6198c644817 100644 --- a/contrib/bmake/unit-tests/directive-for-null.exp +++ b/contrib/bmake/unit-tests/directive-for-null.exp @@ -1,9 +1,5 @@ make: "(stdin)" line 2: Zero byte read from file -make: "(stdin)" line 2: Unexpected end of file in .for loop -make: "(stdin)" line 3: Zero byte read from file -make: Fatal errors encountered -- cannot continue -make: stopped in unit-tests -*** Error code 1 (continuing) +*** Error code 2 (continuing) Stop. make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/directive-for-null.mk b/contrib/bmake/unit-tests/directive-for-null.mk index fb2d440ee1ba..d3de8b598bc2 100644 --- a/contrib/bmake/unit-tests/directive-for-null.mk +++ b/contrib/bmake/unit-tests/directive-for-null.mk @@ -1,18 +1,8 @@ -# $NetBSD: directive-for-null.mk,v 1.3 2022/06/12 15:03:27 rillig Exp $ +# $NetBSD: directive-for-null.mk,v 1.4 2024/04/01 12:26:02 rillig Exp $ # # Test for parsing a .for loop that accidentally contains a null byte. # -# As of 2020-12-19, there are 3 error messages: -# -# make: "(stdin)" line 2: Zero byte read from file -# make: "(stdin)" line 2: Unexpected end of file in for loop. -# make: "(stdin)" line 3: Zero byte read from file -# -# The one about "end of file" might be misleading but is due to the -# implementation. On both errors and EOF, ParseRawLine returns NULL. -# -# The one about the "zero byte" in line 3 is surprising since the only -# line that contains a null byte is line 2. +# expect: make: "(stdin)" line 2: Zero byte read from file all: .PHONY @printf '%s\n' \ diff --git a/contrib/bmake/unit-tests/directive-for.exp b/contrib/bmake/unit-tests/directive-for.exp index 0d0313c4e7b0..3e346dfab4ea 100755 --- a/contrib/bmake/unit-tests/directive-for.exp +++ b/contrib/bmake/unit-tests/directive-for.exp @@ -17,7 +17,7 @@ make: "directive-for.mk" line 146: }{ }{ }{ make: "directive-for.mk" line 166: invalid character ':' in .for loop variable name make: "directive-for.mk" line 173: invalid character '$' in .for loop variable name make: "directive-for.mk" line 185: invalid character '$' in .for loop variable name -make: "directive-for.mk" line 210: Unknown modifier "Z" +make: "directive-for.mk" line 210: while evaluating "${:Uword2:Z}-after word3": Unknown modifier "Z" make: "directive-for.mk" line 211: XXX: Should not reach word1 make: "directive-for.mk" line 211: XXX: Should not reach before--after make: "directive-for.mk" line 211: XXX: Should not reach word3 diff --git a/contrib/bmake/unit-tests/directive-for.mk b/contrib/bmake/unit-tests/directive-for.mk index becc314226dc..d777c3921556 100755 --- a/contrib/bmake/unit-tests/directive-for.mk +++ b/contrib/bmake/unit-tests/directive-for.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-for.mk,v 1.24 2023/12/06 22:28:20 rillig Exp $ +# $NetBSD: directive-for.mk,v 1.25 2024/04/20 10:18:55 rillig Exp $ # # Tests for the .for directive. # @@ -206,7 +206,7 @@ INDIRECT= ${DIRECT} # XXX: A parse error or evaluation error in the items of the .for loop # should skip the whole loop. As of 2023-05-09, the loop is expanded as # usual. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:Uword2:Z}-after word3": Unknown modifier "Z" .for var in word1 before-${:Uword2:Z}-after word3 . info XXX: Should not reach ${var} .endfor diff --git a/contrib/bmake/unit-tests/directive-include.exp b/contrib/bmake/unit-tests/directive-include.exp index de94b751b33a..6454b6835edf 100755 --- a/contrib/bmake/unit-tests/directive-include.exp +++ b/contrib/bmake/unit-tests/directive-include.exp @@ -4,7 +4,7 @@ CondParser_Eval: ${.MAKE.MAKEFILES:T} != "${.PARSEFILE} null" Comparing "directive-include.mk null" != "directive-include.mk null" make: "directive-include.mk" line 26: Could not find nonexistent.mk make: "directive-include.mk" line 49: Could not find " -make: "directive-include.mk" line 56: Unknown modifier "Z" +make: "directive-include.mk" line 56: while evaluating "${:U123:Z}.mk": Unknown modifier "Z" make: "directive-include.mk" line 56: Could not find nonexistent.mk make: "directive-include.mk" line 61: Cannot open /nonexistent make: "directive-include.mk" line 66: Invalid line 'include' diff --git a/contrib/bmake/unit-tests/directive-include.mk b/contrib/bmake/unit-tests/directive-include.mk index 2517b4be6930..14d00600cb8f 100755 --- a/contrib/bmake/unit-tests/directive-include.mk +++ b/contrib/bmake/unit-tests/directive-include.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-include.mk,v 1.13 2023/08/19 10:52:14 rillig Exp $ +# $NetBSD: directive-include.mk,v 1.14 2024/04/20 10:18:55 rillig Exp $ # # Tests for the .include directive, which includes another file. @@ -52,7 +52,7 @@ DQUOT= " # expression is skipped and the file is included nevertheless. # FIXME: Add proper error handling, no file must be included here. # expect+2: Could not find nonexistent.mk -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:U123:Z}.mk": Unknown modifier "Z" .include "nonexistent${:U123:Z}.mk" # The traditional include directive is seldom used. diff --git a/contrib/bmake/unit-tests/directive-undef.exp b/contrib/bmake/unit-tests/directive-undef.exp index f3957a990e18..329dc8d6282a 100644 --- a/contrib/bmake/unit-tests/directive-undef.exp +++ b/contrib/bmake/unit-tests/directive-undef.exp @@ -1,5 +1,5 @@ make: "directive-undef.mk" line 30: The .undef directive requires an argument -make: "directive-undef.mk" line 88: Unknown modifier "Z" +make: "directive-undef.mk" line 88: while evaluating variable "VARNAMES": Unknown modifier "Z" make: "directive-undef.mk" line 105: warning: UT_EXPORTED is still listed in .MAKE.EXPORTED even though spaceit is not exported anymore. make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/directive-undef.mk b/contrib/bmake/unit-tests/directive-undef.mk index ef047fefe177..ac4b20d3e858 100644 --- a/contrib/bmake/unit-tests/directive-undef.mk +++ b/contrib/bmake/unit-tests/directive-undef.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-undef.mk,v 1.13 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: directive-undef.mk,v 1.14 2024/04/20 10:18:55 rillig Exp $ # # Tests for the .undef directive. # @@ -84,7 +84,7 @@ ${DOLLAR}= dollar # # As of var.c 1.762, this doesn't happen though because the error handling # in Var_Parse and Var_Subst is not done properly. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating variable "VARNAMES": Unknown modifier "Z" .undef ${VARNAMES:L:Z} diff --git a/contrib/bmake/unit-tests/lint.exp b/contrib/bmake/unit-tests/lint.exp index db2290c040cd..78761c862298 100755 --- a/contrib/bmake/unit-tests/lint.exp +++ b/contrib/bmake/unit-tests/lint.exp @@ -1,4 +1,4 @@ -make: In the :@ modifier of "VAR", the variable name "${:Ubar:S,b,v,}" must not contain a dollar +make: in target "mod-loop-varname": while evaluating variable "VAR": In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar y@:Q} xvaluey exit status 2 diff --git a/contrib/bmake/unit-tests/moderrs.exp b/contrib/bmake/unit-tests/moderrs.exp index 6b41241b6800..0d1bcdc5b0f9 100644 --- a/contrib/bmake/unit-tests/moderrs.exp +++ b/contrib/bmake/unit-tests/moderrs.exp @@ -1,11 +1,11 @@ mod-unknown-direct: want: Unknown modifier 'Z' -make: Unknown modifier "Z" +make: in target "mod-unknown-direct": while evaluating variable "VAR": Unknown modifier "Z" VAR:Z=before--after mod-unknown-indirect: want: Unknown modifier 'Z' -make: Unknown modifier "Z" +make: in target "mod-unknown-indirect": while evaluating variable "VAR": Unknown modifier "Z" VAR:Z=before-inner}-after unclosed-direct: @@ -119,17 +119,17 @@ then mod-remember-parse: 1 1 2 3 5 8 13 21 34 -make: Unknown modifier "__" +make: in target "mod-remember-parse": while evaluating variable "FIB": Unknown modifier "__" mod-sysv-parse: -make: Unknown modifier "3" +make: in target "mod-sysv-parse": while evaluating variable "FIB": Unknown modifier "3" make: Unclosed expression, expecting '}' for modifier "3" of variable "FIB" with value "" -make: Unknown modifier "3=" +make: in target "mod-sysv-parse": while evaluating variable "FIB": Unknown modifier "3=" make: Unclosed expression, expecting '}' for modifier "3=" of variable "FIB" with value "" -make: Unknown modifier "3=x3" +make: in target "mod-sysv-parse": while evaluating variable "FIB": Unknown modifier "3=x3" make: Unclosed expression, expecting '}' for modifier "3=x3" of variable "FIB" with value "" 1 1 2 x3 5 8 1x3 21 34 diff --git a/contrib/bmake/unit-tests/opt-chdir.exp b/contrib/bmake/unit-tests/opt-chdir.exp index d9759cf9ed8b..3d89360f9a62 100644 --- a/contrib/bmake/unit-tests/opt-chdir.exp +++ b/contrib/bmake/unit-tests/opt-chdir.exp @@ -1,5 +1,3 @@ -make: chdir /./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././: File name too long -*** Error code 2 (ignored) cwd: / make: chdir /nonexistent: No such file or directory *** Error code 2 (ignored) diff --git a/contrib/bmake/unit-tests/opt-chdir.mk b/contrib/bmake/unit-tests/opt-chdir.mk index a8806149f31c..e94b8799af2e 100644 --- a/contrib/bmake/unit-tests/opt-chdir.mk +++ b/contrib/bmake/unit-tests/opt-chdir.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-chdir.mk,v 1.6 2021/05/18 17:05:45 sjg Exp $ +# $NetBSD: opt-chdir.mk,v 1.7 2024/04/02 11:11:00 rillig Exp $ # # Tests for the -C command line option, which changes the directory at the # beginning. @@ -7,15 +7,9 @@ .MAKEFLAGS: -d0 # switch stdout to line-buffered -all: chdir-filename-too-long all: chdir-root all: chdir-nonexistent -# Try to overflow the internal buffer for .CURDIR, which is curdir. -chdir-filename-too-long: .PHONY .IGNORE - # 5000 slashes, separated by dots: /./././.../././ - @${MAKE} -C ${:U:range=5000:@@/@:ts.} - # Changing to another directory is possible via the command line. # In this test, it is the root directory since almost any other directory # is not guaranteed to exist on every platform. diff --git a/contrib/bmake/unit-tests/opt-debug-errors-jobs.exp b/contrib/bmake/unit-tests/opt-debug-errors-jobs.exp index c957c7736b32..614bb33b9208 100644 --- a/contrib/bmake/unit-tests/opt-debug-errors-jobs.exp +++ b/contrib/bmake/unit-tests/opt-debug-errors-jobs.exp @@ -2,6 +2,7 @@ echo '3 spaces'; false 3 spaces *** Failed target: fail-spaces +*** In directory: <curdir> *** Failed commands: echo '3 spaces'; false *** [fail-spaces] Error code 1 @@ -11,6 +12,7 @@ echo \ indented; false indented *** Failed target: fail-escaped-space +*** In directory: <curdir> *** Failed commands: echo \ indented; false *** [fail-escaped-space] Error code 1 @@ -22,6 +24,7 @@ line1 line2 *** Failed target: fail-newline +*** In directory: <curdir> *** Failed commands: echo 'line1${.newline}line2'; false => echo 'line1 @@ -33,6 +36,7 @@ echo 'line1 line2'; false line1 line2 *** Failed target: fail-multiline +*** In directory: <curdir> *** Failed commands: echo 'line1 line2'; false *** [fail-multiline] Error code 1 @@ -42,6 +46,7 @@ echo 'word1' 'word2'; false word1 word2 *** Failed target: fail-multiline-intention +*** In directory: <curdir> *** Failed commands: echo 'word1' 'word2'; false *** [fail-multiline-intention] Error code 1 @@ -49,6 +54,7 @@ word1 word2 make: stopped in unit-tests *** Failed target: fail-vars +*** In directory: <curdir> *** Failed commands: @${COMPILE_C} ${COMPILE_C_FLAGS} => @false c-compiler flag1 -macro="several words" diff --git a/contrib/bmake/unit-tests/opt-debug-lint.exp b/contrib/bmake/unit-tests/opt-debug-lint.exp index 5a6510bd029a..c6cd748acd5d 100644 --- a/contrib/bmake/unit-tests/opt-debug-lint.exp +++ b/contrib/bmake/unit-tests/opt-debug-lint.exp @@ -2,9 +2,9 @@ make: "opt-debug-lint.mk" line 21: Variable "X" is undefined make: "opt-debug-lint.mk" line 21: Malformed conditional ($X) make: "opt-debug-lint.mk" line 45: Variable "UNDEF" is undefined make: "opt-debug-lint.mk" line 45: Malformed conditional (${UNDEF}) -make: "opt-debug-lint.mk" line 67: Missing delimiter ':' after modifier "L" -make: "opt-debug-lint.mk" line 67: Missing delimiter ':' after modifier "P" -make: "opt-debug-lint.mk" line 76: Unknown modifier "${" +make: "opt-debug-lint.mk" line 67: while evaluating variable "value": Missing delimiter ':' after modifier "L" +make: "opt-debug-lint.mk" line 67: while evaluating variable "value": Missing delimiter ':' after modifier "P" +make: "opt-debug-lint.mk" line 76: while evaluating variable "value": Unknown modifier "${" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/opt-debug-lint.mk b/contrib/bmake/unit-tests/opt-debug-lint.mk index 042bfd51d35b..3e946ac6ad61 100644 --- a/contrib/bmake/unit-tests/opt-debug-lint.mk +++ b/contrib/bmake/unit-tests/opt-debug-lint.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-debug-lint.mk,v 1.16 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: opt-debug-lint.mk,v 1.17 2024/04/20 10:18:55 rillig Exp $ # # Tests for the -dL command line option, which runs additional checks # to catch common mistakes, such as unclosed expressions. @@ -62,8 +62,8 @@ ${UNDEF}: ${UNDEF} # Since 2020-10-03, in lint mode the variable modifier must be separated # by colons. See varparse-mod.mk. -# expect+2: Missing delimiter ':' after modifier "L" -# expect+1: Missing delimiter ':' after modifier "P" +# expect+2: while evaluating variable "value": Missing delimiter ':' after modifier "L" +# expect+1: while evaluating variable "value": Missing delimiter ':' after modifier "P" .if ${value:LPL} != "value" . error .endif @@ -72,7 +72,7 @@ ${UNDEF}: ${UNDEF} # variable modifier had to be separated by colons. This was wrong though # since make always fell back trying to parse the indirect modifier as a # SysV modifier. -# expect+1: Unknown modifier "${" +# expect+1: while evaluating variable "value": Unknown modifier "${" .if ${value:${:UL}PL} != "LPL}" # FIXME: "LPL}" is unexpected here. . error ${value:${:UL}PL} .endif diff --git a/contrib/bmake/unit-tests/opt-debug-parse.exp b/contrib/bmake/unit-tests/opt-debug-parse.exp index 811c6b45dce5..a19a58bcc965 100644 --- a/contrib/bmake/unit-tests/opt-debug-parse.exp +++ b/contrib/bmake/unit-tests/opt-debug-parse.exp @@ -1,3 +1,4 @@ +Parsing line 16: .for var in value Parse_PushInput: .for loop in opt-debug-parse.mk, line 16 SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk' Parsing line 21: .info trace with multi-line .for loop head @@ -11,6 +12,7 @@ SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `null' SetFilenameVars: ${.INCLUDEDFROMDIR} = <some-dir> ${.INCLUDEDFROMFILE} = `opt-debug-parse.mk' ParseEOF: returning to file opt-debug-parse.mk, line 27 SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk' +Parsing line 31: .for a b c in 1 2 3 ${:U4 5 6} Parse_PushInput: .for loop in opt-debug-parse.mk, line 31 SetFilenameVars: ${.PARSEDIR} = <some-dir> ${.PARSEFILE} = `opt-debug-parse.mk' Parsing line 34: .info trace diff --git a/contrib/bmake/unit-tests/opt-file.exp b/contrib/bmake/unit-tests/opt-file.exp index 76a832949aca..9550958fea37 100644 --- a/contrib/bmake/unit-tests/opt-file.exp +++ b/contrib/bmake/unit-tests/opt-file.exp @@ -2,9 +2,7 @@ value value line-with-trailing-whitespace make: "(stdin)" line 1: Zero byte read from file -make: Fatal errors encountered -- cannot continue -make: stopped in unit-tests -*** Error code 1 (continuing) +*** Error code 2 (continuing) `all' not remade because of errors. Stop. diff --git a/contrib/bmake/unit-tests/opt-file.mk b/contrib/bmake/unit-tests/opt-file.mk index 5085fe126af8..0f07ede560f5 100644 --- a/contrib/bmake/unit-tests/opt-file.mk +++ b/contrib/bmake/unit-tests/opt-file.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-file.mk,v 1.15 2022/03/26 13:32:31 rillig Exp $ +# $NetBSD: opt-file.mk,v 1.16 2024/04/01 12:26:02 rillig Exp $ # # Tests for the -f command line option, which adds a makefile to the list of # files that are parsed. @@ -79,7 +79,7 @@ line-with-trailing-whitespace: .PHONY # exit status 0 # # 2008 to 2010: -# make: "zero-byte.in" line 1: Zero byte read from file +# make: "(stdin)" line 1: Zero byte read from file # make: Fatal errors encountered -- cannot continue # # make: stopped in . @@ -92,14 +92,18 @@ line-with-trailing-whitespace: .PHONY # exit status 2 # # 2014 to 2020-12-06: -# make: "zero-byte.in" line 1: warning: Zero byte read from file, skipping rest of line. +# make: "(stdin)" line 1: warning: Zero byte read from file, skipping rest of line. # exit status 0 # # Since 2020-12-07: -# make: "zero-byte.in" line 1: Zero byte read from file +# make: "(stdin)" line 1: Zero byte read from file # make: Fatal errors encountered -- cannot continue # make: stopped in . # exit status 1 +# +# Since 2024-04-01: +# make: "(stdin)" line 1: Zero byte read from file +# *** Error code 2 (continuing) file-containing-null-byte: .PHONY @printf '%s\n' 'VAR=value' 'VAR2=VALUE2' \ | tr 'l' '\0' \ diff --git a/contrib/bmake/unit-tests/opt-keep-going-indirect.mk b/contrib/bmake/unit-tests/opt-keep-going-indirect.mk index 22f7be945f71..5d18553fa512 100644 --- a/contrib/bmake/unit-tests/opt-keep-going-indirect.mk +++ b/contrib/bmake/unit-tests/opt-keep-going-indirect.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-keep-going-indirect.mk,v 1.2 2022/02/12 20:05:36 rillig Exp $ +# $NetBSD: opt-keep-going-indirect.mk,v 1.3 2024/04/02 15:05:15 rillig Exp $ # # Tests for the -k command line option, which stops building a target as soon # as an error is detected, but continues building the other, independent @@ -49,19 +49,19 @@ # to the child processes. all: @echo 'direct compat' - @set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k direct; echo "exited $$?" + @set +e; env -i "PATH=$$PATH" ${MAKE} -r -f ${MAKEFILE} -k direct; echo "exited $$?" @echo @echo 'direct jobs' - @set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k direct -j1; echo "exited $$?" + @set +e; env -i "PATH=$$PATH" ${MAKE} -r -f ${MAKEFILE} -k direct -j1; echo "exited $$?" @echo @echo 'indirect compat' - @set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k indirect; echo "exited $$?" + @set +e; env -i "PATH=$$PATH" ${MAKE} -r -f ${MAKEFILE} -k indirect; echo "exited $$?" @echo @echo 'indirect jobs' - @set +e; env -i ${MAKE} -r -f ${MAKEFILE} -k indirect -j1; echo "exited $$?" + @set +e; env -i "PATH=$$PATH" ${MAKE} -r -f ${MAKEFILE} -k indirect -j1; echo "exited $$?" @echo indirect: direct diff --git a/contrib/bmake/unit-tests/opt-m-include-dir.mk b/contrib/bmake/unit-tests/opt-m-include-dir.mk index 6e0801390395..b677f172e85b 100644 --- a/contrib/bmake/unit-tests/opt-m-include-dir.mk +++ b/contrib/bmake/unit-tests/opt-m-include-dir.mk @@ -1,4 +1,4 @@ -# $NetBSD: opt-m-include-dir.mk,v 1.4 2020/09/01 20:14:34 rillig Exp $ +# $NetBSD: opt-m-include-dir.mk,v 1.5 2024/04/30 16:13:34 sjg Exp $ # # Tests for the -m command line option, which adds a directory to the # search path for the .include <...> directive. @@ -22,11 +22,14 @@ TEST_DIR:= ${.PARSEFILE:R}.tmp/sub/sub/sub/workdir CANARY_FILE:= ${.PARSEFILE:R}.tmp/sub/opt-m-canary.mk ACTUAL_FILE:= ${.PARSEFILE:R}.tmp/sub/opt-m-step3.mk +WANTED_FILE:= ${.PARSEFILE:R}.tmp/sub/opt-m-check.mk _!= mkdir -p ${TEST_DIR} _!= > ${CANARY_FILE} _!= cp ${MAKEFILE} ${TEST_DIR}/step2.mk _!= cp ${MAKEFILE} ${ACTUAL_FILE} +_!= echo CHECK=ok > ${WANTED_FILE} +_!= echo CHECK=${WANTED_FILE:T} found in .CURDIR > ${TEST_DIR}/${WANTED_FILE:T} step1: @${.MAKE} -C ${TEST_DIR} -f step2.mk step2 @@ -52,9 +55,10 @@ step1: .elif ${.PARSEFILE:T} == "opt-m-step3.mk" # This file is included by step2.mk. +.include <opt-m-check.mk> step2: - @echo ok + @echo ${CHECK} .else . error diff --git a/contrib/bmake/unit-tests/var-eval-short.exp b/contrib/bmake/unit-tests/var-eval-short.exp index 14e3d372f198..6b42c27e22bc 100644 --- a/contrib/bmake/unit-tests/var-eval-short.exp +++ b/contrib/bmake/unit-tests/var-eval-short.exp @@ -1,5 +1,6 @@ -make: "var-eval-short.mk" line 46: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar +make: "var-eval-short.mk" line 46: while evaluating "${:Uword:@${FAIL}@expr@}": In the :@ modifier, the variable name "${FAIL}" must not contain a dollar make: "var-eval-short.mk" line 46: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@}) +Parsing line 159: .if 0 && ${0:?${FAIL}then:${FAIL}else} CondParser_Eval: 0 && ${0:?${FAIL}then:${FAIL}else} Var_Parse: ${0:?${FAIL}then:${FAIL}else} (parse-only) Parsing modifier ${0:?...} @@ -10,6 +11,7 @@ Modifier part: "${FAIL}else" Result of ${0:?${FAIL}then:${FAIL}else} is "" (parse-only, defined) Parsing line 167: DEFINED= defined Global: DEFINED = defined +Parsing line 168: .if 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else} CondParser_Eval: 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else} Var_Parse: ${DEFINED:L:?${FAIL}then:${FAIL}else} (parse-only) Parsing modifier ${DEFINED:L} diff --git a/contrib/bmake/unit-tests/var-eval-short.mk b/contrib/bmake/unit-tests/var-eval-short.mk index 2b25d82e96b8..5a42335a4474 100644 --- a/contrib/bmake/unit-tests/var-eval-short.mk +++ b/contrib/bmake/unit-tests/var-eval-short.mk @@ -1,4 +1,4 @@ -# $NetBSD: var-eval-short.mk,v 1.11 2023/10/19 18:24:33 rillig Exp $ +# $NetBSD: var-eval-short.mk,v 1.12 2024/04/20 10:18:55 rillig Exp $ # # Tests for each variable modifier to ensure that they only do the minimum # necessary computations. If the result of the expression is irrelevant, @@ -41,7 +41,7 @@ FAIL= ${:!echo unexpected 1>&2!} # after the loop, when undefining the temporary global loop variable. # Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the # variable name. -# expect+2: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar +# expect+2: while evaluating "${:Uword:@${FAIL}@expr@}": In the :@ modifier, the variable name "${FAIL}" must not contain a dollar # expect+1: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@}) .if 0 && ${:Uword:@${FAIL}@expr@} .endif diff --git a/contrib/bmake/unit-tests/var-op-expand.exp b/contrib/bmake/unit-tests/var-op-expand.exp index 5ea4e6b6954c..0eafc9ae4c39 100644 --- a/contrib/bmake/unit-tests/var-op-expand.exp +++ b/contrib/bmake/unit-tests/var-op-expand.exp @@ -1,6 +1,6 @@ -make: "var-op-expand.mk" line 274: Unknown modifier "s,value,replaced," +make: "var-op-expand.mk" line 274: while evaluating variable "indirect": while evaluating variable "later": Unknown modifier "s,value,replaced," make: "var-op-expand.mk" line 278: warning: XXX Neither branch should be taken. -make: "var-op-expand.mk" line 283: Unknown modifier "s,value,replaced," +make: "var-op-expand.mk" line 283: while evaluating variable "indirect": while evaluating variable "later": Unknown modifier "s,value,replaced," make: "var-op-expand.mk" line 285: warning: XXX Neither branch should be taken. make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/var-op-expand.mk b/contrib/bmake/unit-tests/var-op-expand.mk index 76b90bf72b56..fb1e6d2c390f 100644 --- a/contrib/bmake/unit-tests/var-op-expand.mk +++ b/contrib/bmake/unit-tests/var-op-expand.mk @@ -1,4 +1,4 @@ -# $NetBSD: var-op-expand.mk,v 1.19 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: var-op-expand.mk,v 1.20 2024/04/20 10:18:55 rillig Exp $ # # Tests for the := variable assignment operator, which expands its # right-hand side. @@ -270,7 +270,7 @@ later= lowercase-value .undef later INDIRECT:= ${LATER:S,value,replaced,} OK ${LATER:value=sysv} indirect:= ${INDIRECT:tl} -# expect+1: Unknown modifier "s,value,replaced," +# expect+1: while evaluating variable "indirect": while evaluating variable "later": Unknown modifier "s,value,replaced," .if ${indirect} != " ok " . error .else @@ -279,7 +279,7 @@ indirect:= ${INDIRECT:tl} .endif LATER= uppercase-value later= lowercase-value -# expect+1: Unknown modifier "s,value,replaced," +# expect+1: while evaluating variable "indirect": while evaluating variable "later": Unknown modifier "s,value,replaced," .if ${indirect} != "uppercase-replaced ok uppercase-sysv" # expect+1: warning: XXX Neither branch should be taken. . warning XXX Neither branch should be taken. diff --git a/contrib/bmake/unit-tests/vardebug.exp b/contrib/bmake/unit-tests/vardebug.exp index a0aa6a301800..86f2ac0b420d 100644 --- a/contrib/bmake/unit-tests/vardebug.exp +++ b/contrib/bmake/unit-tests/vardebug.exp @@ -54,7 +54,7 @@ Var_Parse: ${:Uvariable:unknown} (eval-defined) Evaluating modifier ${:U...} on value "" (eval-defined, undefined) Result of ${:Uvariable} is "variable" (eval-defined, defined) Evaluating modifier ${:u...} on value "variable" (eval-defined, defined) -make: "vardebug.mk" line 63: Unknown modifier "unknown" +make: "vardebug.mk" line 63: while evaluating "${:Uvariable:unknown}": Unknown modifier "unknown" Result of ${:unknown} is error (eval-defined, defined) make: "vardebug.mk" line 63: Malformed conditional (${:Uvariable:unknown}) Var_Parse: ${UNDEFINED} (eval-defined) diff --git a/contrib/bmake/unit-tests/vardebug.mk b/contrib/bmake/unit-tests/vardebug.mk index b9b094772b54..6c5703cb526f 100644 --- a/contrib/bmake/unit-tests/vardebug.mk +++ b/contrib/bmake/unit-tests/vardebug.mk @@ -1,4 +1,4 @@ -# $NetBSD: vardebug.mk,v 1.9 2023/12/20 09:46:00 rillig Exp $ +# $NetBSD: vardebug.mk,v 1.10 2024/04/20 10:18:55 rillig Exp $ # # Demonstrates the debugging output for var.c. @@ -59,7 +59,7 @@ VAR+= 3 # as "is error", without surrounding quotes. # expect: Result of ${:unknown} is error (eval-defined, defined) # expect+2: Malformed conditional (${:Uvariable:unknown}) -# expect+1: Unknown modifier "unknown" +# expect+1: while evaluating "${:Uvariable:unknown}": Unknown modifier "unknown" .if ${:Uvariable:unknown} .endif diff --git a/contrib/bmake/unit-tests/varmisc.exp b/contrib/bmake/unit-tests/varmisc.exp index 61e6a49963a0..dd24a419fe75 100644 --- a/contrib/bmake/unit-tests/varmisc.exp +++ b/contrib/bmake/unit-tests/varmisc.exp @@ -44,26 +44,26 @@ parse-dynamic: parse-dynamic parse-dynamic before parse-dynamic: parse-dynamic parse-dynamic after parse-dynamic: parse-dynamic parse-dynamic after varerror-unclosed:begin -make: Unclosed variable "" +make: in target "varerror-unclosed": Unclosed variable "" -make: Unclosed variable "UNCLOSED" +make: in target "varerror-unclosed": Unclosed variable "UNCLOSED" -make: Unclosed variable "UNCLOSED" +make: in target "varerror-unclosed": Unclosed variable "UNCLOSED" -make: Unclosed variable "PATTERN" +make: in target "varerror-unclosed": while evaluating variable "UNCLOSED": Unclosed variable "PATTERN" make: Unclosed expression, expecting '}' for modifier "M${PATTERN" of variable "UNCLOSED" with value "" -make: Unclosed variable "param" -make: Unclosed variable "UNCLOSED." +make: in target "varerror-unclosed": Unclosed variable "param" +make: in target "varerror-unclosed": Unclosed variable "UNCLOSED." -make: Unclosed variable "UNCLOSED.1" +make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.1" -make: Unclosed variable "UNCLOSED.2" +make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.2" -make: Unclosed variable "UNCLOSED.3" +make: in target "varerror-unclosed": Unclosed variable "UNCLOSED.3" -make: Unclosed variable "UNCLOSED_ORIG" +make: in target "varerror-unclosed": while evaluating variable "UNCLOSED_INDIR_2": while evaluating variable "UNCLOSED_INDIR_1": Unclosed variable "UNCLOSED_ORIG" varerror-unclosed:end target1-flags: we have: one two diff --git a/contrib/bmake/unit-tests/varmod-assign.exp b/contrib/bmake/unit-tests/varmod-assign.exp index f258f92ea05b..db1fa64c8479 100644 --- a/contrib/bmake/unit-tests/varmod-assign.exp +++ b/contrib/bmake/unit-tests/varmod-assign.exp @@ -42,7 +42,7 @@ mod-assign-empty: value} make: Bad modifier ":" for variable "" mod-assign-empty: overwritten} mod-assign-empty: VAR=overwritten -make: Unknown modifier ":x" +make: in target "mod-assign-parse": while evaluating variable "ASSIGN": Unknown modifier ":x" sysv:y make: Unfinished modifier for "ASSIGN" ('}' missing) diff --git a/contrib/bmake/unit-tests/varmod-assign.mk b/contrib/bmake/unit-tests/varmod-assign.mk index f7112c47c935..17d9df764be1 100644 --- a/contrib/bmake/unit-tests/varmod-assign.mk +++ b/contrib/bmake/unit-tests/varmod-assign.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-assign.mk,v 1.19 2024/01/07 11:42:22 rillig Exp $ +# $NetBSD: varmod-assign.mk,v 1.20 2024/04/20 10:18:55 rillig Exp $ # # Tests for the obscure ::= variable modifiers, which perform variable # assignments during evaluation, just like the = operator in C. @@ -90,7 +90,7 @@ mod-assign-empty: mod-assign-parse: # The modifier for assignment operators starts with a ':'. # An 'x' after that is an invalid modifier. - # expect: make: Unknown modifier ":x" + # expect: make: in target "mod-assign-parse": while evaluating variable "ASSIGN": Unknown modifier ":x" @echo ${ASSIGN::x} # When parsing an assignment operator fails because the operator is diff --git a/contrib/bmake/unit-tests/varmod-edge.exp b/contrib/bmake/unit-tests/varmod-edge.exp index c2477f16e950..fad5cb2c3c94 100644 --- a/contrib/bmake/unit-tests/varmod-edge.exp +++ b/contrib/bmake/unit-tests/varmod-edge.exp @@ -15,10 +15,10 @@ make: "varmod-edge.mk" line 184: ok eq-bs make: Unfinished modifier for "INP.eq-esc" ('=' missing) make: "varmod-edge.mk" line 184: ok eq-esc make: "varmod-edge.mk" line 184: ok colon -make: "varmod-edge.mk" line 167: Unknown modifier ":" -make: "varmod-edge.mk" line 167: Unknown modifier ":" +make: "varmod-edge.mk" line 167: while evaluating variable "MOD.colons": while evaluating variable "INP.colons": Unknown modifier ":" +make: "varmod-edge.mk" line 167: while evaluating variable "MOD.colons": while evaluating variable "INP.colons": Unknown modifier ":" make: "varmod-edge.mk" line 184: ok colons -make: "varmod-edge.mk" line 195: Unknown modifier "Z" +make: "varmod-edge.mk" line 195: while evaluating "${:Z}": Unknown modifier "Z" make: "varmod-edge.mk" line 195: Malformed conditional (${:Z}) make: Unfinished modifier for "" (',' missing) make: "varmod-edge.mk" line 209: Malformed conditional (${:S,}) diff --git a/contrib/bmake/unit-tests/varmod-edge.mk b/contrib/bmake/unit-tests/varmod-edge.mk index 91220d99e47d..2f8f8c793de1 100644 --- a/contrib/bmake/unit-tests/varmod-edge.mk +++ b/contrib/bmake/unit-tests/varmod-edge.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-edge.mk,v 1.19 2023/11/19 22:06:15 rillig Exp $ +# $NetBSD: varmod-edge.mk,v 1.20 2024/04/20 10:18:55 rillig Exp $ # # Tests for edge cases in variable modifiers. # @@ -162,8 +162,8 @@ MOD.colons= ${INP.colons::::} EXP.colons= # empty .for test in ${TESTS} -# expect+2: Unknown modifier ":" -# expect+1: Unknown modifier ":" +# expect+2: while evaluating variable "MOD.colons": while evaluating variable "INP.colons": Unknown modifier ":" +# expect+1: while evaluating variable "MOD.colons": while evaluating variable "INP.colons": Unknown modifier ":" . if ${MOD.${test}} == ${EXP.${test}} # expect+16: ok M-paren # expect+15: ok M-mixed @@ -191,7 +191,7 @@ EXP.colons= # empty # XXX: The error message should mention the variable name of the expression, # even though that name is empty in this case. # expect+2: Malformed conditional (${:Z}) -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:Z}": Unknown modifier "Z" .if ${:Z} . error .else diff --git a/contrib/bmake/unit-tests/varmod-gmtime.exp b/contrib/bmake/unit-tests/varmod-gmtime.exp index bbb8bd547bd5..1b12ead96d85 100644 --- a/contrib/bmake/unit-tests/varmod-gmtime.exp +++ b/contrib/bmake/unit-tests/varmod-gmtime.exp @@ -1,12 +1,12 @@ -make: "varmod-gmtime.mk" line 61: Invalid time value "-1" +make: "varmod-gmtime.mk" line 61: while evaluating "${:L:gmtime=-1} != """: Invalid time value "-1" make: "varmod-gmtime.mk" line 61: Malformed conditional (${:L:gmtime=-1} != "") -make: "varmod-gmtime.mk" line 72: Invalid time value " 1" +make: "varmod-gmtime.mk" line 72: while evaluating "${:L:gmtime= 1} != """: Invalid time value " 1" make: "varmod-gmtime.mk" line 72: Malformed conditional (${:L:gmtime= 1} != "") -make: "varmod-gmtime.mk" line 120: Invalid time value "10000000000000000000000000000000" +make: "varmod-gmtime.mk" line 120: while evaluating "${:L:gmtime=10000000000000000000000000000000} != """: Invalid time value "10000000000000000000000000000000" make: "varmod-gmtime.mk" line 120: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "") -make: "varmod-gmtime.mk" line 133: Invalid time value "error" +make: "varmod-gmtime.mk" line 133: while evaluating "${:L:gmtime=error} != """: Invalid time value "error" make: "varmod-gmtime.mk" line 133: Malformed conditional (${:L:gmtime=error} != "") -make: "varmod-gmtime.mk" line 144: Invalid time value "100000S,1970,bad," +make: "varmod-gmtime.mk" line 144: while evaluating variable "%Y": Invalid time value "100000S,1970,bad," make: "varmod-gmtime.mk" line 144: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-gmtime.mk b/contrib/bmake/unit-tests/varmod-gmtime.mk index c30f5edbecc2..db24b1680c46 100644 --- a/contrib/bmake/unit-tests/varmod-gmtime.mk +++ b/contrib/bmake/unit-tests/varmod-gmtime.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-gmtime.mk,v 1.21 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: varmod-gmtime.mk,v 1.22 2024/04/20 10:18:55 rillig Exp $ # # Tests for the :gmtime variable modifier, which formats a timestamp # using strftime(3) in UTC. @@ -56,7 +56,7 @@ # 1970. Going back 50 years in the past is not a practical use case for # make. Therefore, since var.c 1.631, negative time stamps produce a # parse error. -# expect+2: Invalid time value "-1" +# expect+2: while evaluating "${:L:gmtime=-1} != """: Invalid time value "-1" # expect+1: Malformed conditional (${:L:gmtime=-1} != "") .if ${:L:gmtime=-1} != "" . error @@ -67,7 +67,7 @@ # Spaces were allowed before var.c 1.631 from 2020-10-31 21:40:20, not # because it would make sense but just as a side-effect from using strtoul. -# expect+2: Invalid time value " 1" +# expect+2: while evaluating "${:L:gmtime= 1} != """: Invalid time value " 1" # expect+1: Malformed conditional (${:L:gmtime= 1} != "") .if ${:L:gmtime= 1} != "" . error @@ -115,7 +115,7 @@ # # Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a # parse error. -# expect+2: Invalid time value "10000000000000000000000000000000" +# expect+2: while evaluating "${:L:gmtime=10000000000000000000000000000000} != """: Invalid time value "10000000000000000000000000000000" # expect+1: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "") .if ${:L:gmtime=10000000000000000000000000000000} != "" . error @@ -128,7 +128,7 @@ # stopped after the '=', and the remaining string was parsed for more variable # modifiers. Because of the unknown modifier 'e' from the 'error', the whole # variable value was discarded and thus not printed. -# expect+2: Invalid time value "error" +# expect+2: while evaluating "${:L:gmtime=error} != """: Invalid time value "error" # expect+1: Malformed conditional (${:L:gmtime=error} != "") .if ${:L:gmtime=error} != "" . error @@ -139,7 +139,7 @@ # Before var.c 1.1050 from 2023-05-09, the timestamp could be directly # followed by the next modifier, without a ':' separator. This was the same # bug as for the ':L' and ':P' modifiers. -# expect+2: Invalid time value "100000S,1970,bad," +# expect+2: while evaluating variable "%Y": Invalid time value "100000S,1970,bad," # expect+1: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad") .if ${%Y:L:gmtime=100000S,1970,bad,} != "bad" . error diff --git a/contrib/bmake/unit-tests/varmod-hash.exp b/contrib/bmake/unit-tests/varmod-hash.exp index 1286b456c6c2..e385c3b3ae11 100644 --- a/contrib/bmake/unit-tests/varmod-hash.exp +++ b/contrib/bmake/unit-tests/varmod-hash.exp @@ -1,9 +1,9 @@ -make: Unknown modifier "has" +make: in target "all": while evaluating variable "12345": Unknown modifier "has" 26bb0f5f 12345 -make: Unknown modifier "hasX" +make: in target "all": while evaluating variable "12345": Unknown modifier "hasX" -make: Unknown modifier "hashed" +make: in target "all": while evaluating variable "12345": Unknown modifier "hashed" exit status 0 diff --git a/contrib/bmake/unit-tests/varmod-ifelse.exp b/contrib/bmake/unit-tests/varmod-ifelse.exp index 653fe104ddaa..8b9d41bd2427 100644 --- a/contrib/bmake/unit-tests/varmod-ifelse.exp +++ b/contrib/bmake/unit-tests/varmod-ifelse.exp @@ -16,7 +16,7 @@ CondParser_Eval: ${VAR} == value Comparing "value" == "value" Comparing "ok" != "ok" make: "varmod-ifelse.mk" line 158: no. -make: "varmod-ifelse.mk" line 162: Comparison with '>=' requires both operands 'no' and '10' to be numeric +make: "varmod-ifelse.mk" line 162: while evaluating variable "string == "literal" || no >= 10": Comparison with '>=' requires both operands 'no' and '10' to be numeric make: Bad conditional expression 'string == "literal" || no >= 10' before '?yes:no' make: "varmod-ifelse.mk" line 162: . make: Bad conditional expression 'string == "literal" && >= 10' before '?yes:no' diff --git a/contrib/bmake/unit-tests/varmod-ifelse.mk b/contrib/bmake/unit-tests/varmod-ifelse.mk index 5c8b55d92717..3bf433027950 100644 --- a/contrib/bmake/unit-tests/varmod-ifelse.mk +++ b/contrib/bmake/unit-tests/varmod-ifelse.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-ifelse.mk,v 1.26 2023/12/10 20:12:28 rillig Exp $ +# $NetBSD: varmod-ifelse.mk,v 1.28 2024/04/23 22:51:28 rillig Exp $ # # Tests for the ${cond:?then:else} variable modifier, which evaluates either # the then-expression or the else-expression, depending on the condition. @@ -156,7 +156,7 @@ STRING= string NUMBER= no # not really a number # expect+1: no. .info ${${STRING} == "literal" && ${NUMBER} >= 10:?yes:no}. -# expect+3: Comparison with '>=' requires both operands 'no' and '10' to be numeric +# expect+3: while evaluating variable "string == "literal" || no >= 10": Comparison with '>=' requires both operands 'no' and '10' to be numeric # expect: make: Bad conditional expression 'string == "literal" || no >= 10' before '?yes:no' # expect+1: . .info ${${STRING} == "literal" || ${NUMBER} >= 10:?yes:no}. @@ -294,7 +294,7 @@ INDIRECT_COND2= $${DELAYED} == "two" # In the modifier parts for the 'then' and 'else' branches, subexpressions are -# parsed in by inspecting the actual modifiers. In 2008, 2015, 2020, 2022 and +# parsed by inspecting the actual modifiers. In 2008, 2015, 2020, 2022 and # 2023, the exact parsing algorithm switched a few times, counting balanced # braces instead of proper subexpressions, which meant that unbalanced braces # were parsed differently, depending on whether the branch was active or not. diff --git a/contrib/bmake/unit-tests/varmod-indirect.exp b/contrib/bmake/unit-tests/varmod-indirect.exp index ecf52033ee4b..376beb8edef9 100644 --- a/contrib/bmake/unit-tests/varmod-indirect.exp +++ b/contrib/bmake/unit-tests/varmod-indirect.exp @@ -1,5 +1,5 @@ -make: "varmod-indirect.mk" line 19: Unknown modifier "${" -make: "varmod-indirect.mk" line 52: Unknown modifier "${" +make: "varmod-indirect.mk" line 19: while evaluating variable "value": Unknown modifier "${" +make: "varmod-indirect.mk" line 52: while evaluating variable "value": Unknown modifier "${" make: "varmod-indirect.mk" line 54: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression. make: "varmod-indirect.mk" line 143: before make: "varmod-indirect.mk" line 143: after @@ -7,7 +7,7 @@ make: "varmod-indirect.mk" line 151: before make: "varmod-indirect.mk" line 151: after make: "varmod-indirect.mk" line 159: before make: "varmod-indirect.mk" line 159: after -make: "varmod-indirect.mk" line 164: Unknown modifier "Z" +make: "varmod-indirect.mk" line 164: while evaluating variable "UNDEF": Unknown modifier "Z" make: "varmod-indirect.mk" line 167: before make: "varmod-indirect.mk" line 167: after Parsing line 176: _:= before ${UNDEF} after @@ -31,7 +31,7 @@ Parsing line 195: _:= before ${UNDEF:${:UZ}} after Var_Parse: ${UNDEF:${:UZ}} after (eval-keep-dollar-and-undefined) Indirect modifier "Z" from "${:UZ}" Evaluating modifier ${UNDEF:Z} on value "" (eval-keep-dollar-and-undefined, undefined) -make: "varmod-indirect.mk" line 195: Unknown modifier "Z" +make: "varmod-indirect.mk" line 195: while evaluating variable "UNDEF": Unknown modifier "Z" Result of ${UNDEF:Z} is error (eval-keep-dollar-and-undefined, undefined) Global: _ = before ${UNDEF:Z} after Parsing line 197: .MAKEFLAGS: -d0 diff --git a/contrib/bmake/unit-tests/varmod-indirect.mk b/contrib/bmake/unit-tests/varmod-indirect.mk index 99e7215aa639..869231d47ebc 100644 --- a/contrib/bmake/unit-tests/varmod-indirect.mk +++ b/contrib/bmake/unit-tests/varmod-indirect.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-indirect.mk,v 1.18 2024/02/04 10:03:10 rillig Exp $ +# $NetBSD: varmod-indirect.mk,v 1.19 2024/04/20 10:18:55 rillig Exp $ # # Tests for indirect variable modifiers, such as in ${VAR:${M_modifiers}}. # These can be used for very basic purposes like converting a string to either @@ -15,7 +15,7 @@ # The following expression generates a parse error since its indirect # modifier contains more than a sole expression. # -# expect+1: Unknown modifier "${" +# expect+1: while evaluating variable "value": Unknown modifier "${" .if ${value:L:${:US}${:U,value,replacement,}} != "S,value,replacement,}" . warning unexpected .endif @@ -47,7 +47,7 @@ # error. Because of this parse error, this feature cannot be used reasonably # in practice. # -# expect+2: Unknown modifier "${" +# expect+2: while evaluating variable "value": Unknown modifier "${" #.MAKEFLAGS: -dvc .if ${value:L:${:UM*}S,value,replaced,} == "M*S,value,replaced,}" # expect+1: warning: FIXME: this expression should have resulted in a parse error rather than returning the unparsed portion of the expression. @@ -160,7 +160,7 @@ M_NoPrimes= ${PRIMES:${M_ListToSkip}} .endfor # An error in an indirect modifier. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating variable "UNDEF": Unknown modifier "Z" .for var in before ${UNDEF:${:UZ}} after # expect+2: before # expect+1: after @@ -191,7 +191,7 @@ _:= before ${UNDEF:${:U}} after # XXX: This expands to ${UNDEF:Z}, which will behave differently if the # variable '_' is used in a context where the expression ${_} is # parsed but not evaluated. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating variable "UNDEF": Unknown modifier "Z" _:= before ${UNDEF:${:UZ}} after .MAKEFLAGS: -d0 diff --git a/contrib/bmake/unit-tests/varmod-localtime.exp b/contrib/bmake/unit-tests/varmod-localtime.exp index a7c3ff6ab932..1bb547289edd 100644 --- a/contrib/bmake/unit-tests/varmod-localtime.exp +++ b/contrib/bmake/unit-tests/varmod-localtime.exp @@ -1,12 +1,12 @@ -make: "varmod-localtime.mk" line 61: Invalid time value "-1" +make: "varmod-localtime.mk" line 61: while evaluating "${:L:localtime=-1} != """: Invalid time value "-1" make: "varmod-localtime.mk" line 61: Malformed conditional (${:L:localtime=-1} != "") -make: "varmod-localtime.mk" line 72: Invalid time value " 1" +make: "varmod-localtime.mk" line 72: while evaluating "${:L:localtime= 1} != """: Invalid time value " 1" make: "varmod-localtime.mk" line 72: Malformed conditional (${:L:localtime= 1} != "") -make: "varmod-localtime.mk" line 120: Invalid time value "10000000000000000000000000000000" +make: "varmod-localtime.mk" line 120: while evaluating "${:L:localtime=10000000000000000000000000000000} != """: Invalid time value "10000000000000000000000000000000" make: "varmod-localtime.mk" line 120: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "") -make: "varmod-localtime.mk" line 133: Invalid time value "error" +make: "varmod-localtime.mk" line 133: while evaluating "${:L:localtime=error} != """: Invalid time value "error" make: "varmod-localtime.mk" line 133: Malformed conditional (${:L:localtime=error} != "") -make: "varmod-localtime.mk" line 144: Invalid time value "100000S,1970,bad," +make: "varmod-localtime.mk" line 144: while evaluating variable "%Y": Invalid time value "100000S,1970,bad," make: "varmod-localtime.mk" line 144: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-localtime.mk b/contrib/bmake/unit-tests/varmod-localtime.mk index f6fcc61a7fa6..233e556e0c77 100644 --- a/contrib/bmake/unit-tests/varmod-localtime.mk +++ b/contrib/bmake/unit-tests/varmod-localtime.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-localtime.mk,v 1.14 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: varmod-localtime.mk,v 1.15 2024/04/20 10:18:55 rillig Exp $ # # Tests for the :localtime variable modifier, which formats a timestamp # using strftime(3) in local time. @@ -56,7 +56,7 @@ # 1970. Going back 50 years in the past is not a practical use case for # make. Therefore, since var.c 1.631, negative time stamps produce a # parse error. -# expect+2: Invalid time value "-1" +# expect+2: while evaluating "${:L:localtime=-1} != """: Invalid time value "-1" # expect+1: Malformed conditional (${:L:localtime=-1} != "") .if ${:L:localtime=-1} != "" . error @@ -67,7 +67,7 @@ # Spaces were allowed before var.c 1.631 from 2020-10-31 21:40:20, not # because it would make sense but just as a side-effect from using strtoul. -# expect+2: Invalid time value " 1" +# expect+2: while evaluating "${:L:localtime= 1} != """: Invalid time value " 1" # expect+1: Malformed conditional (${:L:localtime= 1} != "") .if ${:L:localtime= 1} != "" . error @@ -115,7 +115,7 @@ # # Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a # parse error. -# expect+2: Invalid time value "10000000000000000000000000000000" +# expect+2: while evaluating "${:L:localtime=10000000000000000000000000000000} != """: Invalid time value "10000000000000000000000000000000" # expect+1: Malformed conditional (${:L:localtime=10000000000000000000000000000000} != "") .if ${:L:localtime=10000000000000000000000000000000} != "" . error @@ -128,7 +128,7 @@ # stopped after the '=', and the remaining string was parsed for more variable # modifiers. Because of the unknown modifier 'e' from the 'error', the whole # variable value was discarded and thus not printed. -# expect+2: Invalid time value "error" +# expect+2: while evaluating "${:L:localtime=error} != """: Invalid time value "error" # expect+1: Malformed conditional (${:L:localtime=error} != "") .if ${:L:localtime=error} != "" . error @@ -139,7 +139,7 @@ # Before var.c 1.1050 from 2023-05-09, the timestamp could be directly # followed by the next modifier, without a ':' separator. This was the same # bug as for the ':L' and ':P' modifiers. -# expect+2: Invalid time value "100000S,1970,bad," +# expect+2: while evaluating variable "%Y": Invalid time value "100000S,1970,bad," # expect+1: Malformed conditional (${%Y:L:localtime=100000S,1970,bad,} != "bad") .if ${%Y:L:localtime=100000S,1970,bad,} != "bad" . error diff --git a/contrib/bmake/unit-tests/varmod-loop-delete.exp b/contrib/bmake/unit-tests/varmod-loop-delete.exp index 47a2f74545a3..5c508a7a6420 100644 --- a/contrib/bmake/unit-tests/varmod-loop-delete.exp +++ b/contrib/bmake/unit-tests/varmod-loop-delete.exp @@ -1,4 +1,4 @@ -make: "varmod-loop-delete.mk" line 20: Cannot delete variable "VAR" while it is used +make: "varmod-loop-delete.mk" line 20: while evaluating variable "VAR": while evaluating "${:U:@VAR@@} rest of the value": Cannot delete variable "VAR" while it is used make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/varmod-loop-delete.mk b/contrib/bmake/unit-tests/varmod-loop-delete.mk index 1ec6d361949d..cf0611991194 100644 --- a/contrib/bmake/unit-tests/varmod-loop-delete.mk +++ b/contrib/bmake/unit-tests/varmod-loop-delete.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-loop-delete.mk,v 1.3 2023/06/01 20:56:35 rillig Exp $ +# $NetBSD: varmod-loop-delete.mk,v 1.4 2024/04/20 10:18:55 rillig Exp $ # # Tests for the variable modifier ':@', which as a side effect allows to # delete an arbitrary variable. @@ -16,7 +16,7 @@ VAR= ${:U:@VAR@@} rest of the value # In an assignment, the scope is 'Global'. Since the variable 'VAR' is # defined in the global scope, it deletes itself. -# expect+1: Cannot delete variable "VAR" while it is used +# expect+1: while evaluating variable "VAR": while evaluating "${:U:@VAR@@} rest of the value": Cannot delete variable "VAR" while it is used EVAL:= ${VAR} .if ${EVAL} != " rest of the value" . error diff --git a/contrib/bmake/unit-tests/varmod-loop-varname.exp b/contrib/bmake/unit-tests/varmod-loop-varname.exp index 2060b51c31df..cefd82093e29 100644 --- a/contrib/bmake/unit-tests/varmod-loop-varname.exp +++ b/contrib/bmake/unit-tests/varmod-loop-varname.exp @@ -1,10 +1,10 @@ -make: "varmod-loop-varname.mk" line 18: In the :@ modifier of "", the variable name "${:Ubar:S,b,v,}" must not contain a dollar +make: "varmod-loop-varname.mk" line 18: while evaluating "${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"": In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar make: "varmod-loop-varname.mk" line 18: Malformed conditional (${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+") -make: "varmod-loop-varname.mk" line 89: In the :@ modifier of "1 2 3", the variable name "v$" must not contain a dollar +make: "varmod-loop-varname.mk" line 89: while evaluating variable "1 2 3": In the :@ modifier, the variable name "v$" must not contain a dollar make: "varmod-loop-varname.mk" line 89: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)") -make: "varmod-loop-varname.mk" line 96: In the :@ modifier of "1 2 3", the variable name "v$$" must not contain a dollar +make: "varmod-loop-varname.mk" line 96: while evaluating variable "1 2 3": In the :@ modifier, the variable name "v$$" must not contain a dollar make: "varmod-loop-varname.mk" line 96: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()") -make: "varmod-loop-varname.mk" line 103: In the :@ modifier of "1 2 3", the variable name "v$$$" must not contain a dollar +make: "varmod-loop-varname.mk" line 103: while evaluating variable "1 2 3": In the :@ modifier, the variable name "v$$$" must not contain a dollar make: "varmod-loop-varname.mk" line 103: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-loop-varname.mk b/contrib/bmake/unit-tests/varmod-loop-varname.mk index 6f7436f277da..7abf8610911a 100644 --- a/contrib/bmake/unit-tests/varmod-loop-varname.mk +++ b/contrib/bmake/unit-tests/varmod-loop-varname.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-loop-varname.mk,v 1.6 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: varmod-loop-varname.mk,v 1.7 2024/04/20 10:18:55 rillig Exp $ # # Tests for the first part of the variable modifier ':@var@...@', which # contains the variable name to use during the loop. @@ -13,7 +13,7 @@ # dynamically. There was no practical use-case for this. # Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the # variable name. -# expect+2: In the :@ modifier of "", the variable name "${:Ubar:S,b,v,}" must not contain a dollar +# expect+2: while evaluating "${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+"": In the :@ modifier, the variable name "${:Ubar:S,b,v,}" must not contain a dollar # expect+1: Malformed conditional (${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+") .if ${:Uone two three:@${:Ubar:S,b,v,}@+${var}+@} != "+one+ +two+ +three+" . error @@ -84,21 +84,21 @@ RES3= 3 # There's no point in allowing a dollar sign in that position. # Since var.c 1.907 from 2021-04-04, a '$' is no longer allowed in the # variable name. -# expect+2: In the :@ modifier of "1 2 3", the variable name "v$" must not contain a dollar +# expect+2: while evaluating variable "1 2 3": In the :@ modifier, the variable name "v$" must not contain a dollar # expect+1: Malformed conditional (${1 2 3:L:@v$@($v)@} != "(1) (2) (3)") .if ${1 2 3:L:@v$@($v)@} != "(1) (2) (3)" . error .else . error .endif -# expect+2: In the :@ modifier of "1 2 3", the variable name "v$$" must not contain a dollar +# expect+2: while evaluating variable "1 2 3": In the :@ modifier, the variable name "v$$" must not contain a dollar # expect+1: Malformed conditional (${1 2 3:L:@v$$@($v)@} != "() () ()") .if ${1 2 3:L:@v$$@($v)@} != "() () ()" . error .else . error .endif -# expect+2: In the :@ modifier of "1 2 3", the variable name "v$$$" must not contain a dollar +# expect+2: while evaluating variable "1 2 3": In the :@ modifier, the variable name "v$$$" must not contain a dollar # expect+1: Malformed conditional (${1 2 3:L:@v$$$@($v)@} != "() () ()") .if ${1 2 3:L:@v$$$@($v)@} != "() () ()" . error diff --git a/contrib/bmake/unit-tests/varmod-loop.exp b/contrib/bmake/unit-tests/varmod-loop.exp index 356946f63a9b..6aef3fe86857 100644 --- a/contrib/bmake/unit-tests/varmod-loop.exp +++ b/contrib/bmake/unit-tests/varmod-loop.exp @@ -1,7 +1,9 @@ Parsing line 91: USE_8_DOLLARS= ${:U1:@var@${8_DOLLARS}@} ${8_DOLLARS} $$$$$$$$ +Parsing line 92: .if ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$" CondParser_Eval: ${USE_8_DOLLARS} != "\$\$\$\$ \$\$\$\$ \$\$\$\$" Comparing "$$$$ $$$$ $$$$" != "$$$$ $$$$ $$$$" Parsing line 96: SUBST_CONTAINING_LOOP:= ${USE_8_DOLLARS} +Parsing line 118: .if ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$" CondParser_Eval: ${SUBST_CONTAINING_LOOP} != "\$\$ \$\$\$\$ \$\$\$\$" Comparing "$$ $$$$ $$$$" != "$$ $$$$ $$$$" Parsing line 121: .MAKEFLAGS: -d0 diff --git a/contrib/bmake/unit-tests/varmod-match-escape.exp b/contrib/bmake/unit-tests/varmod-match-escape.exp index 9a8f9ccf6082..d6bd804a7e89 100755 --- a/contrib/bmake/unit-tests/varmod-match-escape.exp +++ b/contrib/bmake/unit-tests/varmod-match-escape.exp @@ -33,9 +33,9 @@ Comparing ":" != "::" make: "varmod-match-escape.mk" line 43: warning: XXX: Oops Global: .MAKEFLAGS = -r -k -d cv -d Global: .MAKEFLAGS = -r -k -d cv -d 0 -make: "varmod-match-escape.mk" line 69: Dollar followed by nothing -make: "varmod-match-escape.mk" line 110: warning: Unfinished character list in pattern '[A-]' of modifier ':M' -make: "varmod-match-escape.mk" line 110: warning: Unfinished character list in pattern '[^A-]' of modifier ':M' +make: "varmod-match-escape.mk" line 69: while evaluating "${:U\$:M\$} != """: Dollar followed by nothing +make: "varmod-match-escape.mk" line 110: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[A-]' of modifier ':M' +make: "varmod-match-escape.mk" line 110: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[^A-]' of modifier ':M' make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/varmod-match-escape.mk b/contrib/bmake/unit-tests/varmod-match-escape.mk index 1da3918fe1a5..d39ece1cba2c 100755 --- a/contrib/bmake/unit-tests/varmod-match-escape.mk +++ b/contrib/bmake/unit-tests/varmod-match-escape.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-match-escape.mk,v 1.12 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: varmod-match-escape.mk,v 1.13 2024/04/20 10:18:55 rillig Exp $ # # As of 2020-08-01, the :M and :N modifiers interpret backslashes differently, # depending on whether there was an expression somewhere before the @@ -65,7 +65,7 @@ VALUES= : :: :\: # In lint mode, the case of a lonely '$' is covered with an error message. .MAKEFLAGS: -dL -# expect+1: Dollar followed by nothing +# expect+1: while evaluating "${:U\$:M\$} != """: Dollar followed by nothing .if ${:U\$:M\$} != "" . error .endif @@ -105,8 +105,8 @@ EXP.[^A-]]= a EXP.[^A-]]]= a] .for pattern in [A-] [A-]] [A-]]] [^A-] [^A-]] [^A-]]] -# expect+2: warning: Unfinished character list in pattern '[A-]' of modifier ':M' -# expect+1: warning: Unfinished character list in pattern '[^A-]' of modifier ':M' +# expect+2: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[A-]' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[^A-]' of modifier ':M' . if ${WORDS:M${pattern}} != ${EXP.${pattern}} . warning ${pattern}: ${WORDS:M${pattern}} != ${EXP.${pattern}} . endif diff --git a/contrib/bmake/unit-tests/varmod-match.exp b/contrib/bmake/unit-tests/varmod-match.exp index e4e0783a7b15..3425eae2d421 100644 --- a/contrib/bmake/unit-tests/varmod-match.exp +++ b/contrib/bmake/unit-tests/varmod-match.exp @@ -1,14 +1,14 @@ -make: "varmod-match.mk" line 289: warning: Unfinished character list in pattern 'a[' of modifier ':M' -make: "varmod-match.mk" line 297: warning: Unfinished character list in pattern 'a[^' of modifier ':M' -make: "varmod-match.mk" line 305: warning: Unfinished character list in pattern '[-x1-3' of modifier ':M' -make: "varmod-match.mk" line 313: warning: Unfinished character list in pattern '*[-x1-3' of modifier ':M' -make: "varmod-match.mk" line 322: warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M' -make: "varmod-match.mk" line 336: warning: Unfinished character list in pattern '?[\' of modifier ':M' -make: "varmod-match.mk" line 344: warning: Unfinished character range in pattern '[x-' of modifier ':M' -make: "varmod-match.mk" line 356: warning: Unfinished character range in pattern '[^x-' of modifier ':M' -make: "varmod-match.mk" line 364: warning: Unfinished character list in pattern '[' of modifier ':M' -make: "varmod-match.mk" line 364: Unknown modifier "]" -make: "varmod-match.mk" line 364: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":") +make: "varmod-match.mk" line 290: while evaluating variable "WORDS": warning: Unfinished character list in pattern 'a[' of modifier ':M' +make: "varmod-match.mk" line 298: while evaluating variable "WORDS": warning: Unfinished character list in pattern 'a[^' of modifier ':M' +make: "varmod-match.mk" line 306: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[-x1-3' of modifier ':M' +make: "varmod-match.mk" line 314: while evaluating variable "WORDS": warning: Unfinished character list in pattern '*[-x1-3' of modifier ':M' +make: "varmod-match.mk" line 323: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M' +make: "varmod-match.mk" line 337: while evaluating variable "WORDS": warning: Unfinished character list in pattern '?[\' of modifier ':M' +make: "varmod-match.mk" line 345: while evaluating variable "WORDS": warning: Unfinished character range in pattern '[x-' of modifier ':M' +make: "varmod-match.mk" line 357: while evaluating variable "WORDS": warning: Unfinished character range in pattern '[^x-' of modifier ':M' +make: "varmod-match.mk" line 365: while evaluating variable " : :: ": warning: Unfinished character list in pattern '[' of modifier ':M' +make: "varmod-match.mk" line 365: while evaluating variable " : :: ": Unknown modifier "]" +make: "varmod-match.mk" line 365: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/contrib/bmake/unit-tests/varmod-match.mk b/contrib/bmake/unit-tests/varmod-match.mk index d93d1839192d..e91ddc7ce04b 100644 --- a/contrib/bmake/unit-tests/varmod-match.mk +++ b/contrib/bmake/unit-tests/varmod-match.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-match.mk,v 1.20 2023/12/17 23:19:02 rillig Exp $ +# $NetBSD: varmod-match.mk,v 1.22 2024/04/23 22:51:28 rillig Exp $ # # Tests for the ':M' modifier, which keeps only those words that match the # given pattern. @@ -33,22 +33,22 @@ # The pattern character '?' matches exactly 1 character, the pattern character # '*' matches 0 or more characters. The whole pattern matches all words that # start with 's' and have 3 or more characters. -.if ${One Two Three Four five six seven:L:Ms??*} != "six seven" +.if ${One Two Three Four five six seven so s:L:Ms??*} != "six seven" . error .endif -# Ensure that a pattern without placeholders only matches itself. +# A pattern without placeholders only matches itself. .if ${a aa aaa b ba baa bab:L:Ma} != "a" . error .endif -# Ensure that a pattern that ends with '*' is properly anchored at the +# A pattern that ends with '*' is anchored at the # beginning. .if ${a aa aaa b ba baa bab:L:Ma*} != "a aa aaa" . error .endif -# Ensure that a pattern that starts with '*' is properly anchored at the end. +# A pattern that starts with '*' is anchored at the end. .if ${a aa aaa b ba baa bab:L:M*a} != "a aa aaa ba baa" . error .endif @@ -257,8 +257,9 @@ ${:U*}= asterisk . error .endif -# Without the modifier ':tW', the string is split into words. All whitespace -# around and between the words is normalized to a single space. +# Without the modifier ':tW', the string is split into words. Whitespace +# around the words is discarded, and whitespace between the words is +# normalized to a single space. .if ${ plain string :L:M*} != "plain string" . error .endif @@ -285,7 +286,7 @@ ${:U*}= asterisk # [ Incomplete empty character list, never matches. WORDS= a a[ -# expect+1: warning: Unfinished character list in pattern 'a[' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern 'a[' of modifier ':M' .if ${WORDS:Ma[} != "" . error .endif @@ -293,7 +294,7 @@ WORDS= a a[ # [^ Incomplete negated empty character list, matches any single # character. WORDS= a a[ aX -# expect+1: warning: Unfinished character list in pattern 'a[^' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern 'a[^' of modifier ':M' .if ${WORDS:Ma[^} != "a[ aX" . error .endif @@ -301,7 +302,7 @@ WORDS= a a[ aX # [-x1-3 Incomplete character list, matches those elements that can be # parsed without lookahead. WORDS= - + x xx 0 1 2 3 4 [x1-3 -# expect+1: warning: Unfinished character list in pattern '[-x1-3' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[-x1-3' of modifier ':M' .if ${WORDS:M[-x1-3} != "- x 1 2 3" . error .endif @@ -309,7 +310,7 @@ WORDS= - + x xx 0 1 2 3 4 [x1-3 # *[-x1-3 Incomplete character list after a wildcard, matches those # words that end with one of the characters from the list. WORDS= - + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3 -# expect+1: warning: Unfinished character list in pattern '*[-x1-3' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern '*[-x1-3' of modifier ':M' .if ${WORDS:M*[-x1-3} != "- x xx 1 2 3 01 11 001 011 101 111 [x1-3" . warning ${WORDS:M*[-x1-3} .endif @@ -318,7 +319,7 @@ WORDS= - + x xx 0 1 2 3 4 00 01 10 11 000 001 010 011 100 101 110 111 [x1-3 # Incomplete negated character list, matches any character # except those elements that can be parsed without lookahead. WORDS= - + x xx 0 1 2 3 4 [x1-3 -# expect+1: warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M' .if ${WORDS:M[^-x1-3} != "+ 0 4" . error .endif @@ -332,7 +333,7 @@ WORDS= - + x xx 0 1 2 3 4 [x1-3 # '\', as there is no following space that could be escaped. WORDS= \\ \a ${:Ux\\} PATTERN= ${:U?[\\} -# expect+1: warning: Unfinished character list in pattern '?[\' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character list in pattern '?[\' of modifier ':M' .if ${WORDS:M${PATTERN}} != "\\\\ x\\" . error .endif @@ -340,7 +341,7 @@ PATTERN= ${:U?[\\} # [x- Incomplete character list containing an incomplete character # range, matches only the 'x'. WORDS= [x- x x- y -# expect+1: warning: Unfinished character range in pattern '[x-' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character range in pattern '[x-' of modifier ':M' .if ${WORDS:M[x-} != "x" . error .endif @@ -352,14 +353,14 @@ WORDS= [x- x x- y # XXX: Even matches strings that are longer than a single # character. WORDS= [x- x x- y yyyyy -# expect+1: warning: Unfinished character range in pattern '[^x-' of modifier ':M' +# expect+1: while evaluating variable "WORDS": warning: Unfinished character range in pattern '[^x-' of modifier ':M' .if ${WORDS:M[^x-} != "[x- y yyyyy" . error .endif # [:] matches never since the ':' starts the next modifier -# expect+3: warning: Unfinished character list in pattern '[' of modifier ':M' -# expect+2: Unknown modifier "]" +# expect+3: while evaluating variable " : :: ": warning: Unfinished character list in pattern '[' of modifier ':M' +# expect+2: while evaluating variable " : :: ": Unknown modifier "]" # expect+1: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":") .if ${ ${:U\:} ${:U\:\:} :L:M[:]} != ":" . error @@ -372,9 +373,16 @@ WORDS= [x- x x- y yyyyy # Before var.c 1.1031 from 2022-08-24, the following expressions caused an # out-of-bounds read beyond the indirect ':M' modifiers. -.if ${:U:${:UM\\}} # The ':M' pattern need not be unescaped, the -. error # resulting pattern is '\', it never matches -.endif # anything. -.if ${:U:${:UM\\\:\\}} # The ':M' pattern must be unescaped, the -. error # resulting pattern is ':\', it never matches -.endif # anything. +# +# The argument to the inner ':U' is unescaped to 'M\'. +# This 'M\' becomes an # indirect modifier ':M' with the pattern '\'. +# The pattern '\' never matches. +.if ${:U:${:UM\\}} +. error +.endif +# The argument to the inner ':U' is unescaped to 'M\:\'. +# This 'M\:\' becomes an indirect modifier ':M' with the pattern ':\'. +# The pattern ':\' never matches. +.if ${:U:${:UM\\\:\\}} +. error +.endif diff --git a/contrib/bmake/unit-tests/varmod-mtime.exp b/contrib/bmake/unit-tests/varmod-mtime.exp index 039173feddc3..87f405573437 100644 --- a/contrib/bmake/unit-tests/varmod-mtime.exp +++ b/contrib/bmake/unit-tests/varmod-mtime.exp @@ -1,13 +1,13 @@ -make: "varmod-mtime.mk" line 47: Invalid argument '123x' for modifier ':mtime' +make: "varmod-mtime.mk" line 47: while evaluating variable "no/such/file": Invalid argument '123x' for modifier ':mtime' make: "varmod-mtime.mk" line 47: Malformed conditional (${no/such/file:L:mtime=123x}) -make: "varmod-mtime.mk" line 70: Cannot determine mtime for 'no/such/file1': <ENOENT> -make: "varmod-mtime.mk" line 70: Cannot determine mtime for 'no/such/file2': <ENOENT> +make: "varmod-mtime.mk" line 70: while evaluating variable "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file1': <ENOENT> +make: "varmod-mtime.mk" line 70: while evaluating variable "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file2': <ENOENT> make: "varmod-mtime.mk" line 70: Malformed conditional (${no/such/file1 no/such/file2:L:mtime=error}) -make: "varmod-mtime.mk" line 81: Invalid argument 'errorhandler-no' for modifier ':mtime' +make: "varmod-mtime.mk" line 81: while evaluating variable "MAKEFILE": Invalid argument 'errorhandler-no' for modifier ':mtime' make: "varmod-mtime.mk" line 81: Malformed conditional (${MAKEFILE:mtime=errorhandler-no} > 0) -make: "varmod-mtime.mk" line 90: Invalid argument 'warn' for modifier ':mtime' +make: "varmod-mtime.mk" line 90: while evaluating variable "MAKEFILE": Invalid argument 'warn' for modifier ':mtime' make: "varmod-mtime.mk" line 90: Malformed conditional (${MAKEFILE:mtime=warn} > 0) -make: "varmod-mtime.mk" line 115: Unknown modifier "mtim" +make: "varmod-mtime.mk" line 115: while evaluating variable "anything": Unknown modifier "mtim" make: "varmod-mtime.mk" line 115: Malformed conditional (${anything:L:mtim}) make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-mtime.mk b/contrib/bmake/unit-tests/varmod-mtime.mk index 298756e152c1..189bb8cadc9a 100644 --- a/contrib/bmake/unit-tests/varmod-mtime.mk +++ b/contrib/bmake/unit-tests/varmod-mtime.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-mtime.mk,v 1.9 2023/12/17 14:07:22 rillig Exp $ +# $NetBSD: varmod-mtime.mk,v 1.10 2024/04/20 10:18:55 rillig Exp $ # # Tests for the ':mtime' variable modifier, which maps each word of the # expression to that file's modification time. @@ -42,7 +42,7 @@ not_found_mtime:= ${no/such/file:L:mtime} # The fallback timestamp must only be an integer, without trailing characters. -# expect+2: Invalid argument '123x' for modifier ':mtime' +# expect+2: while evaluating variable "no/such/file": Invalid argument '123x' for modifier ':mtime' # expect+1: Malformed conditional (${no/such/file:L:mtime=123x}) .if ${no/such/file:L:mtime=123x} . error @@ -64,8 +64,8 @@ _!= rm -f ${COOKIE} # If the optional argument of the ':mtime' modifier is the word 'error', the # modifier fails with an error message, once for each affected file. # -# expect+3: Cannot determine mtime for 'no/such/file1': <ENOENT> -# expect+2: Cannot determine mtime for 'no/such/file2': <ENOENT> +# expect+3: while evaluating variable "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file1': <ENOENT> +# expect+2: while evaluating variable "no/such/file1 no/such/file2": Cannot determine mtime for 'no/such/file2': <ENOENT> # expect+1: Malformed conditional (${no/such/file1 no/such/file2:L:mtime=error}) .if ${no/such/file1 no/such/file2:L:mtime=error} . error @@ -76,7 +76,7 @@ _!= rm -f ${COOKIE} # Only the word 'error' is a special argument to the ':mtime' modifier, all # other words result in a parse error. -# expect+2: Invalid argument 'errorhandler-no' for modifier ':mtime' +# expect+2: while evaluating variable "MAKEFILE": Invalid argument 'errorhandler-no' for modifier ':mtime' # expect+1: Malformed conditional (${MAKEFILE:mtime=errorhandler-no} > 0) .if ${MAKEFILE:mtime=errorhandler-no} > 0 .else @@ -85,7 +85,7 @@ _!= rm -f ${COOKIE} # Only the word 'error' can be used as a fallback argument to the modifier. -# expect+2: Invalid argument 'warn' for modifier ':mtime' +# expect+2: while evaluating variable "MAKEFILE": Invalid argument 'warn' for modifier ':mtime' # expect+1: Malformed conditional (${MAKEFILE:mtime=warn} > 0) .if ${MAKEFILE:mtime=warn} > 0 . error @@ -110,7 +110,7 @@ end:= ${%s:L:gmtime} # If there is a typo in the modifier name, it does not match. -# expect+2: Unknown modifier "mtim" +# expect+2: while evaluating variable "anything": Unknown modifier "mtim" # expect+1: Malformed conditional (${anything:L:mtim}) .if ${anything:L:mtim} . error diff --git a/contrib/bmake/unit-tests/varmod-range.exp b/contrib/bmake/unit-tests/varmod-range.exp index 9b0dad40a78e..d9848c2ef4f6 100644 --- a/contrib/bmake/unit-tests/varmod-range.exp +++ b/contrib/bmake/unit-tests/varmod-range.exp @@ -1,13 +1,13 @@ make: "varmod-range.mk" line 43: Malformed conditional (${:range=5} != "") -make: "varmod-range.mk" line 67: Invalid number "x}Rest" != "Rest"" for ':range' modifier +make: "varmod-range.mk" line 67: while evaluating "${:U:range=x}Rest" != "Rest"": Invalid number "x}Rest" != "Rest"" for ':range' modifier make: "varmod-range.mk" line 67: Malformed conditional ("${:U:range=x}Rest" != "Rest") -make: "varmod-range.mk" line 78: Unknown modifier "x0" +make: "varmod-range.mk" line 78: while evaluating "${:U:range=0x0}Rest" != "Rest"": Unknown modifier "x0" make: "varmod-range.mk" line 78: Malformed conditional ("${:U:range=0x0}Rest" != "Rest") -make: "varmod-range.mk" line 96: Unknown modifier "rang" +make: "varmod-range.mk" line 96: while evaluating variable "a b c": Unknown modifier "rang" make: "varmod-range.mk" line 96: Malformed conditional ("${a b c:L:rang}Rest" != "Rest") -make: "varmod-range.mk" line 105: Unknown modifier "rango" +make: "varmod-range.mk" line 105: while evaluating variable "a b c": Unknown modifier "rango" make: "varmod-range.mk" line 105: Malformed conditional ("${a b c:L:rango}Rest" != "Rest") -make: "varmod-range.mk" line 114: Unknown modifier "ranger" +make: "varmod-range.mk" line 114: while evaluating variable "a b c": Unknown modifier "ranger" make: "varmod-range.mk" line 114: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest") make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-range.mk b/contrib/bmake/unit-tests/varmod-range.mk index 920001096054..2915100bfb79 100644 --- a/contrib/bmake/unit-tests/varmod-range.mk +++ b/contrib/bmake/unit-tests/varmod-range.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-range.mk,v 1.10 2023/12/17 14:07:22 rillig Exp $ +# $NetBSD: varmod-range.mk,v 1.11 2024/04/20 10:18:55 rillig Exp $ # # Tests for the :range variable modifier, which generates sequences # of integers from the given range. @@ -62,7 +62,7 @@ # # Since 2020-11-01, the parser issues a more precise "Invalid number" error # instead. -# expect+2: Invalid number "x}Rest" != "Rest"" for ':range' modifier +# expect+2: while evaluating "${:U:range=x}Rest" != "Rest"": Invalid number "x}Rest" != "Rest"" for ':range' modifier # expect+1: Malformed conditional ("${:U:range=x}Rest" != "Rest") .if "${:U:range=x}Rest" != "Rest" . error @@ -73,7 +73,7 @@ # The upper limit of the range must always be given in decimal. # This parse error stops at the 'x', trying to parse it as a variable # modifier. -# expect+2: Unknown modifier "x0" +# expect+2: while evaluating "${:U:range=0x0}Rest" != "Rest"": Unknown modifier "x0" # expect+1: Malformed conditional ("${:U:range=0x0}Rest" != "Rest") .if "${:U:range=0x0}Rest" != "Rest" . error @@ -91,7 +91,7 @@ #.endif # modifier name too short -# expect+2: Unknown modifier "rang" +# expect+2: while evaluating variable "a b c": Unknown modifier "rang" # expect+1: Malformed conditional ("${a b c:L:rang}Rest" != "Rest") .if "${a b c:L:rang}Rest" != "Rest" . error @@ -100,7 +100,7 @@ .endif # misspelled modifier name -# expect+2: Unknown modifier "rango" +# expect+2: while evaluating variable "a b c": Unknown modifier "rango" # expect+1: Malformed conditional ("${a b c:L:rango}Rest" != "Rest") .if "${a b c:L:rango}Rest" != "Rest" . error @@ -109,7 +109,7 @@ .endif # modifier name too long -# expect+2: Unknown modifier "ranger" +# expect+2: while evaluating variable "a b c": Unknown modifier "ranger" # expect+1: Malformed conditional ("${a b c:L:ranger}Rest" != "Rest") .if "${a b c:L:ranger}Rest" != "Rest" . error diff --git a/contrib/bmake/unit-tests/varmod-subst-regex.exp b/contrib/bmake/unit-tests/varmod-subst-regex.exp index a09046ef764c..25626ba18508 100644 --- a/contrib/bmake/unit-tests/varmod-subst-regex.exp +++ b/contrib/bmake/unit-tests/varmod-subst-regex.exp @@ -20,7 +20,7 @@ mod-regex-limits:22-ok:1 33 556 mod-regex-limits:capture:ihgfedcbaabcdefghijABCDEFGHIJa0a1a2rest make: Regex compilation error: (details omitted) mod-regex-errors: -make: Unknown modifier "Z" +make: in target "mod-regex-errors": while evaluating variable "word": while evaluating "${:U:Z}y,W}": Unknown modifier "Z" mod-regex-errors: xy unmatched-subexpression.ok: one one 2 3 5 8 one3 2one 34 make: No match for subexpression \2 diff --git a/contrib/bmake/unit-tests/varmod-subst.exp b/contrib/bmake/unit-tests/varmod-subst.exp index 97fa2e4f1491..9d88b3d6fa6f 100644 --- a/contrib/bmake/unit-tests/varmod-subst.exp +++ b/contrib/bmake/unit-tests/varmod-subst.exp @@ -45,7 +45,7 @@ mod-subst-delimiter: 1 two 3 tilde mod-subst-chain: A B c. -make: Unknown modifier "i" +make: in target "mod-subst-chain": while evaluating "${:Uvalue:S,a,x,i}.": Unknown modifier "i" . mod-subst-dollar:$1: mod-subst-dollar:$2: diff --git a/contrib/bmake/unit-tests/varmod-to-separator.exp b/contrib/bmake/unit-tests/varmod-to-separator.exp index a7d4ddb20147..6bdd6f0c2d43 100644 --- a/contrib/bmake/unit-tests/varmod-to-separator.exp +++ b/contrib/bmake/unit-tests/varmod-to-separator.exp @@ -1,6 +1,6 @@ -make: "varmod-to-separator.mk" line 155: Invalid character number at "400:tu}" +make: "varmod-to-separator.mk" line 155: while evaluating variable "WORDS": Invalid character number at "400:tu}" make: "varmod-to-separator.mk" line 155: Malformed conditional (${WORDS:[1..3]:ts\400:tu}) -make: "varmod-to-separator.mk" line 171: Invalid character number at "100:tu}" +make: "varmod-to-separator.mk" line 171: while evaluating variable "WORDS": Invalid character number at "100:tu}" make: "varmod-to-separator.mk" line 171: Malformed conditional (${WORDS:[1..3]:ts\x100:tu}) make: Bad modifier ":ts\-300" for variable "WORDS" make: "varmod-to-separator.mk" line 179: Malformed conditional (${WORDS:[1..3]:ts\-300:tu}) @@ -18,7 +18,7 @@ make: Bad modifier ":t\X" for variable "WORDS" make: "varmod-to-separator.mk" line 232: Malformed conditional (${WORDS:t\X} != "anything") make: Bad modifier ":ts\69" for variable "" make: "varmod-to-separator.mk" line 249: Malformed conditional (${:Ua b:ts\69}) -make: "varmod-to-separator.mk" line 258: Invalid character number at "1F60E}" +make: "varmod-to-separator.mk" line 258: while evaluating "${:Ua b:ts\x1F60E}": Invalid character number at "1F60E}" make: "varmod-to-separator.mk" line 258: Malformed conditional (${:Ua b:ts\x1F60E}) make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod-to-separator.mk b/contrib/bmake/unit-tests/varmod-to-separator.mk index 57a7bd84ec44..8b8aeb4d3c33 100644 --- a/contrib/bmake/unit-tests/varmod-to-separator.mk +++ b/contrib/bmake/unit-tests/varmod-to-separator.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod-to-separator.mk,v 1.13 2023/11/19 21:47:52 rillig Exp $ +# $NetBSD: varmod-to-separator.mk,v 1.14 2024/04/20 10:18:55 rillig Exp $ # # Tests for the :ts variable modifier, which joins the words of the variable # using an arbitrary character as word separator. @@ -150,7 +150,7 @@ WORDS= one two three four five six # for an unsigned character though. # # Since 2020-11-01, these out-of-bounds values are rejected. -# expect+2: Invalid character number at "400:tu}" +# expect+2: while evaluating variable "WORDS": Invalid character number at "400:tu}" # expect+1: Malformed conditional (${WORDS:[1..3]:ts\400:tu}) .if ${WORDS:[1..3]:ts\400:tu} . warning The separator \400 is accepted even though it is out of bounds. @@ -166,7 +166,7 @@ WORDS= one two three four five six # The hexadecimal number must be in the range of an unsigned char. # # Since 2020-11-01, these out-of-bounds values are rejected. -# expect+2: Invalid character number at "100:tu}" +# expect+2: while evaluating variable "WORDS": Invalid character number at "100:tu}" # expect+1: Malformed conditional (${WORDS:[1..3]:ts\x100:tu}) .if ${WORDS:[1..3]:ts\x100:tu} . warning The separator \x100 is accepted even though it is out of bounds. @@ -253,7 +253,7 @@ WORDS= one two three four five six .endif # Try whether bmake is Unicode-ready. -# expect+2: Invalid character number at "1F60E}" +# expect+2: while evaluating "${:Ua b:ts\x1F60E}": Invalid character number at "1F60E}" # expect+1: Malformed conditional (${:Ua b:ts\x1F60E}) .if ${:Ua b:ts\x1F60E} # U+1F60E "smiling face with sunglasses" . error diff --git a/contrib/bmake/unit-tests/varmod.exp b/contrib/bmake/unit-tests/varmod.exp index 9ba0cb1d278b..22a7019dfc1a 100644 --- a/contrib/bmake/unit-tests/varmod.exp +++ b/contrib/bmake/unit-tests/varmod.exp @@ -1,7 +1,7 @@ make: "varmod.mk" line 101: To escape a dollar, use \$, not $$, at "$$:L} != """ make: "varmod.mk" line 101: Invalid variable name ':', at "$:L} != """ -make: "varmod.mk" line 107: Dollar followed by nothing -make: "varmod.mk" line 117: Missing delimiter ':' after modifier "P" +make: "varmod.mk" line 107: while evaluating "${:Uword:@word@${word}$@} != "word"": Dollar followed by nothing +make: "varmod.mk" line 117: while evaluating variable "VAR": Missing delimiter ':' after modifier "P" make: "varmod.mk" line 119: Missing argument for ".error" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests diff --git a/contrib/bmake/unit-tests/varmod.mk b/contrib/bmake/unit-tests/varmod.mk index 45707ab9b886..c749dfb9659d 100644 --- a/contrib/bmake/unit-tests/varmod.mk +++ b/contrib/bmake/unit-tests/varmod.mk @@ -1,4 +1,4 @@ -# $NetBSD: varmod.mk,v 1.10 2024/02/03 00:20:23 sjg Exp $ +# $NetBSD: varmod.mk,v 1.11 2024/04/20 10:18:56 rillig Exp $ # # Tests for variable modifiers, such as :Q, :S,from,to or :Ufallback. # @@ -103,7 +103,7 @@ DOLLAR2= ${:U\$} .endif # A '$' followed by nothing is an error as well. -# expect+1: Dollar followed by nothing +# expect+1: while evaluating "${:Uword:@word@${word}$@} != "word"": Dollar followed by nothing .if ${:Uword:@word@${word}$@} != "word" . error .endif @@ -113,7 +113,7 @@ DOLLAR2= ${:U\$} # XXX: The .error should not be reached since the expression is # malformed, and this error should be propagated up to Cond_EvalLine. VAR= STOP -# expect+1: Missing delimiter ':' after modifier "P" +# expect+1: while evaluating variable "VAR": Missing delimiter ':' after modifier "P" .if ${VAR:P=RE} != "STORE" # expect+1: Missing argument for ".error" . error diff --git a/contrib/bmake/unit-tests/varname-dot-shell.exp b/contrib/bmake/unit-tests/varname-dot-shell.exp index 22c2afe218a9..7d481fdf6ff1 100755 --- a/contrib/bmake/unit-tests/varname-dot-shell.exp +++ b/contrib/bmake/unit-tests/varname-dot-shell.exp @@ -6,6 +6,7 @@ Command: .SHELL = (details omitted) Global: ORIG_SHELL = (details omitted) Parsing line 12: .SHELL= overwritten Global: ignoring '.SHELL = overwritten' due to a command line variable of the same name +Parsing line 13: .if ${.SHELL} != ${ORIG_SHELL} CondParser_Eval: ${.SHELL} != ${ORIG_SHELL} Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined) Var_Parse: ${ORIG_SHELL} (eval-defined) @@ -13,6 +14,7 @@ Comparing "(details omitted)" != "(details omitted)" Parsing line 19: .MAKEFLAGS: .SHELL+=appended ParseDependency(.MAKEFLAGS: .SHELL+=appended) Command: ignoring '.SHELL += appended' as it is read-only +Parsing line 20: .if ${.SHELL} != ${ORIG_SHELL} CondParser_Eval: ${.SHELL} != ${ORIG_SHELL} Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined) Var_Parse: ${ORIG_SHELL} (eval-defined) @@ -21,6 +23,7 @@ Parsing line 27: .undef .SHELL Global: ignoring delete '.SHELL' as it is not found Parsing line 28: .SHELL= newly overwritten Global: ignoring '.SHELL = newly overwritten' due to a command line variable of the same name +Parsing line 29: .if ${.SHELL} != ${ORIG_SHELL} CondParser_Eval: ${.SHELL} != ${ORIG_SHELL} Var_Parse: ${.SHELL} != ${ORIG_SHELL} (eval-defined) Var_Parse: ${ORIG_SHELL} (eval-defined) diff --git a/contrib/bmake/unit-tests/varparse-errors.exp b/contrib/bmake/unit-tests/varparse-errors.exp index 4193bea181c9..20fee23bddae 100644 --- a/contrib/bmake/unit-tests/varparse-errors.exp +++ b/contrib/bmake/unit-tests/varparse-errors.exp @@ -1,5 +1,5 @@ -make: "varparse-errors.mk" line 38: Unknown modifier "Z" -make: "varparse-errors.mk" line 47: Unknown modifier "Z" +make: "varparse-errors.mk" line 38: while evaluating "${:U:Z}": Unknown modifier "Z" +make: "varparse-errors.mk" line 47: while evaluating "${:U:Z}post": Unknown modifier "Z" make: Bad modifier ":OX" for variable "" make: "varparse-errors.mk" line 71: Undefined variable "${:U:OX" make: Bad modifier ":OX" for variable "" diff --git a/contrib/bmake/unit-tests/varparse-errors.mk b/contrib/bmake/unit-tests/varparse-errors.mk index fc94d9dd3d18..edb02ef0b957 100644 --- a/contrib/bmake/unit-tests/varparse-errors.mk +++ b/contrib/bmake/unit-tests/varparse-errors.mk @@ -1,4 +1,4 @@ -# $NetBSD: varparse-errors.mk,v 1.11 2023/11/19 22:32:44 rillig Exp $ +# $NetBSD: varparse-errors.mk,v 1.12 2024/04/20 10:18:56 rillig Exp $ # Tests for parsing and evaluating all kinds of expressions. # @@ -34,7 +34,7 @@ ERR_EVAL= An evaluation error ${:Uvalue:C,.,\3,}. # As of 2020-12-01, errors in the variable name are silently ignored. # Since var.c 1.754 from 2020-12-20, unknown modifiers at parse time result # in an error message and a non-zero exit status. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:U:Z}": Unknown modifier "Z" VAR.${:U:Z}= unknown modifier in the variable name .if ${VAR.} != "unknown modifier in the variable name" . error @@ -43,7 +43,7 @@ VAR.${:U:Z}= unknown modifier in the variable name # As of 2020-12-01, errors in the variable name are silently ignored. # Since var.c 1.754 from 2020-12-20, unknown modifiers at parse time result # in an error message and a non-zero exit status. -# expect+1: Unknown modifier "Z" +# expect+1: while evaluating "${:U:Z}post": Unknown modifier "Z" VAR.${:U:Z}post= unknown modifier with text in the variable name .if ${VAR.post} != "unknown modifier with text in the variable name" . error diff --git a/contrib/bmake/var.c b/contrib/bmake/var.c index 54d6ef57c497..f39ce1baa83b 100644 --- a/contrib/bmake/var.c +++ b/contrib/bmake/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1101 2024/03/01 17:53:30 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1108 2024/04/28 15:10:19 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -81,8 +81,7 @@ * Var_End Clean up the module. * * Var_Set - * Var_SetExpand - * Set the value of the variable, creating it if + * Var_SetExpand Set the value of the variable, creating it if * necessary. * * Var_Append @@ -102,8 +101,7 @@ * * Var_Parse Parse an expression such as ${VAR:Mpattern}. * - * Var_Delete - * Delete a variable. + * Var_Delete Delete a variable. * * Var_ReexportVars * Export some or even all variables to the environment @@ -118,9 +116,6 @@ * Var_Stats Print out hashing statistics if in -dh mode. * * Var_Dump Print out all variables defined in the given scope. - * - * XXX: There's a lot of almost duplicate code in these functions that only - * differs in subtle details that are not mentioned in the manual page. */ #include <sys/stat.h> @@ -148,7 +143,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1101 2024/03/01 17:53:30 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1108 2024/04/28 15:10:19 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -158,7 +153,7 @@ MAKE_RCSID("$NetBSD: var.c,v 1.1101 2024/03/01 17:53:30 rillig Exp $"); * There are 3 kinds of variables: scope variables, environment variables, * undefined variables. * - * Scope variables are stored in a GNode.scope. The only way to undefine + * Scope variables are stored in GNode.vars. The only way to undefine * a scope variable is using the .undef directive. In particular, it must * not be possible to undefine a variable during the evaluation of an * expression, or Var.name might point nowhere. (There is another, @@ -193,7 +188,7 @@ typedef struct Var { /* * The variable comes from the environment. - * Appending to its value moves the variable to the global scope. + * Appending to its value depends on the scope, see var-op-append.mk. */ bool fromEnvironment:1; @@ -269,6 +264,18 @@ typedef struct SepBuf { char sep; } SepBuf; +typedef struct { + const char *target; + const char *varname; + const char *expr; +} EvalStackElement; + +typedef struct { + EvalStackElement *elems; + size_t len; + size_t cap; + Buffer details; +} EvalStack; /* Whether we have replaced the original environ (which we cannot free). */ char **savedEnv = NULL; @@ -337,6 +344,58 @@ static const char VarEvalMode_Name[][32] = { "eval-keep-dollar-and-undefined", }; +static EvalStack evalStack; + + +void +EvalStack_Push(const char *target, const char *expr, const char *varname) +{ + if (evalStack.len >= evalStack.cap) { + evalStack.cap = 16 + 2 * evalStack.cap; + evalStack.elems = bmake_realloc(evalStack.elems, + evalStack.cap * sizeof(*evalStack.elems)); + } + evalStack.elems[evalStack.len].target = target; + evalStack.elems[evalStack.len].expr = expr; + evalStack.elems[evalStack.len].varname = varname; + evalStack.len++; +} + +void +EvalStack_Pop(void) +{ + assert(evalStack.len > 0); + evalStack.len--; +} + +const char * +EvalStack_Details(void) +{ + size_t i; + Buffer *buf = &evalStack.details; + + + buf->len = 0; + for (i = 0; i < evalStack.len; i++) { + EvalStackElement *elem = evalStack.elems + i; + if (elem->target != NULL) { + Buf_AddStr(buf, "in target \""); + Buf_AddStr(buf, elem->target); + Buf_AddStr(buf, "\": "); + } + if (elem->expr != NULL) { + Buf_AddStr(buf, "while evaluating \""); + Buf_AddStr(buf, elem->expr); + Buf_AddStr(buf, "\": "); + } + if (elem->varname != NULL) { + Buf_AddStr(buf, "while evaluating variable \""); + Buf_AddStr(buf, elem->varname); + Buf_AddStr(buf, "\": "); + } + } + return buf->len > 0 ? buf->data : ""; +} static Var * VarNew(FStr name, const char *value, @@ -432,11 +491,8 @@ VarFindSubstring(Substring name, GNode *scope, bool elsewhere) } if (var == NULL) { - FStr envName; - const char *envValue; - - envName = Substring_Str(name); - envValue = getenv(envName.str); + FStr envName = Substring_Str(name); + const char *envValue = getenv(envName.str); if (envValue != NULL) return VarNew(envName, envValue, true, true, false); FStr_Done(&envName); @@ -951,9 +1007,10 @@ Var_SetWithFlags(GNode *scope, const char *name, const char *val, if (v == NULL) { if (scope == SCOPE_CMDLINE && !(flags & VAR_SET_NO_EXPORT)) { /* - * This var would normally prevent the same name being - * added to SCOPE_GLOBAL, so delete it from there if - * needed. Otherwise -V name may show the wrong value. + * This variable would normally prevent the same name + * being added to SCOPE_GLOBAL, so delete it from + * there if needed. Otherwise -V name may show the + * wrong value. * * See ExistsInCmdline. */ @@ -2336,9 +2393,9 @@ ApplyModifier_Loop(const char **pp, ModChain *ch) args.var = tvar.str; if (strchr(args.var, '$') != NULL) { Parse_Error(PARSE_FATAL, - "In the :@ modifier of \"%s\", the variable name \"%s\" " + "In the :@ modifier, the variable name \"%s\" " "must not contain a dollar", - expr->name, args.var); + args.var); return AMR_CLEANUP; } @@ -2480,22 +2537,22 @@ ApplyModifier_Time(const char **pp, ModChain *ch) if (args[0] == '=') { const char *p = args + 1; LazyBuf buf; + FStr arg; if (!ParseModifierPartSubst(&p, true, '\0', ch->expr->emode, ch, &buf, NULL, NULL)) return AMR_CLEANUP; + arg = LazyBuf_DoneGet(&buf); if (ModChain_ShouldEval(ch)) { - Substring arg = LazyBuf_Get(&buf); - const char *arg_p = arg.start; - if (!TryParseTime(&arg_p, &t) || arg_p != arg.end) { + const char *arg_p = arg.str; + if (!TryParseTime(&arg_p, &t) || *arg_p != '\0') { Parse_Error(PARSE_FATAL, - "Invalid time value \"%.*s\"", - (int)Substring_Length(arg), arg.start); - LazyBuf_Done(&buf); + "Invalid time value \"%s\"", arg.str); + FStr_Done(&arg); return AMR_CLEANUP; } } else t = 0; - LazyBuf_Done(&buf); + FStr_Done(&arg); *pp = p; } else { t = 0; @@ -3076,28 +3133,20 @@ ok: static char * str_toupper(const char *str) { - char *res; - size_t i, len; - - len = strlen(str); - res = bmake_malloc(len + 1); - for (i = 0; i < len + 1; i++) + size_t i, n = strlen(str) + 1; + char *res = bmake_malloc(n); + for (i = 0; i < n; i++) res[i] = ch_toupper(str[i]); - return res; } static char * str_tolower(const char *str) { - char *res; - size_t i, len; - - len = strlen(str); - res = bmake_malloc(len + 1); - for (i = 0; i < len + 1; i++) + size_t i, n = strlen(str) + 1; + char *res = bmake_malloc(n); + for (i = 0; i < n; i++) res[i] = ch_tolower(str[i]); - return res; } @@ -4390,7 +4439,7 @@ Expr_Init(const char *name, FStr value, * by .for loops and are boring, so evaluate them without debug logging. */ static bool -Var_Parse_FastLane(const char **pp, VarEvalMode emode, FStr *out_value) +Var_Parse_U(const char **pp, VarEvalMode emode, FStr *out_value) { const char *p; @@ -4449,8 +4498,7 @@ Var_Parse_FastLane(const char **pp, VarEvalMode emode, FStr *out_value) FStr Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) { - const char *p = *pp; - const char *const start = p; + const char *start, *p; bool haveModifier; /* true for ${VAR:...}, false for ${VAR} */ char startc; /* the actual '{' or '(' or '\0' */ char endc; /* the expected '}' or ')' or '\0' */ @@ -4467,9 +4515,11 @@ Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) scope, DEF_REGULAR); FStr val; - if (Var_Parse_FastLane(pp, emode, &val)) + if (Var_Parse_U(pp, emode, &val)) return val; + p = *pp; + start = p; DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]); val = FStr_InitRefer(NULL); @@ -4510,7 +4560,7 @@ Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) * while its value is still being used: * * VAR= value - * _:= ${VAR:${:U@VAR@loop@}:S,^,prefix,} + * _:= ${VAR:${:U:@VAR@@}:S,^,prefix,} * * The same effect might be achievable using the '::=' or the ':_' * modifiers. @@ -4521,6 +4571,11 @@ Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) */ expr.value = FStr_InitRefer(v->val.data); + if (expr.name[0] != '\0') + EvalStack_Push(NULL, NULL, expr.name); + else + EvalStack_Push(NULL, start, NULL); + /* * Before applying any modifiers, expand any nested expressions from * the variable value. @@ -4577,6 +4632,7 @@ Var_Parse(const char **pp, GNode *scope, VarEvalMode emode) VarFreeShortLived(v); } + EvalStack_Pop(); return expr.value; } @@ -4664,10 +4720,9 @@ VarSubstPlain(const char **pp, Buffer *res) * given string. * * Input: - * str The string in which the expressions are - * expanded. - * scope The scope in which to start searching for - * variables. The other scopes are searched as well. + * str The string in which the expressions are expanded. + * scope The scope in which to start searching for variables. + * The other scopes are searched as well. * emode The mode for parsing or evaluating subexpressions. */ char * @@ -4694,7 +4749,7 @@ Var_Subst(const char *str, GNode *scope, VarEvalMode emode) VarSubstPlain(&p, &res); } - return Buf_DoneDataCompact(&res); + return Buf_DoneData(&res); } void |