diff options
-rw-r--r-- | .hgtags | 4 | ||||
-rw-r--r-- | .pc/.quilt_patches | 1 | ||||
-rw-r--r-- | .pc/.quilt_series | 1 | ||||
-rw-r--r-- | .pc/.version | 1 | ||||
-rw-r--r-- | .pc/100_makefile.boot.diff/Makefile.boot | 0 | ||||
-rw-r--r-- | .pc/140_multiarch.diff/Makefile.boot | 48 | ||||
-rw-r--r-- | .pc/140_multiarch.diff/arch.c | 1403 | ||||
-rw-r--r-- | .pc/140_multiarch.diff/bmake.1 | 2289 | ||||
-rw-r--r-- | .pc/140_multiarch.diff/main.c | 2023 | ||||
-rw-r--r-- | .pc/160_manpage.diff/bmake.1 | 2290 | ||||
-rw-r--r-- | .pc/applied-patches | 3 |
11 files changed, 0 insertions, 8063 deletions
diff --git a/.hgtags b/.hgtags deleted file mode 100644 index fa12837..0000000 --- a/.hgtags +++ /dev/null @@ -1,4 +0,0 @@ -408b7e42f6c6e03ee0c16351a1f4ee80c88e4847 bmake_20130904-1 -41b4566316e2900f228224c51aa4ad2e721e0839 bmake_20131001-1 -2c423c57b894cdf9f6c245db5d2bc44e8c616a45 bmake_20131001-2 -e5d0d575aa101a29a58de9acaa8d336c792e95c4 bmake_20150606-1 diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches deleted file mode 100644 index 6857a8d..0000000 --- a/.pc/.quilt_patches +++ /dev/null @@ -1 +0,0 @@ -debian/patches diff --git a/.pc/.quilt_series b/.pc/.quilt_series deleted file mode 100644 index c206706..0000000 --- a/.pc/.quilt_series +++ /dev/null @@ -1 +0,0 @@ -series diff --git a/.pc/.version b/.pc/.version deleted file mode 100644 index 0cfbf08..0000000 --- a/.pc/.version +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/.pc/100_makefile.boot.diff/Makefile.boot b/.pc/100_makefile.boot.diff/Makefile.boot deleted file mode 100644 index e69de29..0000000 --- a/.pc/100_makefile.boot.diff/Makefile.boot +++ /dev/null diff --git a/.pc/140_multiarch.diff/Makefile.boot b/.pc/140_multiarch.diff/Makefile.boot deleted file mode 100644 index 88a9aac..0000000 --- a/.pc/140_multiarch.diff/Makefile.boot +++ /dev/null @@ -1,48 +0,0 @@ -# $NetBSD: Makefile.boot,v 1.17 2004/05/07 00:04:38 ross Exp $ -# -# a very simple makefile... -# -# You only want to use this if you aren't running NetBSD. -# -# modify MACHINE and MACHINE_ARCH as appropriate for your target architecture -# -CC=gcc -O -g - --include Makefile.config - -.c.o: - ${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@ - -MACHINE=i386 -MACHINE_ARCH=i386 -# tested on HP-UX 10.20 -#MAKE_MACHINE=hp700 -#MAKE_MACHINE_ARCH=hppa -CFLAGS= -DTARGET_MACHINE=\"${MACHINE}\" \ - -DTARGET_MACHINE_ARCH=\"${MACHINE_ARCH}\" \ - -DMAKE_MACHINE=\"${MACHINE}\" -LIBS= - -OBJ=arch.o buf.o compat.o cond.o dir.o for.o hash.o job.o main.o make.o \ - make_malloc.o parse.o str.o strlist.o suff.o targ.o trace.o var.o util.o \ - meta.o strlcpy.o - -LIBOBJ= lst.lib/lstAppend.o lst.lib/lstAtEnd.o lst.lib/lstAtFront.o \ - lst.lib/lstClose.o lst.lib/lstConcat.o lst.lib/lstDatum.o \ - lst.lib/lstDeQueue.o lst.lib/lstDestroy.o lst.lib/lstDupl.o \ - lst.lib/lstEnQueue.o lst.lib/lstFind.o lst.lib/lstFindFrom.o \ - lst.lib/lstFirst.o lst.lib/lstForEach.o lst.lib/lstForEachFrom.o \ - lst.lib/lstInit.o lst.lib/lstInsert.o lst.lib/lstIsAtEnd.o \ - lst.lib/lstIsEmpty.o lst.lib/lstLast.o lst.lib/lstMember.o \ - lst.lib/lstNext.o lst.lib/lstOpen.o lst.lib/lstRemove.o \ - lst.lib/lstReplace.o lst.lib/lstSucc.o lst.lib/lstPrev.o - -bmake: ${OBJ} ${LIBOBJ} -# @echo 'make of make and make.0 started.' - ${CC} ${LDFLAGS} ${OBJ} ${LIBOBJ} -o bmake ${LIBS} - @ls -l $@ -# nroff -h -man make.1 > make.0 -# @echo 'make of make and make.0 completed.' - -clean: - rm -f ${OBJ} ${LIBOBJ} ${PORTOBJ} bmake diff --git a/.pc/140_multiarch.diff/arch.c b/.pc/140_multiarch.diff/arch.c deleted file mode 100644 index 943f41e..0000000 --- a/.pc/140_multiarch.diff/arch.c +++ /dev/null @@ -1,1403 +0,0 @@ -/* $NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * arch.c -- - * Functions to manipulate libraries, archives and their members. - * - * Once again, cacheing/hashing comes into play in the manipulation - * of archives. The first time an archive is referenced, all of its members' - * headers are read and hashed and the archive closed again. All hashed - * archives are kept on a list which is searched each time an archive member - * is referenced. - * - * The interface to this module is: - * Arch_ParseArchive Given an archive specification, return a list - * of GNode's, one for each member in the spec. - * FAILURE is returned if the specification is - * invalid for some reason. - * - * Arch_Touch Alter the modification time of the archive - * member described by the given node to be - * the current time. - * - * Arch_TouchLib Update the modification time of the library - * described by the given node. This is special - * because it also updates the modification time - * of the library's table of contents. - * - * Arch_MTime Find the modification time of a member of - * an archive *in the archive*. The time is also - * placed in the member's GNode. Returns the - * modification time. - * - * Arch_MemTime Find the modification time of a member of - * an archive. Called when the member doesn't - * already exist. Looks in the archive for the - * modification time. Returns the modification - * time. - * - * Arch_FindLib Search for a library along a path. The - * library name in the GNode should be in - * -l<name> format. - * - * Arch_LibOODate Special function to decide if a library node - * is out-of-date. - * - * Arch_Init Initialize this module. - * - * Arch_End Cleanup this module. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/param.h> -#include <ctype.h> -#ifdef HAVE_AR_H -#include <ar.h> -#else -struct ar_hdr { - char ar_name[16]; /* name */ - char ar_date[12]; /* modification time */ - char ar_uid[6]; /* user id */ - char ar_gid[6]; /* group id */ - char ar_mode[8]; /* octal file permissions */ - char ar_size[10]; /* size in bytes */ -#ifndef ARFMAG -#define ARFMAG "`\n" -#endif - char ar_fmag[2]; /* consistency check */ -}; -#endif -#if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB)) -#include <ranlib.h> -#endif -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#ifdef HAVE_UTIME_H -#include <utime.h> -#endif - -#include "make.h" -#include "hash.h" -#include "dir.h" - -#ifdef TARGET_MACHINE -#undef MAKE_MACHINE -#define MAKE_MACHINE TARGET_MACHINE -#endif -#ifdef TARGET_MACHINE_ARCH -#undef MAKE_MACHINE_ARCH -#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH -#endif - -static Lst archives; /* Lst of archives we've already examined */ - -typedef struct Arch { - char *name; /* Name of archive */ - Hash_Table members; /* All the members of the archive described - * by <name, struct ar_hdr *> key/value pairs */ - char *fnametab; /* Extended name table strings */ - size_t fnamesize; /* Size of the string table */ -} Arch; - -static int ArchFindArchive(const void *, const void *); -#ifdef CLEANUP -static void ArchFree(void *); -#endif -static struct ar_hdr *ArchStatMember(char *, char *, Boolean); -static FILE *ArchFindMember(char *, char *, struct ar_hdr *, const char *); -#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__) -#define SVR4ARCHIVES -static int ArchSVR4Entry(Arch *, char *, size_t, FILE *); -#endif - - -#if defined(_AIX) -# define AR_NAME _ar_name.ar_name -# define AR_FMAG _ar_name.ar_fmag -# define SARMAG SAIAMAG -# define ARMAG AIAMAG -# define ARFMAG AIAFMAG -#endif -#ifndef AR_NAME -# define AR_NAME ar_name -#endif -#ifndef AR_DATE -# define AR_DATE ar_date -#endif -#ifndef AR_SIZE -# define AR_SIZE ar_size -#endif -#ifndef AR_FMAG -# define AR_FMAG ar_fmag -#endif -#ifndef ARMAG -# define ARMAG "!<arch>\n" -#endif -#ifndef SARMAG -# define SARMAG 8 -#endif - -#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1) - -#ifdef CLEANUP -/*- - *----------------------------------------------------------------------- - * ArchFree -- - * Free memory used by an archive - * - * Results: - * None. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static void -ArchFree(void *ap) -{ - Arch *a = (Arch *)ap; - Hash_Search search; - Hash_Entry *entry; - - /* Free memory from hash entries */ - for (entry = Hash_EnumFirst(&a->members, &search); - entry != NULL; - entry = Hash_EnumNext(&search)) - free(Hash_GetValue(entry)); - - free(a->name); - if (a->fnametab) - free(a->fnametab); - Hash_DeleteTable(&a->members); - free(a); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * Arch_ParseArchive -- - * Parse the archive specification in the given line and find/create - * the nodes for the specified archive members, placing their nodes - * on the given list. - * - * Input: - * linePtr Pointer to start of specification - * nodeLst Lst on which to place the nodes - * ctxt Context in which to expand variables - * - * Results: - * SUCCESS if it was a valid specification. The linePtr is updated - * to point to the first non-space after the archive spec. The - * nodes for the members are placed on the given list. - * - * Side Effects: - * Some nodes may be created. The given list is extended. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) -{ - char *cp; /* Pointer into line */ - GNode *gn; /* New node */ - char *libName; /* Library-part of specification */ - char *memName; /* Member-part of specification */ - char *nameBuf; /* temporary place for node name */ - char saveChar; /* Ending delimiter of member-name */ - Boolean subLibName; /* TRUE if libName should have/had - * variable substitution performed on it */ - - libName = *linePtr; - - subLibName = FALSE; - - for (cp = libName; *cp != '(' && *cp != '\0'; cp++) { - if (*cp == '$') { - /* - * Variable spec, so call the Var module to parse the puppy - * so we can safely advance beyond it... - */ - int length; - void *freeIt; - char *result; - - result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); - if (freeIt) - free(freeIt); - if (result == var_Error) { - return(FAILURE); - } else { - subLibName = TRUE; - } - - cp += length-1; - } - } - - *cp++ = '\0'; - if (subLibName) { - libName = Var_Subst(NULL, libName, ctxt, TRUE); - } - - - for (;;) { - /* - * First skip to the start of the member's name, mark that - * place and skip to the end of it (either white-space or - * a close paren). - */ - Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */ - - while (*cp != '\0' && *cp != ')' && isspace ((unsigned char)*cp)) { - cp++; - } - memName = cp; - while (*cp != '\0' && *cp != ')' && !isspace ((unsigned char)*cp)) { - if (*cp == '$') { - /* - * Variable spec, so call the Var module to parse the puppy - * so we can safely advance beyond it... - */ - int length; - void *freeIt; - char *result; - - result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); - if (freeIt) - free(freeIt); - if (result == var_Error) { - return(FAILURE); - } else { - doSubst = TRUE; - } - - cp += length; - } else { - cp++; - } - } - - /* - * 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') { - printf("No closing parenthesis in archive specification\n"); - return (FAILURE); - } - - /* - * If we didn't move anywhere, we must be done - */ - if (cp == memName) { - break; - } - - saveChar = *cp; - *cp = '\0'; - - /* - * XXX: This should be taken care of intelligently by - * SuffExpandChildren, both for the archive and the member portions. - */ - /* - * If member contains variables, try and substitute for them. - * This will slow down archive specs with dynamic sources, of course, - * since we'll be (non-)substituting them three times, but them's - * the breaks -- we need to do this since SuffExpandChildren calls - * us, otherwise we could assume the thing would be taken care of - * later. - */ - if (doSubst) { - char *buf; - char *sacrifice; - char *oldMemName = memName; - size_t sz; - - memName = Var_Subst(NULL, memName, ctxt, TRUE); - - /* - * Now form an archive spec and recurse to deal with nested - * variables and multi-word variable values.... The results - * are just placed at the end of the nodeLst we're returning. - */ - sz = strlen(memName)+strlen(libName)+3; - buf = sacrifice = bmake_malloc(sz); - - snprintf(buf, sz, "%s(%s)", libName, memName); - - if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) { - /* - * 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... - */ - gn = Targ_FindNode(buf, TARG_CREATE); - - if (gn == NULL) { - free(buf); - return(FAILURE); - } else { - gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, gn); - } - } else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) { - /* - * Error in nested call -- free buffer and return FAILURE - * ourselves. - */ - free(buf); - return(FAILURE); - } - /* - * Free buffer and continue with our work. - */ - free(buf); - } else if (Dir_HasWildcards(memName)) { - Lst members = Lst_Init(FALSE); - char *member; - size_t sz = MAXPATHLEN, nsz; - nameBuf = bmake_malloc(sz); - - Dir_Expand(memName, dirSearchPath, members); - while (!Lst_IsEmpty(members)) { - member = (char *)Lst_DeQueue(members); - nsz = strlen(libName) + strlen(member) + 3; - if (sz > nsz) - nameBuf = bmake_realloc(nameBuf, sz = nsz * 2); - - snprintf(nameBuf, sz, "%s(%s)", libName, member); - free(member); - gn = Targ_FindNode(nameBuf, TARG_CREATE); - if (gn == NULL) { - free(nameBuf); - return (FAILURE); - } else { - /* - * 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; - (void)Lst_AtEnd(nodeLst, gn); - } - } - Lst_Destroy(members, NULL); - free(nameBuf); - } else { - size_t sz = strlen(libName) + strlen(memName) + 3; - nameBuf = bmake_malloc(sz); - snprintf(nameBuf, sz, "%s(%s)", libName, memName); - gn = Targ_FindNode(nameBuf, TARG_CREATE); - free(nameBuf); - if (gn == NULL) { - return (FAILURE); - } else { - /* - * 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; - (void)Lst_AtEnd(nodeLst, gn); - } - } - if (doSubst) { - free(memName); - } - - *cp = saveChar; - } - - /* - * If substituted libName, free it now, since we need it no longer. - */ - if (subLibName) { - free(libName); - } - - /* - * We promised the pointer would be set up at the next non-space, so - * we must advance cp there before setting *linePtr... (note that on - * entrance to the loop, cp is guaranteed to point at a ')') - */ - do { - cp++; - } while (*cp != '\0' && isspace ((unsigned char)*cp)); - - *linePtr = cp; - return (SUCCESS); -} - -/*- - *----------------------------------------------------------------------- - * ArchFindArchive -- - * See if the given archive is the one we are looking for. Called - * From ArchStatMember and ArchFindMember via Lst_Find. - * - * Input: - * ar Current list element - * archName Name we want - * - * Results: - * 0 if it is, non-zero if it isn't. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static int -ArchFindArchive(const void *ar, const void *archName) -{ - return (strcmp(archName, ((const Arch *)ar)->name)); -} - -/*- - *----------------------------------------------------------------------- - * ArchStatMember -- - * 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. - * hash TRUE if archive should be hashed if not already so. - * - * Results: - * A pointer to the current struct ar_hdr structure for the member. Note - * That no position is returned, so this is not useful for touching - * archive members. This is mostly because we have no assurances that - * The archive will remain constant after we read all the headers, so - * there's not much point in remembering the position... - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -static struct ar_hdr * -ArchStatMember(char *archive, char *member, Boolean hash) -{ - FILE * arch; /* Stream to archive */ - int size; /* Size of archive member */ - char *cp; /* Useful character pointer */ - char magic[SARMAG]; - LstNode ln; /* Lst member containing archive descriptor */ - Arch *ar; /* Archive descriptor */ - Hash_Entry *he; /* Entry containing member's description */ - struct ar_hdr arh; /* archive-member header for reading archive */ - char memName[MAXPATHLEN+1]; - /* Current member name while hashing. */ - - /* - * Because of space constraints and similar things, files are archived - * using their final path components, not the entire thing, so we need - * to point 'member' to the final component, if there is one, to make - * the comparisons easier... - */ - cp = strrchr(member, '/'); - if (cp != NULL) { - member = cp + 1; - } - - ln = Lst_Find(archives, archive, ArchFindArchive); - if (ln != NULL) { - ar = (Arch *)Lst_Datum(ln); - - he = Hash_FindEntry(&ar->members, member); - - if (he != NULL) { - return ((struct ar_hdr *)Hash_GetValue(he)); - } else { - /* Try truncated name */ - char copy[AR_MAX_NAME_LEN+1]; - size_t len = strlen(member); - - if (len > AR_MAX_NAME_LEN) { - len = AR_MAX_NAME_LEN; - strncpy(copy, member, AR_MAX_NAME_LEN); - copy[AR_MAX_NAME_LEN] = '\0'; - } - if ((he = Hash_FindEntry(&ar->members, copy)) != NULL) - return ((struct ar_hdr *)Hash_GetValue(he)); - return NULL; - } - } - - if (!hash) { - /* - * Caller doesn't want the thing hashed, just use ArchFindMember - * to read the header for the member out and close down the stream - * again. Since the archive is not to be hashed, we assume there's - * no need to allocate extra room for the header we're returning, - * so just declare it static. - */ - static struct ar_hdr sarh; - - arch = ArchFindMember(archive, member, &sarh, "r"); - - if (arch == NULL) { - return NULL; - } else { - fclose(arch); - 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)) { - fclose(arch); - return NULL; - } - - ar = bmake_malloc(sizeof(Arch)); - ar->name = bmake_strdup(archive); - ar->fnametab = NULL; - ar->fnamesize = 0; - Hash_InitTable(&ar->members, -1); - memName[AR_MAX_NAME_LEN] = '\0'; - - while (fread((char *)&arh, sizeof(struct ar_hdr), 1, arch) == 1) { - if (strncmp( arh.AR_FMAG, ARFMAG, sizeof(arh.AR_FMAG)) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ - goto badarch; - } else { - /* - * 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 = (int)strtol(arh.AR_SIZE, NULL, 10); - - (void)strncpy(memName, arh.AR_NAME, sizeof(arh.AR_NAME)); - for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) { - continue; - } - cp[1] = '\0'; - -#ifdef SVR4ARCHIVES - /* - * svr4 names are slash terminated. Also svr4 extended AR format. - */ - if (memName[0] == '/') { - /* - * svr4 magic mode; handle it - */ - switch (ArchSVR4Entry(ar, memName, size, arch)) { - case -1: /* Invalid data */ - goto badarch; - case 0: /* List of files entry */ - continue; - default: /* Got the entry */ - break; - } - } - else { - if (cp[0] == '/') - cp[0] = '\0'; - } -#endif - -#ifdef AR_EFMT1 - /* - * BSD 4.4 extended AR format: #1/<namelen>, with name as the - * first <namelen> bytes of the file - */ - if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 && - isdigit((unsigned char)memName[sizeof(AR_EFMT1) - 1])) { - - unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]); - - if (elen > MAXPATHLEN) - goto badarch; - if (fread(memName, elen, 1, arch) != 1) - goto badarch; - memName[elen] = '\0'; - fseek(arch, -elen, SEEK_CUR); - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "ArchStat: Extended format entry for %s\n", memName); - } - } -#endif - - he = Hash_CreateEntry(&ar->members, memName, NULL); - Hash_SetValue(he, bmake_malloc(sizeof(struct ar_hdr))); - memcpy(Hash_GetValue(he), &arh, sizeof(struct ar_hdr)); - } - fseek(arch, (size + 1) & ~1, SEEK_CUR); - } - - fclose(arch); - - (void)Lst_AtEnd(archives, ar); - - /* - * Now that the archive has been read and cached, we can look into - * the hash table to find the desired member's header. - */ - he = Hash_FindEntry(&ar->members, member); - - if (he != NULL) { - return ((struct ar_hdr *)Hash_GetValue(he)); - } else { - return NULL; - } - -badarch: - fclose(arch); - Hash_DeleteTable(&ar->members); - if (ar->fnametab) - free(ar->fnametab); - free(ar); - return NULL; -} - -#ifdef SVR4ARCHIVES -/*- - *----------------------------------------------------------------------- - * ArchSVR4Entry -- - * Parse an SVR4 style entry that begins with a slash. - * If it is "//", then load the table of filenames - * If it is "/<offset>", then try to substitute the long file name - * from offset of a table previously read. - * - * Results: - * -1: Bad data in archive - * 0: A table was loaded from the file - * 1: Name was successfully substituted from table - * 2: Name was not successfully substituted from table - * - * Side Effects: - * If a table is read, the file pointer is moved to the next archive - * member - * - *----------------------------------------------------------------------- - */ -static int -ArchSVR4Entry(Arch *ar, char *name, size_t size, FILE *arch) -{ -#define ARLONGNAMES1 "//" -#define ARLONGNAMES2 "/ARFILENAMES" - size_t entry; - char *ptr, *eptr; - - if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 || - strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) { - - if (ar->fnametab != NULL) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "Attempted to redefine an SVR4 name table\n"); - } - return -1; - } - - /* - * This is a table of archive names, so we build one for - * ourselves - */ - ar->fnametab = bmake_malloc(size); - ar->fnamesize = size; - - if (fread(ar->fnametab, size, 1, arch) != 1) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "Reading an SVR4 name table failed\n"); - } - return -1; - } - eptr = ar->fnametab + size; - for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++) - switch (*ptr) { - case '/': - entry++; - *ptr = '\0'; - break; - - case '\n': - break; - - default: - break; - } - if (DEBUG(ARCH)) { - fprintf(debug_file, "Found svr4 archive name table with %lu entries\n", - (u_long)entry); - } - return 0; - } - - if (name[1] == ' ' || name[1] == '\0') - return 2; - - entry = (size_t)strtol(&name[1], &eptr, 0); - if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "Could not parse SVR4 name %s\n", name); - } - return 2; - } - if (entry >= ar->fnamesize) { - if (DEBUG(ARCH)) { - fprintf(debug_file, "SVR4 entry offset %s is greater than %lu\n", - name, (u_long)ar->fnamesize); - } - return 2; - } - - if (DEBUG(ARCH)) { - fprintf(debug_file, "Replaced %s with %s\n", name, &ar->fnametab[entry]); - } - - (void)strncpy(name, &ar->fnametab[entry], MAXPATHLEN); - name[MAXPATHLEN] = '\0'; - return 1; -} -#endif - - -/*- - *----------------------------------------------------------------------- - * ArchFindMember -- - * Locate a member of an archive, given the path of the archive and - * the path of the desired member. If the archive is to be modified, - * the mode should be "r+", if not, it should be "r". - * - * Input: - * archive Path to the archive - * member Name of member. If it is a path, only the last - * component is used. - * arhPtr Pointer to header structure to be filled in - * mode The mode for opening the stream - * - * Results: - * An FILE *, opened for reading and writing, positioned at the - * start of the member's struct ar_hdr, or NULL if the member was - * nonexistent. The current struct ar_hdr for member. - * - * Side Effects: - * The passed struct ar_hdr structure is filled in. - * - *----------------------------------------------------------------------- - */ -static FILE * -ArchFindMember(char *archive, char *member, struct ar_hdr *arhPtr, - const char *mode) -{ - FILE * arch; /* Stream to archive */ - int size; /* Size of archive member */ - char *cp; /* Useful character pointer */ - char magic[SARMAG]; - size_t len, tlen; - - arch = fopen(archive, mode); - 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 final path components, not the entire thing, so we need - * to point 'member' to the final component, if there is one, to make - * the comparisons easier... - */ - cp = strrchr(member, '/'); - if (cp != NULL) { - member = cp + 1; - } - len = tlen = strlen(member); - if (len > sizeof(arhPtr->AR_NAME)) { - tlen = sizeof(arhPtr->AR_NAME); - } - - while (fread((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) == 1) { - if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof(arhPtr->AR_FMAG) ) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ - fclose(arch); - return NULL; - } else if (strncmp(member, arhPtr->AR_NAME, tlen) == 0) { - /* - * If the member's name doesn't take up the entire 'name' field, - * we have to be careful of matching prefixes. Names are space- - * padded to the right, so if the character in 'name' at the end - * of the matched string is anything but a space, this isn't the - * member we sought. - */ - if (tlen != sizeof(arhPtr->AR_NAME) && arhPtr->AR_NAME[tlen] != ' '){ - goto skip; - } else { - /* - * To make life easier, 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... - */ - fseek(arch, -sizeof(struct ar_hdr), SEEK_CUR); - return (arch); - } - } else -#ifdef AR_EFMT1 - /* - * BSD 4.4 extended AR format: #1/<namelen>, with name as the - * first <namelen> bytes of the file - */ - if (strncmp(arhPtr->AR_NAME, AR_EFMT1, - sizeof(AR_EFMT1) - 1) == 0 && - isdigit((unsigned char)arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) { - - unsigned int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]); - char ename[MAXPATHLEN + 1]; - - if (elen > MAXPATHLEN) { - fclose(arch); - return NULL; - } - if (fread(ename, elen, 1, arch) != 1) { - fclose(arch); - return NULL; - } - ename[elen] = '\0'; - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "ArchFind: Extended format entry for %s\n", ename); - } - if (strncmp(ename, member, len) == 0) { - /* Found as extended name */ - fseek(arch, -sizeof(struct ar_hdr) - elen, SEEK_CUR); - return (arch); - } - fseek(arch, -elen, SEEK_CUR); - goto skip; - } else -#endif - { -skip: - /* - * 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. - */ - arhPtr->ar_size[sizeof(arhPtr->AR_SIZE)-1] = '\0'; - size = (int)strtol(arhPtr->AR_SIZE, NULL, 10); - fseek(arch, (size + 1) & ~1, SEEK_CUR); - } - } - - /* - * We've looked everywhere, but the member is not to be found. Close the - * archive and return NULL -- an error. - */ - fclose(arch); - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * Arch_Touch -- - * Touch a member of an archive. - * - * Input: - * gn Node of member to touch - * - * Results: - * The 'time' field of the member's header is updated. - * - * Side Effects: - * The modification time of the entire archive is also changed. - * For a library, this could necessitate the re-ranlib'ing of the - * whole thing. - * - *----------------------------------------------------------------------- - */ -void -Arch_Touch(GNode *gn) -{ - FILE * arch; /* Stream open to archive, positioned properly */ - struct ar_hdr arh; /* Current header describing member */ - char *p1, *p2; - - arch = ArchFindMember(Var_Value(ARCHIVE, gn, &p1), - Var_Value(MEMBER, gn, &p2), - &arh, "r+"); - if (p1) - free(p1); - if (p2) - free(p2); - snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now); - - if (arch != NULL) { - (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch); - fclose(arch); - } -} - -/*- - *----------------------------------------------------------------------- - * Arch_TouchLib -- - * Given a node which represents a library, touch the thing, making - * sure that the table of contents also is touched. - * - * Input: - * gn The node of the library to touch - * - * Results: - * None. - * - * Side Effects: - * Both the modification time of the library and of the RANLIBMAG - * member are set to 'now'. - * - *----------------------------------------------------------------------- - */ -void -#if !defined(RANLIBMAG) -Arch_TouchLib(GNode *gn MAKE_ATTR_UNUSED) -#else -Arch_TouchLib(GNode *gn) -#endif -{ -#ifdef RANLIBMAG - FILE * arch; /* Stream open to archive */ - struct ar_hdr arh; /* Header describing table of contents */ - struct utimbuf times; /* Times for utime() call */ - - arch = ArchFindMember(gn->path, UNCONST(RANLIBMAG), &arh, "r+"); - snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now); - - if (arch != NULL) { - (void)fwrite((char *)&arh, sizeof(struct ar_hdr), 1, arch); - fclose(arch); - - times.actime = times.modtime = now; - utime(gn->path, ×); - } -#endif -} - -/*- - *----------------------------------------------------------------------- - * Arch_MTime -- - * Return the modification time of a member of an archive. - * - * Input: - * gn Node describing archive member - * - * Results: - * The modification time(seconds). - * - * Side Effects: - * The mtime field of the given node is filled in with the value - * returned by the function. - * - *----------------------------------------------------------------------- - */ -time_t -Arch_MTime(GNode *gn) -{ - struct ar_hdr *arhPtr; /* Header of desired member */ - time_t modTime; /* Modification time as an integer */ - char *p1, *p2; - - arhPtr = ArchStatMember(Var_Value(ARCHIVE, gn, &p1), - Var_Value(MEMBER, gn, &p2), - TRUE); - if (p1) - free(p1); - if (p2) - free(p2); - - if (arhPtr != NULL) { - modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10); - } else { - modTime = 0; - } - - gn->mtime = modTime; - return (modTime); -} - -/*- - *----------------------------------------------------------------------- - * Arch_MemMTime -- - * Given a non-existent archive member's node, get its modification - * time from its archived form, if it exists. - * - * Results: - * The modification time. - * - * Side Effects: - * The mtime field is filled in. - * - *----------------------------------------------------------------------- - */ -time_t -Arch_MemMTime(GNode *gn) -{ - LstNode ln; - GNode *pgn; - char *nameStart, - *nameEnd; - - if (Lst_Open(gn->parents) != SUCCESS) { - gn->mtime = 0; - return (0); - } - while ((ln = Lst_Next(gn->parents)) != NULL) { - pgn = (GNode *)Lst_Datum(ln); - - if (pgn->type & OP_ARCHV) { - /* - * If the parent is an archive specification and is being made - * and its member's name matches the name of the node we were - * given, record the modification time of the parent in the - * child. We keep searching its parents in case some other - * parent requires this child to exist... - */ - nameStart = strchr(pgn->name, '(') + 1; - nameEnd = strchr(nameStart, ')'); - - if ((pgn->flags & REMAKE) && - strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) { - gn->mtime = Arch_MTime(pgn); - } - } else if (pgn->flags & REMAKE) { - /* - * Something which isn't a library depends on the existence of - * this target, so it needs to exist. - */ - gn->mtime = 0; - break; - } - } - - Lst_Close(gn->parents); - - return (gn->mtime); -} - -/*- - *----------------------------------------------------------------------- - * Arch_FindLib -- - * Search for a library along the given search path. - * - * Input: - * gn Node of library to find - * path Search path - * - * Results: - * None. - * - * Side Effects: - * The node's 'path' field is set to the found path (including the - * actual file name, not -l...). If the system can handle the -L - * flag when linking (or we cannot find the library), we assume that - * the user has placed the .LIBRARIES variable in the final linking - * command (or the linker will know where to find it) and set the - * 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. - * - *----------------------------------------------------------------------- - */ -void -Arch_FindLib(GNode *gn, Lst path) -{ - char *libName; /* file name for archive */ - size_t sz = strlen(gn->name) + 6 - 2; - - libName = bmake_malloc(sz); - snprintf(libName, sz, "lib%s.a", &gn->name[2]); - - gn->path = Dir_FindFile(libName, path); - - free(libName); - -#ifdef LIBRARIES - Var_Set(TARGET, gn->name, gn, 0); -#else - Var_Set(TARGET, gn->path == NULL ? gn->name : gn->path, gn, 0); -#endif /* LIBRARIES */ -} - -/*- - *----------------------------------------------------------------------- - * Arch_LibOODate -- - * Decide if a node with the OP_LIB attribute is out-of-date. Called - * from Make_OODate to make its life easier. - * - * 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: - * Its modification time is less than that of one of its - * sources (gn->mtime < gn->cmgn->mtime). - * Its modification time is greater than the time at which the - * make began (i.e. it's been modified in the course - * of the make, probably by archiving). - * The modification time of one of its sources is greater than - * the one of its RANLIBMAG member (i.e. its table of contents - * is out-of-date). We don't compare of the archive time - * vs. TOC time because they can be too close. In my - * opinion we should not bother with the TOC at all since - * this is used by 'ar' rules that affect the data contents - * of the archive, not by ranlib rules, which affect the - * TOC. - * - * Input: - * gn The library's graph node - * - * Results: - * TRUE if the library is out-of-date. FALSE otherwise. - * - * Side Effects: - * The library will be hashed if it hasn't been already. - * - *----------------------------------------------------------------------- - */ -Boolean -Arch_LibOODate(GNode *gn) -{ - Boolean oodate; - - if (gn->type & OP_PHONY) { - oodate = TRUE; - } else if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) { - oodate = FALSE; - } else if ((!Lst_IsEmpty(gn->children) && gn->cmgn == NULL) || - (gn->mtime > now) || - (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime)) { - oodate = TRUE; - } else { -#ifdef RANLIBMAG - struct ar_hdr *arhPtr; /* Header for __.SYMDEF */ - int modTimeTOC; /* The table-of-contents's mod time */ - - arhPtr = ArchStatMember(gn->path, UNCONST(RANLIBMAG), FALSE); - - if (arhPtr != NULL) { - modTimeTOC = (int)strtol(arhPtr->AR_DATE, NULL, 10); - - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); - } - oodate = (gn->cmgn == NULL || gn->cmgn->mtime > modTimeTOC); - } else { - /* - * A library w/o a table of contents is out-of-date - */ - if (DEBUG(ARCH) || DEBUG(MAKE)) { - fprintf(debug_file, "No t.o.c...."); - } - oodate = TRUE; - } -#else - oodate = FALSE; -#endif - } - return (oodate); -} - -/*- - *----------------------------------------------------------------------- - * Arch_Init -- - * Initialize things for this module. - * - * Results: - * None. - * - * Side Effects: - * The 'archives' list is initialized. - * - *----------------------------------------------------------------------- - */ -void -Arch_Init(void) -{ - archives = Lst_Init(FALSE); -} - - - -/*- - *----------------------------------------------------------------------- - * Arch_End -- - * Cleanup things for this module. - * - * Results: - * None. - * - * Side Effects: - * The 'archives' list is freed - * - *----------------------------------------------------------------------- - */ -void -Arch_End(void) -{ -#ifdef CLEANUP - Lst_Destroy(archives, ArchFree); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Arch_IsLib -- - * Check if the node is a library - * - * Results: - * True or False. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Arch_IsLib(GNode *gn) -{ - static const char armag[] = "!<arch>\n"; - char buf[sizeof(armag)-1]; - int fd; - - if ((fd = open(gn->path, O_RDONLY)) == -1) - return FALSE; - - if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { - (void)close(fd); - return FALSE; - } - - (void)close(fd); - - return memcmp(buf, armag, sizeof(buf)) == 0; -} diff --git a/.pc/140_multiarch.diff/bmake.1 b/.pc/140_multiarch.diff/bmake.1 deleted file mode 100644 index 39d28c4..0000000 --- a/.pc/140_multiarch.diff/bmake.1 +++ /dev/null @@ -1,2289 +0,0 @@ -.\" $NetBSD: make.1,v 1.249 2015/06/05 07:33:40 wiz Exp $ -.\" -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 -.\" -.Dd June 4, 2015 -.Dt MAKE 1 -.Os -.Sh NAME -.Nm bmake -.Nd maintain program dependencies -.Sh SYNOPSIS -.Nm -.Op Fl BeikNnqrstWwX -.Op Fl C Ar directory -.Op Fl D Ar variable -.Op Fl d Ar flags -.Op Fl f Ar makefile -.Op Fl I Ar directory -.Op Fl J Ar private -.Op Fl j Ar max_jobs -.Op Fl m Ar directory -.Op Fl T Ar file -.Op Fl V Ar variable -.Op Ar variable=value -.Op Ar target ... -.Sh DESCRIPTION -.Nm -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 -.Fl f Ar makefile -makefile option is given, -.Nm -will try to open -.Ql Pa makefile -then -.Ql Pa Makefile -in order to find the specifications. -If the file -.Ql Pa .depend -exists, it is read (see -.Xr mkdep 1 ) . -.Pp -This manual page is intended as a reference document only. -For a more thorough description of -.Nm -and makefiles, please refer to -.%T "PMake \- A Tutorial" . -.Pp -.Nm -will prepend the contents of the -.Va MAKEFLAGS -environment variable to the command line arguments before parsing them. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl B -Try to be backwards compatible by executing a single shell per command and -by executing the commands to make the sources of a dependency line in sequence. -.It Fl C Ar directory -Change to -.Ar directory -before reading the makefiles or doing anything else. -If multiple -.Fl C -options are specified, each is interpreted relative to the previous one: -.Fl C Pa / Fl C Pa etc -is equivalent to -.Fl C Pa /etc . -.It Fl D Ar variable -Define -.Ar variable -to be 1, in the global context. -.It Fl d Ar [-]flags -Turn on debugging, and specify which portions of -.Nm -are to print debugging information. -Unless the flags are preceded by -.Ql \- -they are added to the -.Va MAKEFLAGS -environment variable and will be processed by any child make processes. -By default, debugging information is printed to standard error, -but this can be changed using the -.Ar F -debugging flag. -The debugging output is always unbuffered; in addition, if debugging -is enabled but debugging output is not directed to standard output, -then the standard output is line buffered. -.Ar Flags -is one or more of the following: -.Bl -tag -width Ds -.It Ar A -Print all possible debugging information; -equivalent to specifying all of the debugging flags. -.It Ar a -Print debugging information about archive searching and caching. -.It Ar C -Print debugging information about current working directory. -.It Ar c -Print debugging information about conditional evaluation. -.It Ar d -Print debugging information about directory searching and caching. -.It Ar e -Print debugging information about failed commands and targets. -.It Ar F Ns Oo Sy \&+ Oc Ns Ar filename -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 -.Ql F -flag is -.Ql \&+ , -then the file will be opened in append mode; -otherwise the file will be overwritten. -If the file name is -.Ql stdout -or -.Ql stderr -then debugging output will be written to the -standard output or standard error output file descriptors respectively -(and the -.Ql \&+ -option has no effect). -Otherwise, the output will be written to the named file. -If the file name ends -.Ql .%d -then the -.Ql %d -is replaced by the pid. -.It Ar f -Print debugging information about loop evaluation. -.It Ar "g1" -Print the input graph before making anything. -.It Ar "g2" -Print the input graph after making everything, or before exiting -on error. -.It Ar "g3" -Print the input graph before exiting on error. -.It Ar j -Print debugging information about running multiple shells. -.It Ar l -Print commands in Makefiles regardless of whether or not they are prefixed by -.Ql @ -or other "quiet" flags. -Also known as "loud" behavior. -.It Ar M -Print debugging information about "meta" mode decisions about targets. -.It Ar m -Print debugging information about making targets, including modification -dates. -.It Ar n -Don't delete the temporary command scripts created when running commands. -These temporary scripts are created in the directory -referred to by the -.Ev TMPDIR -environment variable, or in -.Pa /tmp -if -.Ev TMPDIR -is unset or set to the empty string. -The temporary scripts are created by -.Xr mkstemp 3 , -and have names of the form -.Pa makeXXXXXX . -.Em NOTE : -This can create many files in -.Ev TMPDIR -or -.Pa /tmp , -so use with care. -.It Ar p -Print debugging information about makefile parsing. -.It Ar s -Print debugging information about suffix-transformation rules. -.It Ar t -Print debugging information about target list maintenance. -.It Ar V -Force the -.Fl V -option to print raw values of variables. -.It Ar v -Print debugging information about variable assignment. -.It Ar x -Run shell commands with -.Fl x -so the actual commands are printed as they are executed. -.El -.It Fl e -Specify that environment variables override macro assignments within -makefiles. -.It Fl f Ar makefile -Specify a makefile to read instead of the default -.Ql Pa makefile . -If -.Ar makefile -is -.Ql Fl , -standard input is read. -Multiple makefiles may be specified, and are read in the order specified. -.It Fl I Ar directory -Specify a directory in which to search for makefiles and included makefiles. -The system makefile directory (or directories, see the -.Fl m -option) is automatically included as part of this list. -.It Fl i -Ignore non-zero exit of shell commands in the makefile. -Equivalent to specifying -.Ql Fl -before each command line in the makefile. -.It Fl J Ar private -This option should -.Em not -be specified by the user. -.Pp -When the -.Ar j -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. -.It Fl j Ar max_jobs -Specify the maximum number of jobs that -.Nm -may have running at any one time. -The value is saved in -.Va .MAKE.JOBS . -Turns compatibility mode off, unless the -.Ar B -flag 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. -.It Fl k -Continue processing after errors are encountered, but only on those targets -that do not depend on the target whose creation caused the error. -.It Fl m Ar directory -Specify a directory in which to search for sys.mk and makefiles included -via the -.Ao Ar file Ac Ns -style -include statement. -The -.Fl m -option can be used multiple times to form a search path. -This path will override the default system include path: /usr/share/mk. -Furthermore the system include path will be appended to the search path used -for -.Qo Ar file Qc Ns -style -include statements (see the -.Fl I -option). -.Pp -If a file or directory name in the -.Fl m -argument (or the -.Ev MAKESYSPATH -environment variable) starts with the string -.Qq \&.../ -then -.Nm -will search for the specified file or directory named in the remaining part -of the argument string. -The search starts with the current directory of -the Makefile and then works upward towards the root of the filesystem. -If the search is successful, then the resulting directory replaces the -.Qq \&.../ -specification in the -.Fl m -argument. -If used, this feature allows -.Nm -to easily search in the current source tree for customized sys.mk files -(e.g., by using -.Qq \&.../mk/sys.mk -as an argument). -.It Fl n -Display the commands that would have been executed, but do not -actually execute them unless the target depends on the .MAKE special -source (see below). -.It Fl N -Display the commands which would have been executed, but do not -actually execute any of them; useful for debugging top-level makefiles -without descending into subdirectories. -.It Fl q -Do not execute any commands, but exit 0 if the specified targets are -up-to-date and 1, otherwise. -.It Fl r -Do not use the built-in rules specified in the system makefile. -.It Fl s -Do not echo any commands as they are executed. -Equivalent to specifying -.Ql Ic @ -before each command line in the makefile. -.It Fl T Ar tracefile -When used with the -.Fl j -flag, -append a trace record to -.Ar tracefile -for each job started and completed. -.It Fl t -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. -.It Fl V Ar variable -Print -.Nm Ns 's -idea of the value of -.Ar variable , -in the global context. -Do not build any targets. -Multiple instances of this option may be specified; -the variables will be printed one per line, -with a blank line for each null or undefined variable. -If -.Ar variable -contains a -.Ql \&$ -then the value will be expanded before printing. -.It Fl W -Treat any warnings during makefile parsing as errors. -.It Fl w -Print entering and leaving directory messages, pre and post processing. -.It Fl X -Don't export variables passed on the command line to the environment -individually. -Variables passed on the command line are still exported -via the -.Va MAKEFLAGS -environment variable. -This option may be useful on systems which have a small limit on the -size of command arguments. -.It Ar variable=value -Set the value of the variable -.Ar variable -to -.Ar value . -Normally, all values passed on the command line are also exported to -sub-makes in the environment. -The -.Fl X -flag disables this behavior. -Variable assignments should follow options for POSIX compatibility -but no ordering is enforced. -.El -.Pp -There are seven different types of lines in a makefile: file dependency -specifications, shell commands, variable assignments, include statements, -conditional directives, for loops, and comments. -.Pp -In general, lines may be continued from one line to the next by ending -them with a backslash -.Pq Ql \e . -The trailing newline character and initial whitespace on the following -line are compressed into a single space. -.Sh FILE DEPENDENCY SPECIFICATIONS -Dependency lines consist of one or more targets, an operator, and zero -or more sources. -This creates a relationship where the targets -.Dq depend -on the sources -and are usually created from them. -The exact relationship between the target and the source is determined -by the operator that separates them. -The three operators are as follows: -.Bl -tag -width flag -.It Ic \&: -A target is considered out-of-date if its modification time is less than -those of any of its sources. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&! -Targets are always re-created, but not until all sources have been -examined and re-created as necessary. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&:: -If no sources are specified, the target is always re-created. -Otherwise, a target is considered out-of-date if any of its sources has -been modified more recently than the target. -Sources for a target do not accumulate over dependency lines when this -operator is used. -The target will not be removed if -.Nm -is interrupted. -.El -.Pp -Targets and sources may contain the shell wildcard values -.Ql \&? , -.Ql * , -.Ql [] , -and -.Ql {} . -The values -.Ql \&? , -.Ql * , -and -.Ql [] -may only be used as part of the final -component of the target or source, and must be used to describe existing -files. -The value -.Ql {} -need not necessarily be used to describe existing files. -Expansion is in directory order, not alphabetically as done in the shell. -.Sh SHELL COMMANDS -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 -.Em must -be preceded by a tab. -(For historical reasons, spaces are not accepted.) -While targets can appear in many dependency lines if desired, by -default only one of these rules may be followed by a creation -script. -If the -.Ql Ic \&:: -operator is used, however, all rules may include scripts and the -scripts are executed in the order found. -.Pp -Each line is treated as a separate shell command, unless the end of -line is escaped with a backslash -.Pq Ql \e -in which case that line and the next are combined. -.\" The escaped newline is retained and passed to the shell, which -.\" normally ignores it. -.\" However, the tab at the beginning of the following line is removed. -If the first characters of the command are any combination of -.Ql Ic @ , -.Ql Ic + , -or -.Ql Ic \- , -the command is treated specially. -A -.Ql Ic @ -causes the command not to be echoed before it is executed. -A -.Ql Ic + -causes the command to be executed even when -.Fl n -is given. -This is similar to the effect of the .MAKE special source, -except that the effect can be limited to a single line of a script. -A -.Ql Ic \- -in compatibility mode -causes any non-zero exit status of the command line to be ignored. -.Pp -When -.Nm -is run in jobs mode with -.Fl j Ar max_jobs , -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 -.Pq Ql #=|^(){};&<>*?[]:$`\e\en -it will be passed to the shell; otherwise -.Nm -will attempt direct execution. -If a line starts with -.Ql Ic \- -and the shell has ErrCtl enabled then failure of the command line -will be ignored as in compatibility mode. -Otherwise -.Ql Ic \- -affects the entire job; -the script will stop at the first command line that fails, -but the target will not be deemed to have failed. -.Pp -Makefiles should be written so that the mode of -.Nm -operation does not change their behavior. -For example, any command which needs to use -.Dq cd -or -.Dq chdir -without potentially changing the directory for subsequent commands -should be put in parentheses so it executes in a subshell. -To force the use of one shell, escape the line breaks so as to make -the whole script one command. -For example: -.Bd -literal -offset indent -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`; \e - (cd ${.CURDIR} && ${MAKE} $@); \e - echo Back in `pwd` -.Ed -.Pp -Since -.Nm -will -.Xr chdir 2 -to -.Ql Va .OBJDIR -before executing any targets, each child process -starts with that as its current working directory. -.Sh VARIABLE ASSIGNMENTS -Variables in make are much like variables in the shell, and, by tradition, -consist of all upper-case letters. -.Ss Variable assignment modifiers -The five operators that can be used to assign values to variables are as -follows: -.Bl -tag -width Ds -.It Ic \&= -Assign the value to the variable. -Any previous value is overridden. -.It Ic \&+= -Append the value to the current value of the variable. -.It Ic \&?= -Assign the value to the variable if it is not already defined. -.It Ic \&:= -Assign with expansion, i.e. expand the value before assigning it -to the variable. -Normally, expansion is not done until the variable is referenced. -.Em NOTE : -References to undefined variables are -.Em not -expanded. -This can cause problems when variable modifiers are used. -.It Ic \&!= -Expand the value and pass it to the shell for execution and assign -the result to the variable. -Any newlines in the result are replaced with spaces. -.El -.Pp -Any white-space before the assigned -.Ar value -is removed; if the value is being appended, a single space is inserted -between the previous contents of the variable and the appended value. -.Pp -Variables are expanded by surrounding the variable name with either -curly braces -.Pq Ql {} -or parentheses -.Pq Ql () -and preceding it with -a dollar sign -.Pq Ql \&$ . -If the variable name contains only a single letter, the surrounding -braces or parentheses are not required. -This shorter form is not recommended. -.Pp -If the variable name contains a dollar, then the name itself is expanded first. -This allows almost arbitrary variable names, however names containing dollar, -braces, parenthesis, or whitespace are really best avoided! -.Pp -If the result of expanding a variable contains a dollar sign -.Pq Ql \&$ -the string is expanded again. -.Pp -Variable substitution occurs at three distinct times, depending on where -the variable is being used. -.Bl -enum -.It -Variables in dependency lines are expanded as the line is read. -.It -Variables in shell commands are expanded when the shell command is -executed. -.It -.Dq .for -loop index variables are expanded on each loop iteration. -Note that other variables are not expanded inside loops so -the following example code: -.Bd -literal -offset indent - -.Dv .for i in 1 2 3 -a+= ${i} -j= ${i} -b+= ${j} -.Dv .endfor - -all: - @echo ${a} - @echo ${b} - -.Ed -will print: -.Bd -literal -offset indent -1 2 3 -3 3 3 - -.Ed -Because while ${a} contains -.Dq 1 2 3 -after the loop is executed, ${b} -contains -.Dq ${j} ${j} ${j} -which expands to -.Dq 3 3 3 -since after the loop completes ${j} contains -.Dq 3 . -.El -.Ss Variable classes -The four different classes of variables (in order of increasing precedence) -are: -.Bl -tag -width Ds -.It Environment variables -Variables defined as part of -.Nm Ns 's -environment. -.It Global variables -Variables defined in the makefile or in included makefiles. -.It Command line variables -Variables defined as part of the command line. -.It Local variables -Variables that are defined specific to a certain target. -.El -.Pp -Local variables are all built in and their values vary magically from -target to target. -It is not currently possible to define new local variables. -The seven local variables are as follows: -.Bl -tag -width ".ARCHIVE" -offset indent -.It Va .ALLSRC -The list of all sources for this target; also known as -.Ql Va \&\*[Gt] . -.It Va .ARCHIVE -The name of the archive file; also known as -.Ql Va \&! . -.It Va .IMPSRC -In suffix-transformation rules, the name/path of the source from which the -target is to be transformed (the -.Dq implied -source); also known as -.Ql Va \&\*[Lt] . -It is not defined in explicit rules. -.It Va .MEMBER -The name of the archive member; also known as -.Ql Va % . -.It Va .OODATE -The list of sources for this target that were deemed out-of-date; also -known as -.Ql Va \&? . -.It Va .PREFIX -The file prefix of the target, containing only the file portion, no suffix -or preceding directory components; also known as -.Ql Va * . -The suffix must be one of the known suffixes declared with -.Ic .SUFFIXES -or it will not be recognized. -.It Va .TARGET -The name of the target; also known as -.Ql Va @ . -.El -.Pp -The shorter forms -.Ql ( Va \*[Gt] , -.Ql Va \&! , -.Ql Va \*[Lt] , -.Ql Va % , -.Ql Va \&? , -.Ql Va * , -and -.Ql Va @ ) -are permitted for backward -compatibility with historical makefiles and legacy POSIX make and are -not recommended. -.Pp -Variants of these variables with the punctuation followed immediately by -.Ql D -or -.Ql F , -e.g. -.Ql Va $(@D) , -are legacy forms equivalent to using the -.Ql :H -and -.Ql :T -modifiers. -These forms are accepted for compatibility with -.At V -makefiles and POSIX but are not recommended. -.Pp -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 -.Ql Va .TARGET , -.Ql Va .PREFIX , -.Ql Va .ARCHIVE , -and -.Ql Va .MEMBER . -.Ss Additional built-in variables -In addition, -.Nm -sets or knows about the following variables: -.Bl -tag -width .MAKEOVERRIDES -.It Va \&$ -A single dollar sign -.Ql \&$ , -i.e. -.Ql \&$$ -expands to a single dollar -sign. -.It Va .ALLTARGETS -The list of all targets encountered in the Makefile. -If evaluated during -Makefile parsing, lists only those targets encountered thus far. -.It Va .CURDIR -A path to the directory where -.Nm -was executed. -Refer to the description of -.Ql Ev PWD -for more details. -.It Va .INCLUDEDFROMDIR -The directory of the file this Makefile was included from. -.It Va .INCLUDEDFROMFILE -The filename of the file this Makefile was included from. -.It Ev MAKE -The name that -.Nm -was executed with -.Pq Va argv[0] . -For compatibility -.Nm -also sets -.Va .MAKE -with the same value. -The preferred variable to use is the environment variable -.Ev MAKE -because it is more compatible with other versions of -.Nm -and cannot be confused with the special target with the same name. -.It Va .MAKE.DEPENDFILE -Names the makefile (default -.Ql Pa .depend ) -from which generated dependencies are read. -.It Va .MAKE.EXPAND_VARIABLES -A boolean that controls the default behavior of the -.Fl V -option. -.It Va .MAKE.EXPORTED -The list of variables exported by -.Nm . -.It Va .MAKE.JOBS -The argument to the -.Fl j -option. -.It Va .MAKE.JOB.PREFIX -If -.Nm -is run with -.Ar j -then output for each target is prefixed with a token -.Ql --- target --- -the first part of which can be controlled via -.Va .MAKE.JOB.PREFIX . -If -.Va .MAKE.JOB.PREFIX -is empty, no token is printed. -.br -For example: -.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] -would produce tokens like -.Ql ---make[1234] target --- -making it easier to track the degree of parallelism being achieved. -.It Ev MAKEFLAGS -The environment variable -.Ql Ev MAKEFLAGS -may contain anything that -may be specified on -.Nm Ns 's -command line. -Anything specified on -.Nm Ns 's -command line is appended to the -.Ql Ev MAKEFLAGS -variable which is then -entered into the environment for all programs which -.Nm -executes. -.It Va .MAKE.LEVEL -The recursion depth of -.Nm . -The initial instance of -.Nm -will be 0, and an incremented value is put into the environment -to be seen by the next generation. -This allows tests like: -.Li .if ${.MAKE.LEVEL} == 0 -to protect things which should only be evaluated in the initial instance of -.Nm . -.It Va .MAKE.MAKEFILE_PREFERENCE -The ordered list of makefile names -(default -.Ql Pa makefile , -.Ql Pa Makefile ) -that -.Nm -will look for. -.It Va .MAKE.MAKEFILES -The list of makefiles read by -.Nm , -which is useful for tracking dependencies. -Each makefile is recorded only once, regardless of the number of times read. -.It Va .MAKE.MODE -Processed after reading all makefiles. -Can affect the mode that -.Nm -runs in. -It can contain a number of keywords: -.Bl -hang -width ignore-cmd -.It Pa compat -Like -.Fl B , -puts -.Nm -into "compat" mode. -.It Pa meta -Puts -.Nm -into "meta" mode, where meta files are created for each target -to capture the command run, the output generated and if -.Xr filemon 4 -is available, the system calls which are of interest to -.Nm . -The captured output can be very useful when diagnosing errors. -.It Pa curdirOk= Ar bf -Normally -.Nm -will not create .meta files in -.Ql Va .CURDIR . -This can be overridden by setting -.Va bf -to a value which represents True. -.It Pa env -For debugging, it can be useful to inlcude the environment -in the .meta file. -.It Pa verbose -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 the value of: -.Va .MAKE.META.PREFIX . -.It Pa ignore-cmd -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 -.Ic .NOMETA_CMP . -.It Pa silent= Ar bf -If -.Va bf -is True, when a .meta file is created, mark the target -.Ic .SILENT . -.El -.It Va .MAKE.META.BAILIWICK -In "meta" mode, provides a list of prefixes which -match the directories controlled by -.Nm . -If a file that was generated outside of -.Va .OBJDIR -but within said bailiwick is missing, -the current target is considered out-of-date. -.It Va .MAKE.META.CREATED -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 -.Va .MAKE.META.FILES . -.It Va .MAKE.META.FILES -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. -.It Va .MAKE.META.IGNORE_PATHS -Provides a list of path prefixes that should be ignored; -because the contents are expected to change over time. -The default list includes: -.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp -.It Va .MAKE.META.PREFIX -Defines the message printed for each meta file updated in "meta verbose" mode. -The default value is: -.Dl Building ${.TARGET:H:tA}/${.TARGET:T} -.It Va .MAKEOVERRIDES -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 -.Ql Ev MAKEFLAGS . -This behaviour can be disabled by assigning an empty value to -.Ql Va .MAKEOVERRIDES -within a makefile. -Extra variables can be exported from a makefile -by appending their names to -.Ql Va .MAKEOVERRIDES . -.Ql Ev MAKEFLAGS -is re-exported whenever -.Ql Va .MAKEOVERRIDES -is modified. -.It Va .MAKE.PATH_FILEMON -If -.Nm -was built with -.Xr filemon 4 -support, this is set to the path of the device node. -This allows makefiles to test for this support. -.It Va .MAKE.PID -The process-id of -.Nm . -.It Va .MAKE.PPID -The parent process-id of -.Nm . -.It Va MAKE_PRINT_VAR_ON_ERROR -When -.Nm -stops due to an error, it prints its name and the value of -.Ql Va .CURDIR -as well as the value of any variables named in -.Ql Va MAKE_PRINT_VAR_ON_ERROR . -.It Va .newline -This variable is simply assigned a newline character as its value. -This allows expansions using the -.Cm \&:@ -modifier to put a newline between -iterations of the loop rather than a space. -For example, the printing of -.Ql Va MAKE_PRINT_VAR_ON_ERROR -could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}. -.It Va .OBJDIR -A path to the directory where the targets are built. -Its value is determined by trying to -.Xr chdir 2 -to the following directories in order and using the first match: -.Bl -enum -.It -.Ev ${MAKEOBJDIRPREFIX}${.CURDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIRPREFIX -is set in the environment or on the command line.) -.It -.Ev ${MAKEOBJDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIR -is set in the environment or on the command line.) -.It -.Ev ${.CURDIR} Ns Pa /obj. Ns Ev ${MACHINE} -.It -.Ev ${.CURDIR} Ns Pa /obj -.It -.Pa /usr/obj/ Ns Ev ${.CURDIR} -.It -.Ev ${.CURDIR} -.El -.Pp -Variable expansion is performed on the value before it's used, -so expressions such as -.Dl ${.CURDIR:S,^/usr/src,/var/obj,} -may be used. -This is especially useful with -.Ql Ev MAKEOBJDIR . -.Pp -.Ql Va .OBJDIR -may be modified in the makefile via the special target -.Ql Ic .OBJDIR . -In all cases, -.Nm -will -.Xr chdir 2 -to the specified directory if it exists, and set -.Ql Va .OBJDIR -and -.Ql Ev PWD -to that directory before executing any targets. -. -.It Va .PARSEDIR -A path to the directory of the current -.Ql Pa Makefile -being parsed. -.It Va .PARSEFILE -The basename of the current -.Ql Pa Makefile -being parsed. -This variable and -.Ql Va .PARSEDIR -are both set only while the -.Ql Pa Makefiles -are being parsed. -If you want to retain their current values, assign them to a variable -using assignment with expansion: -.Pq Ql Cm \&:= . -.It Va .PATH -A variable that represents the list of directories that -.Nm -will search for files. -The search list should be updated using the target -.Ql Va .PATH -rather than the variable. -.It Ev PWD -Alternate path to the current directory. -.Nm -normally sets -.Ql Va .CURDIR -to the canonical path given by -.Xr getcwd 3 . -However, if the environment variable -.Ql Ev PWD -is set and gives a path to the current directory, then -.Nm -sets -.Ql Va .CURDIR -to the value of -.Ql Ev PWD -instead. -This behaviour is disabled if -.Ql Ev MAKEOBJDIRPREFIX -is set or -.Ql Ev MAKEOBJDIR -contains a variable transform. -.Ql Ev PWD -is set to the value of -.Ql Va .OBJDIR -for all programs which -.Nm -executes. -.It Ev .TARGETS -The list of targets explicitly specified on the command line, if any. -.It Ev VPATH -Colon-separated -.Pq Dq \&: -lists of directories that -.Nm -will search for files. -The variable is supported for compatibility with old make programs only, -use -.Ql Va .PATH -instead. -.El -.Ss Variable modifiers -Variable expansion may be modified to select or modify each word of the -variable (where a -.Dq word -is white-space delimited sequence of characters). -The general format of a variable expansion is as follows: -.Pp -.Dl ${variable[:modifier[:...]]} -.Pp -Each modifier begins with a colon, -which may be escaped with a backslash -.Pq Ql \e . -.Pp -A set of modifiers can be specified via a variable, as follows: -.Pp -.Dl modifier_variable=modifier[:...] -.Dl ${variable:${modifier_variable}[:...]} -.Pp -In this case the first modifier in the modifier_variable does not -start with a colon, since that must appear in the referencing -variable. -If any of the modifiers in the modifier_variable contain a dollar sign -.Pq Ql $ , -these must be doubled to avoid early expansion. -.Pp -The supported modifiers are: -.Bl -tag -width EEE -.It Cm \&:E -Replaces each word in the variable with its suffix. -.It Cm \&:H -Replaces each word in the variable with everything but the last component. -.It Cm \&:M Ns Ar pattern -Select only those words that match -.Ar pattern . -The standard shell wildcard characters -.Pf ( Ql * , -.Ql \&? , -and -.Ql Oo Oc ) -may -be used. -The wildcard characters may be escaped with a backslash -.Pq Ql \e . -As a consequence of the way values are split into words, matched, -and then joined, a construct like -.Dl ${VAR:M*} -will normalise the inter-word spacing, removing all leading and -trailing space, and converting multiple consecutive spaces -to single spaces. -. -.It Cm \&:N Ns Ar pattern -This is identical to -.Ql Cm \&:M , -but selects all words which do not match -.Ar pattern . -.It Cm \&:O -Order every word in variable alphabetically. -To sort words in -reverse order use the -.Ql Cm \&:O:[-1..1] -combination of modifiers. -.It Cm \&:Ox -Randomize words in variable. -The results will be different each time you are referring to the -modified variable; use the assignment with expansion -.Pq Ql Cm \&:= -to prevent such behaviour. -For example, -.Bd -literal -offset indent -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}" -.Ed -may produce output similar to: -.Bd -literal -offset indent -quattro due tre uno -tre due quattro uno -due uno quattro tre -due uno quattro tre -.Ed -.It Cm \&:Q -Quotes every shell meta-character in the variable, so that it can be passed -safely through recursive invocations of -.Nm . -.It Cm \&:R -Replaces each word in the variable with everything but its suffix. -.It Cm \&:gmtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr gmtime 3 . -.It Cm \&:hash -Compute a 32bit hash of the value and encode it as hex digits. -.It Cm \&:localtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr localtime 3 . -.It Cm \&:tA -Attempt to convert variable to an absolute path using -.Xr realpath 3 , -if that fails, the value is unchanged. -.It Cm \&:tl -Converts variable to lower-case letters. -.It Cm \&:ts Ns Ar c -Words in the variable are normally separated by a space on expansion. -This modifier sets the separator to the character -.Ar c . -If -.Ar c -is omitted, then no separator is used. -The common escapes (including octal numeric codes), work as expected. -.It Cm \&:tu -Converts variable to upper-case letters. -.It Cm \&:tW -Causes the value to be treated as a single word -(possibly containing embedded white space). -See also -.Ql Cm \&:[*] . -.It Cm \&:tw -Causes the value to be treated as a sequence of -words delimited by white space. -See also -.Ql Cm \&:[@] . -.Sm off -.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW -.Sm on -Modify the first occurrence of -.Ar old_string -in the variable's value, replacing it with -.Ar new_string . -If a -.Ql g -is appended to the last slash of the pattern, all occurrences -in each word are replaced. -If a -.Ql 1 -is appended to the last slash of the pattern, only the first word -is affected. -If a -.Ql W -is appended to the last slash of the pattern, -then the value is treated as a single word -(possibly containing embedded white space). -If -.Ar old_string -begins with a caret -.Pq Ql ^ , -.Ar old_string -is anchored at the beginning of each word. -If -.Ar old_string -ends with a dollar sign -.Pq Ql \&$ , -it is anchored at the end of each word. -Inside -.Ar new_string , -an ampersand -.Pq Ql \*[Am] -is replaced by -.Ar old_string -(without any -.Ql ^ -or -.Ql \&$ ) . -Any character may be used as a delimiter for the parts of the modifier -string. -The anchoring, ampersand and delimiter characters may be escaped with a -backslash -.Pq Ql \e . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the expansion -of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW -.Sm on -The -.Cm \&:C -modifier is just like the -.Cm \&:S -modifier except that the old and new strings, instead of being -simple strings, are an extended regular expression (see -.Xr regex 3 ) -string -.Ar pattern -and an -.Xr ed 1 Ns \-style -string -.Ar replacement . -Normally, the first occurrence of the pattern -.Ar pattern -in each word of the value is substituted with -.Ar replacement . -The -.Ql 1 -modifier causes the substitution to apply to at most one word; the -.Ql g -modifier causes the substitution to apply to as many instances of the -search pattern -.Ar pattern -as occur in the word or words it is found in; the -.Ql W -modifier causes the value to be treated as a single word -(possibly containing embedded white space). -Note that -.Ql 1 -and -.Ql g -are orthogonal; the former specifies whether multiple words are -potentially affected, the latter whether multiple substitutions can -potentially occur within each affected word. -.Pp -As for the -.Cm \&:S -modifier, the -.Ar pattern -and -.Ar replacement -are subjected to variable expansion before being parsed as -regular expressions. -.It Cm \&:T -Replaces each word in the variable with its last component. -.It Cm \&:u -Remove adjacent duplicate words (like -.Xr uniq 1 ) . -.Sm off -.It Cm \&:\&? Ar true_string Cm \&: Ar false_string -.Sm on -If the variable name (not its value), when parsed as a .if conditional -expression, evaluates to true, return as its value the -.Ar true_string , -otherwise return the -.Ar false_string . -Since the variable name is used as the expression, \&:\&? must be the -first modifier after the variable name itself - which will, of course, -usually contain variable expansions. -A common error is trying to use expressions like -.Dl ${NUMBERS:M42:?match:no} -which actually tests defined(NUMBERS), -to determine is any words match "42" you need to use something like: -.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} . -.It Ar :old_string=new_string -This is the -.At V -style variable substitution. -It must be the last modifier specified. -If -.Ar old_string -or -.Ar new_string -do not contain the pattern matching character -.Ar % -then it is assumed that they are -anchored at the end of each word, so only suffixes or entire -words may be replaced. -Otherwise -.Ar % -is the substring of -.Ar old_string -to be replaced in -.Ar new_string . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the -expansion of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:@ Ar temp Cm @ Ar string Cm @ -.Sm on -This is the loop expansion mechanism from the OSF Development -Environment (ODE) make. -Unlike -.Cm \&.for -loops expansion occurs at the time of -reference. -Assign -.Ar temp -to each word in the variable and evaluate -.Ar string . -The ODE convention is that -.Ar temp -should start and end with a period. -For example. -.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@} -.Pp -However a single character variable is often more readable: -.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} -.It Cm \&:U Ns Ar newval -If the variable is undefined -.Ar newval -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: -.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}} -If a value is only required if the variable is undefined, use: -.Dl ${VAR:D:Unewval} -.It Cm \&:D Ns Ar newval -If the variable is defined -.Ar newval -is the value. -.It Cm \&:L -The name of the variable is the value. -.It Cm \&:P -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, then the -name of the variable is used. -In order for this modifier to work, the name (node) must at least have -appeared on the rhs of a dependency. -.Sm off -.It Cm \&:\&! Ar cmd Cm \&! -.Sm on -The output of running -.Ar cmd -is the value. -.It Cm \&:sh -If the variable is non-empty it is run as a command and the output -becomes the new value. -.It Cm \&::= Ns Ar str -The variable is assigned the value -.Ar str -after substitution. -This modifier and its variations are useful in -obscure situations such as wanting to set a variable when shell commands -are being parsed. -These assignment modifiers always expand to -nothing, so if appearing in a rule line by themselves should be -preceded with something to keep -.Nm -happy. -.Pp -The -.Ql Cm \&:: -helps avoid false matches with the -.At V -style -.Cm \&:= -modifier and since substitution always occurs the -.Cm \&::= -form is vaguely appropriate. -.It Cm \&::?= Ns Ar str -As for -.Cm \&::= -but only if the variable does not already have a value. -.It Cm \&::+= Ns Ar str -Append -.Ar str -to the variable. -.It Cm \&::!= Ns Ar cmd -Assign the output of -.Ar cmd -to the variable. -.It Cm \&:\&[ Ns Ar range Ns Cm \&] -Selects one or more words from the value, -or performs other operations related to the way in which the -value is divided into words. -.Pp -Ordinarily, a value is treated as a sequence of words -delimited by white space. -Some modifiers suppress this behaviour, -causing a value to be treated as a single word -(possibly containing embedded white space). -An empty value, or a value that consists entirely of white-space, -is treated as a single word. -For the purposes of the -.Ql Cm \&:[] -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). -.Pp -The -.Ar range -is subjected to variable expansion, and the expanded result is -then interpreted as follows: -.Bl -tag -width index -.\" :[n] -.It Ar index -Selects a single word from the value. -.\" :[start..end] -.It Ar start Ns Cm \&.. Ns Ar end -Selects all words from -.Ar start -to -.Ar end , -inclusive. -For example, -.Ql Cm \&:[2..-1] -selects all words from the second word to the last word. -If -.Ar start -is greater than -.Ar end , -then the words are output in reverse order. -For example, -.Ql Cm \&:[-1..1] -selects all the words from last to first. -.\" :[*] -.It Cm \&* -Causes subsequent modifiers to treat the value as a single word -(possibly containing embedded white space). -Analogous to the effect of -\&"$*\&" -in Bourne shell. -.\" :[0] -.It 0 -Means the same as -.Ql Cm \&:[*] . -.\" :[*] -.It Cm \&@ -Causes subsequent modifiers to treat the value as a sequence of words -delimited by white space. -Analogous to the effect of -\&"$@\&" -in Bourne shell. -.\" :[#] -.It Cm \&# -Returns the number of words in the value. -.El \" :[range] -.El -.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS -Makefile inclusion, conditional structures and for loops reminiscent -of the C programming language are provided in -.Nm . -All such structures are identified by a line beginning with a single -dot -.Pq Ql \&. -character. -Files are included with either -.Cm \&.include Aq Ar file -or -.Cm \&.include Pf \*q Ar file Ns \*q . -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 -.Fl I -option are searched before the system -makefile directory. -For compatibility with other versions of -.Nm -.Ql include file ... -is also accepted. -If the include statement is written as -.Cm .-include -or as -.Cm .sinclude -then errors locating and/or opening include files are ignored. -.Pp -Conditional expressions are also preceded by a single dot as the first -character of a line. -The possible conditionals are as follows: -.Bl -tag -width Ds -.It Ic .error Ar message -The message is printed along with the name of the makefile and line number, -then -.Nm -will exit. -.It Ic .export Ar variable ... -Export the specified global variable. -If no variable list is provided, all globals are exported -except for internal variables (those that start with -.Ql \&. ) . -This is not affected by the -.Fl X -flag, so should be used with caution. -For compatibility with other -.Nm -programs -.Ql export variable=value -is also accepted. -.Pp -Appending a variable name to -.Va .MAKE.EXPORTED -is equivalent to exporting a variable. -.It Ic .export-env Ar variable ... -The same as -.Ql .export , -except that the variable is not appended to -.Va .MAKE.EXPORTED . -This allows exporting a value to the environment which is different from that -used by -.Nm -internally. -.It Ic .info Ar message -The message is printed along with the name of the makefile and line number. -.It Ic .undef Ar variable -Un-define the specified global variable. -Only global variables may be un-defined. -.It Ic .unexport Ar variable ... -The opposite of -.Ql .export . -The specified global -.Va variable -will be removed from -.Va .MAKE.EXPORTED . -If no variable list is provided, all globals are unexported, -and -.Va .MAKE.EXPORTED -deleted. -.It Ic .unexport-env -Unexport all globals previously exported and -clear the environment inherited from the parent. -This operation will cause a memory leak of the original environment, -so should be used sparingly. -Testing for -.Va .MAKE.LEVEL -being 0, would make sense. -Also note that any variables which originated in the parent environment -should be explicitly preserved if desired. -For example: -.Bd -literal -offset indent -.Li .if ${.MAKE.LEVEL} == 0 -PATH := ${PATH} -.Li .unexport-env -.Li .export PATH -.Li .endif -.Pp -.Ed -Would result in an environment containing only -.Ql Ev PATH , -which is the minimal useful environment. -Actually -.Ql Ev .MAKE.LEVEL -will also be pushed into the new environment. -.It Ic .warning Ar message -The message prefixed by -.Ql Pa warning: -is printed along with the name of the makefile and line number. -.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ... -Test the value of an expression. -.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -Test the target being built. -.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ... -Test the target being built. -.It Ic .else -Reverse the sense of the last conditional. -.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .if . -.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifdef . -.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifndef . -.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifmake . -.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifnmake . -.It Ic .endif -End the body of the conditional. -.El -.Pp -The -.Ar operator -may be any one of the following: -.Bl -tag -width "Cm XX" -.It Cm \&|\&| -Logical OR. -.It Cm \&\*[Am]\*[Am] -Logical -.Tn AND ; -of higher precedence than -.Dq \&|\&| . -.El -.Pp -As in C, -.Nm -will only evaluate a conditional as far as is necessary to determine -its value. -Parentheses may be used to change the order of evaluation. -The boolean operator -.Ql Ic \&! -may be used to logically negate an entire -conditional. -It is of higher precedence than -.Ql Ic \&\*[Am]\*[Am] . -.Pp -The value of -.Ar expression -may be any of the following: -.Bl -tag -width defined -.It Ic defined -Takes a variable name as an argument and evaluates to true if the variable -has been defined. -.It Ic make -Takes a target name as an argument and evaluates to true if the target -was specified as part of -.Nm Ns 's -command line or was declared the default target (either implicitly or -explicitly, see -.Va .MAIN ) -before the line containing the conditional. -.It Ic empty -Takes a variable, with possible modifiers, and evaluates to true if -the expansion of the variable would result in an empty string. -.It Ic exists -Takes a file name as an argument and evaluates to true if the file exists. -The file is searched for on the system search path (see -.Va .PATH ) . -.It Ic target -Takes a target name as an argument and evaluates to true if the target -has been defined. -.It Ic commands -Takes a target name as an argument and evaluates to true if the target -has been defined and has commands associated with it. -.El -.Pp -.Ar Expression -may also be an arithmetic or string comparison. -Variable expansion is -performed on both sides of the comparison, after which the integral -values are compared. -A value is interpreted as hexadecimal if it is -preceded by 0x, otherwise it is decimal; octal numbers are not supported. -The standard C relational operators are all supported. -If after -variable expansion, either the left or right hand side of a -.Ql Ic == -or -.Ql Ic "!=" -operator is not an integral value, then -string comparison is performed between the expanded -variables. -If no relational operator is given, it is assumed that the expanded -variable is being compared against 0 or an empty string in the case -of a string comparison. -.Pp -When -.Nm -is evaluating one of these conditional expressions, and it encounters -a (white-space separated) word it doesn't recognize, either the -.Dq make -or -.Dq defined -expression is applied to it, depending on the form of the conditional. -If the form is -.Ql Ic .ifdef , -.Ql Ic .ifndef , -or -.Ql Ic .if -the -.Dq defined -expression is applied. -Similarly, if the form is -.Ql Ic .ifmake -or -.Ql Ic .ifnmake , the -.Dq make -expression is applied. -.Pp -If the conditional evaluates to true the parsing of the makefile continues -as before. -If it evaluates to false, the following lines are skipped. -In both cases this continues until a -.Ql Ic .else -or -.Ql Ic .endif -is found. -.Pp -For loops are typically used to apply a set of rules to a list of files. -The syntax of a for loop is: -.Pp -.Bl -tag -compact -width Ds -.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression -.It Aq make-rules -.It Ic \&.endfor -.El -.Pp -After the for -.Ic expression -is evaluated, it is split into words. -On each iteration of the loop, one word is taken and assigned to each -.Ic variable , -in order, and these -.Ic variables -are substituted into the -.Ic make-rules -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. -.Sh COMMENTS -Comments begin with a hash -.Pq Ql \&# -character, anywhere but in a shell -command line, and continue to the end of an unescaped new line. -.Sh SPECIAL SOURCES (ATTRIBUTES) -.Bl -tag -width .IGNOREx -.It Ic .EXEC -Target is never out of date, but always execute commands anyway. -.It Ic .IGNORE -Ignore any errors from the commands associated with this target, exactly -as if they all were preceded by a dash -.Pq Ql \- . -.\" .It Ic .INVISIBLE -.\" XXX -.\" .It Ic .JOIN -.\" XXX -.It Ic .MADE -Mark all sources of this target as being up-to-date. -.It Ic .MAKE -Execute the commands associated with this target even if the -.Fl n -or -.Fl t -options were specified. -Normally used to mark recursive -.Nm Ns s . -.It Ic .META -Create a meta file for the target, even if it is flagged as -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL . -Usage in conjunction with -.Ic .MAKE -is the most likely case. -In "meta" mode, the target is out-of-date if the meta file is missing. -.It Ic .NOMETA -Do not create a meta file for the target. -Meta files are also not created for -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL -targets. -.It Ic .NOMETA_CMP -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 will still be out of date. -The same effect applies to any command line that uses the variable -.Va .OODATE , -which can be used for that purpose even when not otherwise needed or desired: -.Bd -literal -offset indent - -skip-compare-for-some: - @echo this will be compared - @echo this will not ${.OODATE:M.NOMETA_CMP} - @echo this will also be compared - -.Ed -The -.Cm \&:M -pattern suppresses any expansion of the unwanted variable. -.It Ic .NOPATH -Do not search for the target in the directories specified by -.Ic .PATH . -.It Ic .NOTMAIN -Normally -.Nm -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. -.It Ic .OPTIONAL -If a target is marked with this attribute and -.Nm -can't figure out how to create it, it will ignore this fact and assume -the file isn't needed or already exists. -.It Ic .PHONY -The target does not -correspond to an actual file; it is always considered to be out of date, -and will not be created with the -.Fl t -option. -Suffix-transformation rules are not applied to -.Ic .PHONY -targets. -.It Ic .PRECIOUS -When -.Nm -is interrupted, it normally removes any partially made targets. -This source prevents the target from being removed. -.It Ic .RECURSIVE -Synonym for -.Ic .MAKE . -.It Ic .SILENT -Do not echo any of the commands associated with this target, exactly -as if they all were preceded by an at sign -.Pq Ql @ . -.It Ic .USE -Turn the target into -.Nm Ns '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 -.Ic .USE ) -of the -source. -If the target already has commands, the -.Ic .USE -target's commands are appended -to them. -.It Ic .USEBEFORE -Exactly like -.Ic .USE , -but prepend the -.Ic .USEBEFORE -target commands to the target. -.It Ic .WAIT -If -.Ic .WAIT -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: -.Bd -literal -x: a .WAIT b - echo x -a: - echo a -b: b1 - echo b -b1: - echo b1 - -.Ed -the output is always -.Ql a , -.Ql b1 , -.Ql b , -.Ql x . -.br -The ordering imposed by -.Ic .WAIT -is only relevant for parallel makes. -.El -.Sh SPECIAL TARGETS -Special targets may not be included with other targets, i.e. they must be -the only target specified. -.Bl -tag -width .BEGINx -.It Ic .BEGIN -Any command lines attached to this target are executed before anything -else is done. -.It Ic .DEFAULT -This is sort of a -.Ic .USE -rule for any target (that was used only as a -source) that -.Nm -can't figure out any other way to create. -Only the shell script is used. -The -.Ic .IMPSRC -variable of a target that inherits -.Ic .DEFAULT Ns 's -commands is set -to the target's own name. -.It Ic .END -Any command lines attached to this target are executed after everything -else is done. -.It Ic .ERROR -Any command lines attached to this target are executed when another target fails. -The -.Ic .ERROR_TARGET -variable is set to the target that failed. -See also -.Ic MAKE_PRINT_VAR_ON_ERROR . -.It Ic .IGNORE -Mark each of the sources with the -.Ic .IGNORE -attribute. -If no sources are specified, this is the equivalent of specifying the -.Fl i -option. -.It Ic .INTERRUPT -If -.Nm -is interrupted, the commands for this target will be executed. -.It Ic .MAIN -If no target is specified when -.Nm -is invoked, this target will be built. -.It Ic .MAKEFLAGS -This target provides a way to specify flags for -.Nm -when the makefile is used. -The flags are as if typed to the shell, though the -.Fl f -option will have -no effect. -.\" XXX: NOT YET!!!! -.\" .It Ic .NOTPARALLEL -.\" The named targets are executed in non parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in non parallel mode. -.It Ic .NOPATH -Apply the -.Ic .NOPATH -attribute to any specified sources. -.It Ic .NOTPARALLEL -Disable parallel mode. -.It Ic .NO_PARALLEL -Synonym for -.Ic .NOTPARALLEL , -for compatibility with other pmake variants. -.It Ic .OBJDIR -The source is a new value for -.Ql Va .OBJDIR . -If it exists, -.Nm -will -.Xr chdir 2 -to it and update the value of -.Ql Va .OBJDIR . -.It Ic .ORDER -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 -.Ql a -is built by another part of the dependency graph, -the following is a dependency loop: -.Bd -literal -\&.ORDER: b a -b: a -.Ed -.Pp -The ordering imposed by -.Ic .ORDER -is only relevant for parallel makes. -.\" XXX: NOT YET!!!! -.\" .It Ic .PARALLEL -.\" The named targets are executed in parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in parallel mode. -.It Ic .PATH -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 -deleted. -If the source is the special -.Ic .DOTLAST -target, then the current working -directory is searched last. -.It Ic .PATH. Ns Va suffix -Like -.Ic .PATH -but applies only to files with a particular suffix. -The suffix must have been previously declared with -.Ic .SUFFIXES . -.It Ic .PHONY -Apply the -.Ic .PHONY -attribute to any specified sources. -.It Ic .PRECIOUS -Apply the -.Ic .PRECIOUS -attribute to any specified sources. -If no sources are specified, the -.Ic .PRECIOUS -attribute is applied to every -target in the file. -.It Ic .SHELL -Sets the shell that -.Nm -will use to execute commands. -The sources are a set of -.Ar field=value -pairs. -.Bl -tag -width hasErrCtls -.It Ar name -This is the minimal specification, used to select one of the builtin -shell specs; -.Ar sh , -.Ar ksh , -and -.Ar csh . -.It Ar path -Specifies the path to the shell. -.It Ar hasErrCtl -Indicates whether the shell supports exit on error. -.It Ar check -The command to turn on error checking. -.It Ar ignore -The command to disable error checking. -.It Ar echo -The command to turn on echoing of commands executed. -.It Ar quiet -The command to turn off echoing of commands executed. -.It Ar filter -The output to filter after issuing the -.Ar quiet -command. -It is typically identical to -.Ar quiet . -.It Ar errFlag -The flag to pass the shell to enable error checking. -.It Ar echoFlag -The flag to pass the shell to enable command echoing. -.It Ar newline -The string literal to pass the shell that results in a single newline -character when used outside of any quoting characters. -.El -Example: -.Bd -literal -\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e - check="set \-e" ignore="set +e" \e - echo="set \-v" quiet="set +v" filter="set +v" \e - echoFlag=v errFlag=e newline="'\en'" -.Ed -.It Ic .SILENT -Apply the -.Ic .SILENT -attribute to any specified sources. -If no sources are specified, the -.Ic .SILENT -attribute is applied to every -command in the file. -.It Ic .STALE -This target gets run when a dependency file contains stale entries, having -.Va .ALLSRC -set to the name of that dependency file. -.It Ic .SUFFIXES -Each source specifies a suffix to -.Nm . -If no sources are specified, any previously specified suffixes are deleted. -It allows the creation of suffix-transformation rules. -.Pp -Example: -.Bd -literal -\&.SUFFIXES: .o -\&.c.o: - cc \-o ${.TARGET} \-c ${.IMPSRC} -.Ed -.El -.Sh ENVIRONMENT -.Nm -uses the following environment variables, if they exist: -.Ev MACHINE , -.Ev MACHINE_ARCH , -.Ev MAKE , -.Ev MAKEFLAGS , -.Ev MAKEOBJDIR , -.Ev MAKEOBJDIRPREFIX , -.Ev MAKESYSPATH , -.Ev PWD , -and -.Ev TMPDIR . -.Pp -.Ev MAKEOBJDIRPREFIX -and -.Ev MAKEOBJDIR -may only be set in the environment or on the command line to -.Nm -and not as makefile variables; -see the description of -.Ql Va .OBJDIR -for more details. -.Sh FILES -.Bl -tag -width /usr/share/mk -compact -.It .depend -list of dependencies -.It Makefile -list of dependencies -.It makefile -list of dependencies -.It sys.mk -system makefile -.It /usr/share/mk -system makefile directory -.El -.Sh COMPATIBILITY -The basic make syntax is compatible between different versions of make; -however the special variables, variable modifiers and conditionals are not. -.Ss Older versions -An incomplete list of changes in older versions of -.Nm : -.Pp -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. -.Pp -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. -.Ss Other make dialects -Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not -support most of the features of -.Nm -as described in this manual. -Most notably: -.Bl -bullet -offset indent -.It -The -.Ic .WAIT -and -.Ic .ORDER -declarations and most functionality pertaining to parallelization. -(GNU make supports parallelization but lacks these features needed to -control it effectively.) -.It -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.) -.It -All built-in variables that begin with a dot. -.It -Most of the special sources and targets that begin with a dot, -with the notable exception of -.Ic .PHONY , -.Ic .PRECIOUS , -and -.Ic .SUFFIXES . -.It -Variable modifiers, except for the -.Dl :old=new -string substitution, which does not portably support globbing with -.Ql % -and historically only works on declared suffixes. -.It -The -.Ic $> -variable even in its short form; most makes support this functionality -but its name varies. -.El -.Pp -Some features are somewhat more portable, such as assignment with -.Ic += , -.Ic ?= , -and -.Ic != . -The -.Ic .PATH -functionality is based on an older feature -.Ic VPATH -found in GNU make and many versions of SVR4 make; however, -historically its behavior is too ill-defined (and too buggy) to rely -upon. -.Pp -The -.Ic $@ -and -.Ic $< -variables are more or less universally portable, as is the -.Ic $(MAKE) -variable. -Basic use of suffix rules (for files only in the current directory, -not trying to chain transformations together, etc.) is also reasonably -portable. -.Sh SEE ALSO -.Xr mkdep 1 -.Sh HISTORY -.Nm -is derived from NetBSD -.Xr make 1 . -It uses autoconf to facilitate portability to other platforms. -.Pp -A -make -command appeared in -.At v7 . -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 -.Dq customs . -.Pp -Historically the target/dependency -.Dq FRC -has been used to FoRCe rebuilding (since the target/dependency -does not exist... unless someone creates an -.Dq FRC -file). -.Sh BUGS -The -make -syntax is difficult to parse without actually acting of the data. -For instance finding the end of a variable use should involve scanning each -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. -.Pp -There is no way of escaping a space character in a filename. diff --git a/.pc/140_multiarch.diff/main.c b/.pc/140_multiarch.diff/main.c deleted file mode 100644 index 3287115..0000000 --- a/.pc/140_multiarch.diff/main.c +++ /dev/null @@ -1,2023 +0,0 @@ -/* $NetBSD: main.c,v 1.232 2015/03/26 22:20:42 sjg Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: main.c,v 1.232 2015/03/26 22:20:42 sjg Exp $"; -#else -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ - The Regents of the University of California. All rights reserved."); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: main.c,v 1.232 2015/03/26 22:20:42 sjg Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * main.c -- - * The main file for this entire program. Exit routines etc - * reside here. - * - * Utility functions defined in this file: - * Main_ParseArgLine Takes a line of arguments, breaks them and - * treats them as if they were given when first - * invoked. Used by the parse module to implement - * the .MFLAGS target. - * - * Error Print a tagged error message. The global - * MAKE variable must have been defined. This - * takes a format string and optional arguments - * for it. - * - * Fatal Print an error message and exit. Also takes - * a format string and arguments for it. - * - * Punt Aborts all jobs and exits with a message. Also - * takes a format string and arguments for it. - * - * Finish Finish things up by printing the number of - * errors which occurred, as passed to it, and - * exiting. - */ - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/param.h> -#include <sys/resource.h> -#include <sys/stat.h> -#if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL) -#include <sys/sysctl.h> -#endif -#include <sys/utsname.h> -#include "wait.h" - -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <ctype.h> - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "pathnames.h" -#include "trace.h" - -#ifdef USE_IOVEC -#include <sys/uio.h> -#endif - -#ifndef DEFMAXLOCAL -#define DEFMAXLOCAL DEFMAXJOBS -#endif /* DEFMAXLOCAL */ - -#ifndef __arraycount -# define __arraycount(__x) (sizeof(__x) / sizeof(__x[0])) -#endif - -Lst create; /* Targets to be made */ -time_t now; /* Time at start of make */ -GNode *DEFAULT; /* .DEFAULT node */ -Boolean allPrecious; /* .PRECIOUS given on line by itself */ - -static Boolean noBuiltins; /* -r flag */ -static Lst makefiles; /* ordered list of makefiles to read */ -static Boolean printVars; /* print value of one or more vars */ -static Lst variables; /* list of variables to print */ -int maxJobs; /* -j argument */ -static int maxJobTokens; /* -j argument */ -Boolean compatMake; /* -B argument */ -int debug; /* -d argument */ -Boolean debugVflag; /* -dV */ -Boolean noExecute; /* -n flag */ -Boolean noRecursiveExecute; /* -N flag */ -Boolean keepgoing; /* -k flag */ -Boolean queryFlag; /* -q flag */ -Boolean touchFlag; /* -t flag */ -Boolean enterFlag; /* -w flag */ -Boolean ignoreErrors; /* -i flag */ -Boolean beSilent; /* -s flag */ -Boolean oldVars; /* variable substitution style */ -Boolean checkEnvFirst; /* -e flag */ -Boolean parseWarnFatal; /* -W flag */ -Boolean jobServer; /* -J flag */ -static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */ -Boolean varNoExportEnv; /* -X flag */ -Boolean doing_depend; /* Set while reading .depend */ -static Boolean jobsRunning; /* TRUE if the jobs might be running */ -static const char * tracefile; -static void MainParseArgs(int, char **); -static int ReadMakefile(const void *, const void *); -static void usage(void) MAKE_ATTR_DEAD; - -static Boolean ignorePWD; /* if we use -C, PWD is meaningless */ -static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */ -char curdir[MAXPATHLEN + 1]; /* Startup directory */ -char *progname; /* the program name */ -char *makeDependfile; -pid_t myPid; -int makelevel; - -Boolean forceJobs = FALSE; - -/* - * On some systems MACHINE is defined as something other than - * what we want. - */ -#ifdef FORCE_MACHINE -# undef MACHINE -# define MACHINE FORCE_MACHINE -#endif - -extern Lst parseIncPath; - -/* - * For compatibility with the POSIX version of MAKEFLAGS that includes - * all the options with out -, convert flags to -f -l -a -g -s. - */ -static char * -explode(const char *flags) -{ - size_t len; - char *nf, *st; - const char *f; - - if (flags == NULL) - return NULL; - - for (f = flags; *f; f++) - if (!isalpha((unsigned char)*f)) - break; - - if (*f) - return bmake_strdup(flags); - - len = strlen(flags); - st = nf = bmake_malloc(len * 3 + 1); - while (*flags) { - *nf++ = '-'; - *nf++ = *flags++; - *nf++ = ' '; - } - *nf = '\0'; - return st; -} - -static void -parse_debug_options(const char *argvalue) -{ - const char *modules; - const char *mode; - char *fname; - int len; - - for (modules = argvalue; *modules; ++modules) { - switch (*modules) { - case 'A': - debug = ~0; - break; - case 'a': - debug |= DEBUG_ARCH; - break; - case 'C': - debug |= DEBUG_CWD; - break; - case 'c': - debug |= DEBUG_COND; - break; - case 'd': - debug |= DEBUG_DIR; - break; - case 'e': - debug |= DEBUG_ERROR; - break; - case 'f': - debug |= DEBUG_FOR; - break; - case 'g': - if (modules[1] == '1') { - debug |= DEBUG_GRAPH1; - ++modules; - } - else if (modules[1] == '2') { - debug |= DEBUG_GRAPH2; - ++modules; - } - else if (modules[1] == '3') { - debug |= DEBUG_GRAPH3; - ++modules; - } - break; - case 'j': - debug |= DEBUG_JOB; - break; - case 'l': - debug |= DEBUG_LOUD; - break; - case 'M': - debug |= DEBUG_META; - break; - case 'm': - debug |= DEBUG_MAKE; - break; - case 'n': - debug |= DEBUG_SCRIPT; - break; - case 'p': - debug |= DEBUG_PARSE; - break; - case 's': - debug |= DEBUG_SUFF; - break; - case 't': - debug |= DEBUG_TARG; - break; - case 'V': - debugVflag = TRUE; - break; - case 'v': - debug |= DEBUG_VAR; - break; - case 'x': - debug |= DEBUG_SHELL; - break; - case 'F': - if (debug_file != stdout && debug_file != stderr) - fclose(debug_file); - if (*++modules == '+') { - modules++; - mode = "a"; - } else - mode = "w"; - if (strcmp(modules, "stdout") == 0) { - debug_file = stdout; - goto debug_setbuf; - } - if (strcmp(modules, "stderr") == 0) { - debug_file = stderr; - goto debug_setbuf; - } - len = strlen(modules); - fname = malloc(len + 20); - memcpy(fname, modules, len + 1); - /* Let the filename be modified by the pid */ - if (strcmp(fname + len - 3, ".%d") == 0) - snprintf(fname + len - 2, 20, "%d", getpid()); - debug_file = fopen(fname, mode); - if (!debug_file) { - fprintf(stderr, "Cannot open debug file %s\n", - fname); - usage(); - } - free(fname); - goto debug_setbuf; - default: - (void)fprintf(stderr, - "%s: illegal argument to d option -- %c\n", - progname, *modules); - usage(); - } - } -debug_setbuf: - /* - * Make the debug_file unbuffered, and make - * stdout line buffered (unless debugfile == stdout). - */ - setvbuf(debug_file, NULL, _IONBF, 0); - if (debug_file != stdout) { - setvbuf(stdout, NULL, _IOLBF, 0); - } -} - -/*- - * MainParseArgs -- - * Parse a given argument vector. Called from main() and from - * Main_ParseArgLine() when the .MAKEFLAGS target is used. - * - * XXX: Deal with command line overriding .MAKEFLAGS in makefile - * - * Results: - * None - * - * Side Effects: - * Various global and local flags will be set depending on the flags - * given - */ -static void -MainParseArgs(int argc, char **argv) -{ - char *p; - int c = '?'; - int arginc; - char *argvalue; - const char *getopt_def; - char *optscan; - Boolean inOption, dashDash = FALSE; - char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ - -#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw" -/* Can't actually use getopt(3) because rescanning is not portable */ - - getopt_def = OPTFLAGS; -rearg: - inOption = FALSE; - optscan = NULL; - while(argc > 1) { - char *getopt_spec; - if(!inOption) - optscan = argv[1]; - c = *optscan++; - arginc = 0; - if(inOption) { - if(c == '\0') { - ++argv; - --argc; - inOption = FALSE; - continue; - } - } else { - if (c != '-' || dashDash) - break; - inOption = TRUE; - c = *optscan++; - } - /* '-' found at some earlier point */ - getopt_spec = strchr(getopt_def, c); - if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') { - /* -<something> found, and <something> should have an arg */ - inOption = FALSE; - arginc = 1; - argvalue = optscan; - if(*argvalue == '\0') { - if (argc < 3) - goto noarg; - argvalue = argv[2]; - arginc = 2; - } - } else { - argvalue = NULL; - } - switch(c) { - case '\0': - arginc = 1; - inOption = FALSE; - break; - case 'B': - compatMake = TRUE; - Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL); - Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0); - break; - case 'C': - if (chdir(argvalue) == -1) { - (void)fprintf(stderr, - "%s: chdir %s: %s\n", - progname, argvalue, - strerror(errno)); - exit(1); - } - if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); - exit(2); - } - ignorePWD = TRUE; - break; - case 'D': - if (argvalue == NULL || argvalue[0] == 0) goto noarg; - Var_Set(argvalue, "1", VAR_GLOBAL, 0); - Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'I': - if (argvalue == NULL) goto noarg; - Parse_AddIncludeDir(argvalue); - Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'J': - if (argvalue == NULL) goto noarg; - if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) { - (void)fprintf(stderr, - "%s: internal error -- J option malformed (%s)\n", - progname, argvalue); - usage(); - } - if ((fcntl(jp_0, F_GETFD, 0) < 0) || - (fcntl(jp_1, F_GETFD, 0) < 0)) { -#if 0 - (void)fprintf(stderr, - "%s: ###### warning -- J descriptors were closed!\n", - progname); - exit(2); -#endif - jp_0 = -1; - jp_1 = -1; - compatMake = TRUE; - } else { - Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - jobServer = TRUE; - } - break; - case 'N': - noExecute = TRUE; - noRecursiveExecute = TRUE; - Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL); - break; - case 'S': - keepgoing = FALSE; - Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); - break; - case 'T': - if (argvalue == NULL) goto noarg; - tracefile = bmake_strdup(argvalue); - Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'V': - if (argvalue == NULL) goto noarg; - printVars = TRUE; - (void)Lst_AtEnd(variables, argvalue); - Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'W': - parseWarnFatal = TRUE; - break; - case 'X': - varNoExportEnv = TRUE; - Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL); - break; - case 'd': - if (argvalue == NULL) goto noarg; - /* If '-d-opts' don't pass to children */ - if (argvalue[0] == '-') - argvalue++; - else { - Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - } - parse_debug_options(argvalue); - break; - case 'e': - checkEnvFirst = TRUE; - Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); - break; - case 'f': - if (argvalue == NULL) goto noarg; - (void)Lst_AtEnd(makefiles, argvalue); - break; - case 'i': - ignoreErrors = TRUE; - Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); - break; - case 'j': - if (argvalue == NULL) goto noarg; - forceJobs = TRUE; - maxJobs = strtol(argvalue, &p, 0); - if (*p != '\0' || maxJobs < 1) { - (void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n", - progname); - exit(1); - } - Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0); - maxJobTokens = maxJobs; - break; - case 'k': - keepgoing = TRUE; - Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); - break; - case 'm': - if (argvalue == NULL) goto noarg; - /* look for magic parent directory search string */ - if (strncmp(".../", argvalue, 4) == 0) { - if (!Dir_FindHereOrAbove(curdir, argvalue+4, - found_path, sizeof(found_path))) - break; /* nothing doing */ - (void)Dir_AddDir(sysIncPath, found_path); - } else { - (void)Dir_AddDir(sysIncPath, argvalue); - } - Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); - Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); - break; - case 'n': - noExecute = TRUE; - Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); - break; - case 'q': - queryFlag = TRUE; - /* Kind of nonsensical, wot? */ - Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); - break; - case 'r': - noBuiltins = TRUE; - Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); - break; - case 's': - beSilent = TRUE; - Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); - break; - case 't': - touchFlag = TRUE; - Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); - break; - case 'w': - enterFlag = TRUE; - Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL); - break; - case '-': - dashDash = TRUE; - break; - default: - case '?': -#ifndef MAKE_NATIVE - fprintf(stderr, "getopt(%s) -> %d (%c)\n", - OPTFLAGS, c, c); -#endif - usage(); - } - argv += arginc; - argc -= arginc; - } - - oldVars = TRUE; - - /* - * See if the rest of the arguments are variable assignments and - * perform them if so. Else take them to be targets and stuff them - * on the end of the "create" list. - */ - for (; argc > 1; ++argv, --argc) - if (Parse_IsVar(argv[1])) { - Parse_DoVar(argv[1], VAR_CMD); - } else { - if (!*argv[1]) - Punt("illegal (null) argument."); - if (*argv[1] == '-' && !dashDash) - goto rearg; - (void)Lst_AtEnd(create, bmake_strdup(argv[1])); - } - - return; -noarg: - (void)fprintf(stderr, "%s: option requires an argument -- %c\n", - progname, c); - usage(); -} - -/*- - * Main_ParseArgLine -- - * Used by the parse module when a .MFLAGS or .MAKEFLAGS target - * is encountered and by main() when reading the .MAKEFLAGS envariable. - * Takes a line of arguments and breaks it into its - * component words and passes those words and the number of them to the - * MainParseArgs function. - * The line should have all its leading whitespace removed. - * - * Input: - * line Line to fracture - * - * Results: - * None - * - * Side Effects: - * Only those that come from the various arguments. - */ -void -Main_ParseArgLine(const char *line) -{ - char **argv; /* Manufactured argument vector */ - int argc; /* Number of arguments in argv */ - char *args; /* Space used by the args */ - char *buf, *p1; - char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1); - size_t len; - - if (line == NULL) - return; - for (; *line == ' '; ++line) - continue; - if (!*line) - return; - -#ifndef POSIX - { - /* - * $MAKE may simply be naming the make(1) binary - */ - char *cp; - - if (!(cp = strrchr(line, '/'))) - cp = line; - if ((cp = strstr(cp, "make")) && - strcmp(cp, "make") == 0) - return; - } -#endif - buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2); - (void)snprintf(buf, len, "%s %s", argv0, line); - if (p1) - free(p1); - - argv = brk_string(buf, &argc, TRUE, &args); - if (argv == NULL) { - Error("Unterminated quoted string [%s]", buf); - free(buf); - return; - } - free(buf); - MainParseArgs(argc, argv); - - free(args); - free(argv); -} - -Boolean -Main_SetObjdir(const char *path) -{ - struct stat sb; - char *p = NULL; - char buf[MAXPATHLEN + 1]; - Boolean rc = FALSE; - - /* expand variable substitutions */ - if (strchr(path, '$') != 0) { - snprintf(buf, MAXPATHLEN, "%s", path); - path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0); - } - - if (path[0] != '/') { - snprintf(buf, MAXPATHLEN, "%s/%s", curdir, path); - path = buf; - } - - /* look for the directory and try to chdir there */ - if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { - if (chdir(path)) { - (void)fprintf(stderr, "make warning: %s: %s.\n", - path, strerror(errno)); - } else { - strncpy(objdir, path, MAXPATHLEN); - Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0); - setenv("PWD", objdir, 1); - Dir_InitDot(); - rc = TRUE; - } - } - - if (p) - free(p); - return rc; -} - -/*- - * ReadAllMakefiles -- - * wrapper around ReadMakefile() to read all. - * - * Results: - * TRUE if ok, FALSE on error - */ -static int -ReadAllMakefiles(const void *p, const void *q) -{ - return (ReadMakefile(p, q) == 0); -} - -int -str2Lst_Append(Lst lp, char *str, const char *sep) -{ - char *cp; - int n; - - if (!sep) - sep = " \t"; - - for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) { - (void)Lst_AtEnd(lp, cp); - n++; - } - return (n); -} - -#ifdef SIGINFO -/*ARGSUSED*/ -static void -siginfo(int signo MAKE_ATTR_UNUSED) -{ - char dir[MAXPATHLEN]; - char str[2 * MAXPATHLEN]; - int len; - if (getcwd(dir, sizeof(dir)) == NULL) - return; - len = snprintf(str, sizeof(str), "%s: Working in: %s\n", progname, dir); - if (len > 0) - (void)write(STDERR_FILENO, str, (size_t)len); -} -#endif - -/* - * Allow makefiles some control over the mode we run in. - */ -void -MakeMode(const char *mode) -{ - char *mp = NULL; - - if (!mode) - mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0); - - if (mode && *mode) { - if (strstr(mode, "compat")) { - compatMake = TRUE; - forceJobs = FALSE; - } -#if USE_META - if (strstr(mode, "meta")) - meta_mode_init(mode); -#endif - } - if (mp) - free(mp); -} - -/*- - * main -- - * The main function, for obvious reasons. Initializes variables - * and a few modules, then parses the arguments give it in the - * environment and on the command line. Reads the system makefile - * followed by either Makefile, makefile or the file given by the - * -f argument. Sets the .MAKEFLAGS PMake variable based on all the - * flags it has received by then uses either the Make or the Compat - * module to create the initial list of targets. - * - * Results: - * If -q was given, exits -1 if anything was out-of-date. Else it exits - * 0. - * - * Side Effects: - * The program exits when done. Targets are created. etc. etc. etc. - */ -int -main(int argc, char **argv) -{ - Lst targs; /* target nodes to create -- passed to Make_Init */ - Boolean outOfDate = FALSE; /* FALSE if all targets up to date */ - struct stat sb, sa; - char *p1, *path; - char mdpath[MAXPATHLEN]; -#ifdef FORCE_MACHINE - const char *machine = FORCE_MACHINE; -#else - const char *machine = getenv("MACHINE"); -#endif - const char *machine_arch = getenv("MACHINE_ARCH"); - char *syspath = getenv("MAKESYSPATH"); - Lst sysMkPath; /* Path of sys.mk */ - char *cp = NULL, *start; - /* avoid faults on read-only strings */ - static char defsyspath[] = _PATH_DEFSYSPATH; - char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */ - struct timeval rightnow; /* to initialize random seed */ - struct utsname utsname; - - /* default to writing debug to stderr */ - debug_file = stderr; - -#ifdef SIGINFO - (void)bmake_signal(SIGINFO, siginfo); -#endif - /* - * Set the seed to produce a different random sequence - * on each program execution. - */ - gettimeofday(&rightnow, NULL); - srandom(rightnow.tv_sec + rightnow.tv_usec); - - if ((progname = strrchr(argv[0], '/')) != NULL) - progname++; - else - progname = argv[0]; -#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)) - /* - * get rid of resource limit on file descriptors - */ - { - struct rlimit rl; - if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && - rl.rlim_cur != rl.rlim_max) { - rl.rlim_cur = rl.rlim_max; - (void)setrlimit(RLIMIT_NOFILE, &rl); - } - } -#endif - - if (uname(&utsname) == -1) { - (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, - strerror(errno)); - exit(2); - } - - /* - * Get the name of this type of MACHINE from utsname - * so we can share an executable for similar machines. - * (i.e. m68k: amiga hp300, mac68k, sun3, ...) - * - * Note that both MACHINE and MACHINE_ARCH are decided at - * run-time. - */ - if (!machine) { -#ifdef MAKE_NATIVE - machine = utsname.machine; -#else -#ifdef MAKE_MACHINE - machine = MAKE_MACHINE; -#else - machine = "unknown"; -#endif -#endif - } - - if (!machine_arch) { -#if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL) && defined(CTL_HW) && defined(HW_MACHINE_ARCH) - static char machine_arch_buf[sizeof(utsname.machine)]; - int mib[2] = { CTL_HW, HW_MACHINE_ARCH }; - size_t len = sizeof(machine_arch_buf); - - if (sysctl(mib, __arraycount(mib), machine_arch_buf, - &len, NULL, 0) < 0) { - (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname, - strerror(errno)); - exit(2); - } - - machine_arch = machine_arch_buf; -#else -#ifndef MACHINE_ARCH -#ifdef MAKE_MACHINE_ARCH - machine_arch = MAKE_MACHINE_ARCH; -#else - machine_arch = "unknown"; -#endif -#else - machine_arch = MACHINE_ARCH; -#endif -#endif - } - - myPid = getpid(); /* remember this for vFork() */ - - /* - * Just in case MAKEOBJDIR wants us to do something tricky. - */ - Var_Init(); /* Initialize the lists of variables for - * parsing arguments */ - Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0); - Var_Set("MACHINE", machine, VAR_GLOBAL, 0); - Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); -#ifdef MAKE_VERSION - Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0); -#endif - Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */ - /* - * This is the traditional preference for makefiles. - */ -#ifndef MAKEFILE_PREFERENCE_LIST -# define MAKEFILE_PREFERENCE_LIST "makefile Makefile" -#endif - Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST, - VAR_GLOBAL, 0); - Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0); - - create = Lst_Init(FALSE); - makefiles = Lst_Init(FALSE); - printVars = FALSE; - debugVflag = FALSE; - variables = Lst_Init(FALSE); - beSilent = FALSE; /* Print commands as executed */ - ignoreErrors = FALSE; /* Pay attention to non-zero returns */ - noExecute = FALSE; /* Execute all commands */ - noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ - keepgoing = FALSE; /* Stop on error */ - allPrecious = FALSE; /* Remove targets when interrupted */ - queryFlag = FALSE; /* This is not just a check-run */ - noBuiltins = FALSE; /* Read the built-in rules */ - touchFlag = FALSE; /* Actually update targets */ - debug = 0; /* No debug verbosity, please. */ - jobsRunning = FALSE; - - maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */ - maxJobTokens = maxJobs; - compatMake = FALSE; /* No compat mode */ - ignorePWD = FALSE; - - /* - * Initialize the parsing, directory and variable modules to prepare - * for the reading of inclusion paths and variable settings on the - * command line - */ - - /* - * Initialize various variables. - * MAKE also gets this name, for compatibility - * .MAKEFLAGS gets set to the empty string just in case. - * MFLAGS also gets initialized empty, for compatibility. - */ - Parse_Init(); - if (argv[0][0] == '/' || strchr(argv[0], '/') == NULL) { - /* - * Leave alone if it is an absolute path, or if it does - * not contain a '/' in which case we need to find it in - * the path, like execvp(3) and the shells do. - */ - p1 = argv[0]; - } else { - /* - * A relative path, canonicalize it. - */ - p1 = realpath(argv[0], mdpath); - if (!p1 || *p1 != '/' || stat(p1, &sb) < 0) { - p1 = argv[0]; /* realpath failed */ - } - } - Var_Set("MAKE", p1, VAR_GLOBAL, 0); - Var_Set(".MAKE", p1, VAR_GLOBAL, 0); - Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0); - Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); - Var_Set("MFLAGS", "", VAR_GLOBAL, 0); - Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0); - /* some makefiles need to know this */ - Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMD, 0); - - /* - * Set some other useful macros - */ - { - char tmp[64], *ep; - - makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0; - if (makelevel < 0) - makelevel = 0; - snprintf(tmp, sizeof(tmp), "%d", makelevel); - Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL, 0); - snprintf(tmp, sizeof(tmp), "%u", myPid); - Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0); - snprintf(tmp, sizeof(tmp), "%u", getppid()); - Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0); - } - if (makelevel > 0) { - char pn[1024]; - snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel); - progname = bmake_strdup(pn); - } - -#ifdef USE_META - meta_init(); -#endif - /* - * First snag any flags out of the MAKE environment variable. - * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's - * in a different format). - */ -#ifdef POSIX - p1 = explode(getenv("MAKEFLAGS")); - Main_ParseArgLine(p1); - free(p1); -#else - Main_ParseArgLine(getenv("MAKE")); -#endif - - /* - * Find where we are (now). - * We take care of PWD for the automounter below... - */ - if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: getcwd: %s.\n", - progname, strerror(errno)); - exit(2); - } - - MainParseArgs(argc, argv); - - if (enterFlag) - printf("%s: Entering directory `%s'\n", progname, curdir); - - /* - * Verify that cwd is sane. - */ - if (stat(curdir, &sa) == -1) { - (void)fprintf(stderr, "%s: %s: %s.\n", - progname, curdir, strerror(errno)); - exit(2); - } - - /* - * All this code is so that we know where we are when we start up - * on a different machine with pmake. - * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX - * since the value of curdir can vary depending on how we got - * here. Ie sitting at a shell prompt (shell that provides $PWD) - * or via subdir.mk in which case its likely a shell which does - * not provide it. - * So, to stop it breaking this case only, we ignore PWD if - * MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform. - */ -#ifndef NO_PWD_OVERRIDE - if (!ignorePWD) { - char *pwd, *ptmp1 = NULL, *ptmp2 = NULL; - - if ((pwd = getenv("PWD")) != NULL && - Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &ptmp1) == NULL) { - const char *makeobjdir = Var_Value("MAKEOBJDIR", - VAR_CMD, &ptmp2); - - if (makeobjdir == NULL || !strchr(makeobjdir, '$')) { - if (stat(pwd, &sb) == 0 && - sa.st_ino == sb.st_ino && - sa.st_dev == sb.st_dev) - (void)strncpy(curdir, pwd, MAXPATHLEN); - } - } - free(ptmp1); - free(ptmp2); - } -#endif - Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); - - /* - * Find the .OBJDIR. If MAKEOBJDIRPREFIX, or failing that, - * MAKEOBJDIR is set in the environment, try only that value - * and fall back to .CURDIR if it does not exist. - * - * Otherwise, try _PATH_OBJDIR.MACHINE, _PATH_OBJDIR, and - * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none - * of these paths exist, just use .CURDIR. - */ - Dir_Init(curdir); - (void)Main_SetObjdir(curdir); - - if ((path = Var_Value("MAKEOBJDIRPREFIX", VAR_CMD, &p1)) != NULL) { - (void)snprintf(mdpath, MAXPATHLEN, "%s%s", path, curdir); - (void)Main_SetObjdir(mdpath); - free(p1); - } else if ((path = Var_Value("MAKEOBJDIR", VAR_CMD, &p1)) != NULL) { - (void)Main_SetObjdir(path); - free(p1); - } else { - (void)snprintf(mdpath, MAXPATHLEN, "%s.%s", _PATH_OBJDIR, machine); - if (!Main_SetObjdir(mdpath) && !Main_SetObjdir(_PATH_OBJDIR)) { - (void)snprintf(mdpath, MAXPATHLEN, "%s%s", - _PATH_OBJDIRPREFIX, curdir); - (void)Main_SetObjdir(mdpath); - } - } - - /* - * Be compatible if user did not specify -j and did not explicitly - * turned compatibility on - */ - if (!compatMake && !forceJobs) { - compatMake = TRUE; - } - - /* - * Initialize archive, target and suffix modules in preparation for - * parsing the makefile(s) - */ - Arch_Init(); - Targ_Init(); - Suff_Init(); - Trace_Init(tracefile); - - DEFAULT = NULL; - (void)time(&now); - - Trace_Log(MAKESTART, NULL); - - /* - * Set up the .TARGETS variable to contain the list of targets to be - * created. If none specified, make the variable empty -- the parser - * will fill the thing in with the default or .MAIN target. - */ - if (!Lst_IsEmpty(create)) { - LstNode ln; - - for (ln = Lst_First(create); ln != NULL; - ln = Lst_Succ(ln)) { - char *name = (char *)Lst_Datum(ln); - - Var_Append(".TARGETS", name, VAR_GLOBAL); - } - } else - Var_Set(".TARGETS", "", VAR_GLOBAL, 0); - - - /* - * If no user-supplied system path was given (through the -m option) - * add the directories from the DEFSYSPATH (more than one may be given - * as dir1:...:dirn) to the system include path. - */ - if (syspath == NULL || *syspath == '\0') - syspath = defsyspath; - else - syspath = bmake_strdup(syspath); - - for (start = syspath; *start != '\0'; start = cp) { - for (cp = start; *cp != '\0' && *cp != ':'; cp++) - continue; - if (*cp == ':') { - *cp++ = '\0'; - } - /* look for magic parent directory search string */ - if (strncmp(".../", start, 4) != 0) { - (void)Dir_AddDir(defIncPath, start); - } else { - if (Dir_FindHereOrAbove(curdir, start+4, - found_path, sizeof(found_path))) { - (void)Dir_AddDir(defIncPath, found_path); - } - } - } - if (syspath != defsyspath) - free(syspath); - - /* - * Read in the built-in rules first, followed by the specified - * makefile, if it was (makefile != NULL), or the default - * makefile and Makefile, in that order, if it wasn't. - */ - if (!noBuiltins) { - LstNode ln; - - sysMkPath = Lst_Init(FALSE); - Dir_Expand(_PATH_DEFSYSMK, - Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath, - sysMkPath); - if (Lst_IsEmpty(sysMkPath)) - Fatal("%s: no system rules (%s).", progname, - _PATH_DEFSYSMK); - ln = Lst_Find(sysMkPath, NULL, ReadMakefile); - if (ln == NULL) - Fatal("%s: cannot open %s.", progname, - (char *)Lst_Datum(ln)); - } - - if (!Lst_IsEmpty(makefiles)) { - LstNode ln; - - ln = Lst_Find(makefiles, NULL, ReadAllMakefiles); - if (ln != NULL) - Fatal("%s: cannot open %s.", progname, - (char *)Lst_Datum(ln)); - } else { - p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}", - VAR_CMD, 0); - if (p1) { - (void)str2Lst_Append(makefiles, p1, NULL); - (void)Lst_Find(makefiles, NULL, ReadMakefile); - free(p1); - } - } - - /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */ - if (!noBuiltins || !printVars) { - makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}", - VAR_CMD, 0); - doing_depend = TRUE; - (void)ReadMakefile(makeDependfile, NULL); - doing_depend = FALSE; - } - - MakeMode(NULL); - - Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); - if (p1) - free(p1); - - if (!compatMake) - Job_ServerStart(maxJobTokens, jp_0, jp_1); - if (DEBUG(JOB)) - fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", - jp_0, jp_1, maxJobs, maxJobTokens, compatMake); - - Main_ExportMAKEFLAGS(TRUE); /* initial export */ - - /* - * For compatibility, look at the directories in the VPATH variable - * and add them to the search path, if the variable is defined. The - * variable's value is in the same format as the PATH envariable, i.e. - * <directory>:<directory>:<directory>... - */ - if (Var_Exists("VPATH", VAR_CMD)) { - char *vpath, savec; - /* - * GCC stores string constants in read-only memory, but - * Var_Subst will want to write this thing, so store it - * in an array - */ - static char VPATH[] = "${VPATH}"; - - vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); - path = vpath; - do { - /* skip to end of directory */ - for (cp = path; *cp != ':' && *cp != '\0'; cp++) - continue; - /* Save terminator character so know when to stop */ - savec = *cp; - *cp = '\0'; - /* Add directory to search path */ - (void)Dir_AddDir(dirSearchPath, path); - *cp = savec; - path = cp + 1; - } while (savec == ':'); - free(vpath); - } - - /* - * Now that all search paths have been read for suffixes et al, it's - * time to add the default search path to their lists... - */ - Suff_DoPaths(); - - /* - * Propagate attributes through :: dependency lists. - */ - Targ_Propagate(); - - /* print the initial graph, if the user requested it */ - if (DEBUG(GRAPH1)) - Targ_PrintGraph(1); - - /* print the values of any variables requested by the user */ - if (printVars) { - LstNode ln; - Boolean expandVars; - - if (debugVflag) - expandVars = FALSE; - else - expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE); - for (ln = Lst_First(variables); ln != NULL; - ln = Lst_Succ(ln)) { - char *var = (char *)Lst_Datum(ln); - char *value; - - if (strchr(var, '$')) { - value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0); - } else if (expandVars) { - char tmp[128]; - - if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp))) - Fatal("%s: variable name too big: %s", - progname, var); - value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - } else { - value = Var_Value(var, VAR_GLOBAL, &p1); - } - printf("%s\n", value ? value : ""); - if (p1) - free(p1); - } - } else { - /* - * Have now read the entire graph and need to make a list of - * targets to create. If none was given on the command line, - * we consult the parsing module to find the main target(s) - * to create. - */ - if (Lst_IsEmpty(create)) - targs = Parse_MainName(); - else - targs = Targ_FindList(create, TARG_CREATE); - - if (!compatMake) { - /* - * Initialize job module before traversing the graph - * now that any .BEGIN and .END targets have been read. - * This is done only if the -q flag wasn't given - * (to prevent the .BEGIN from being executed should - * it exist). - */ - if (!queryFlag) { - Job_Init(); - jobsRunning = TRUE; - } - - /* Traverse the graph, checking on all the targets */ - outOfDate = Make_Run(targs); - } else { - /* - * Compat_Init will take care of creating all the - * targets as well as initializing the module. - */ - Compat_Run(targs); - } - } - -#ifdef CLEANUP - Lst_Destroy(targs, NULL); - Lst_Destroy(variables, NULL); - Lst_Destroy(makefiles, NULL); - Lst_Destroy(create, (FreeProc *)free); -#endif - - /* print the graph now it's been processed if the user requested it */ - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - - Trace_Log(MAKEEND, 0); - - if (enterFlag) - printf("%s: Leaving directory `%s'\n", progname, curdir); - - Suff_End(); - Targ_End(); - Arch_End(); - Var_End(); - Parse_End(); - Dir_End(); - Job_End(); - Trace_End(); - - return outOfDate ? 1 : 0; -} - -/*- - * ReadMakefile -- - * Open and parse the given makefile. - * - * Results: - * 0 if ok. -1 if couldn't open file. - * - * Side Effects: - * lots - */ -static int -ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED) -{ - const char *fname = p; /* makefile to read */ - int fd; - size_t len = MAXPATHLEN; - char *name, *path = bmake_malloc(len); - - if (!strcmp(fname, "-")) { - Parse_File(NULL /*stdin*/, -1); - Var_Set("MAKEFILE", "", VAR_INTERNAL, 0); - } else { - /* if we've chdir'd, rebuild the path name */ - if (strcmp(curdir, objdir) && *fname != '/') { - size_t plen = strlen(curdir) + strlen(fname) + 2; - if (len < plen) - path = bmake_realloc(path, len = 2 * plen); - - (void)snprintf(path, len, "%s/%s", curdir, fname); - fd = open(path, O_RDONLY); - if (fd != -1) { - fname = path; - goto found; - } - - /* If curdir failed, try objdir (ala .depend) */ - plen = strlen(objdir) + strlen(fname) + 2; - if (len < plen) - path = bmake_realloc(path, len = 2 * plen); - (void)snprintf(path, len, "%s/%s", objdir, fname); - fd = open(path, O_RDONLY); - if (fd != -1) { - fname = path; - goto found; - } - } else { - fd = open(fname, O_RDONLY); - if (fd != -1) - goto found; - } - /* look in -I and system include directories. */ - name = Dir_FindFile(fname, parseIncPath); - if (!name) - name = Dir_FindFile(fname, - Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); - if (!name || (fd = open(name, O_RDONLY)) == -1) { - if (name) - free(name); - free(path); - return(-1); - } - fname = name; - /* - * set the MAKEFILE variable desired by System V fans -- the - * placement of the setting here means it gets set to the last - * makefile specified, as it is set by SysV make. - */ -found: - if (!doing_depend) - Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0); - Parse_File(fname, fd); - } - free(path); - return(0); -} - - - -/*- - * Cmd_Exec -- - * Execute the command in cmd, and return the output of that command - * in a string. - * - * Results: - * A string containing the output of the command, or the empty string - * If errnum is not NULL, it contains the reason for the command failure - * - * Side Effects: - * The string must be freed by the caller. - */ -char * -Cmd_Exec(const char *cmd, const char **errnum) -{ - const char *args[4]; /* Args for invoking the shell */ - int fds[2]; /* Pipe streams */ - int cpid; /* Child PID */ - int pid; /* PID from wait() */ - char *res; /* result */ - WAIT_T status; /* command exit status */ - Buffer buf; /* buffer to store the result */ - char *cp; - int cc; /* bytes read, or -1 */ - int savederr; /* saved errno */ - - - *errnum = NULL; - - if (!shellName) - Shell_Init(); - /* - * Set up arguments for shell - */ - args[0] = shellName; - args[1] = "-c"; - args[2] = cmd; - args[3] = NULL; - - /* - * Open a pipe for fetching its output - */ - if (pipe(fds) == -1) { - *errnum = "Couldn't create pipe for \"%s\""; - goto bad; - } - - /* - * Fork - */ - switch (cpid = vFork()) { - case 0: - /* - * Close input side of pipe - */ - (void)close(fds[0]); - - /* - * Duplicate the output stream to the shell's output, then - * shut the extra thing down. Note we don't fetch the error - * stream...why not? Why? - */ - (void)dup2(fds[1], 1); - (void)close(fds[1]); - - Var_ExportVars(); - - (void)execv(shellPath, UNCONST(args)); - _exit(1); - /*NOTREACHED*/ - - case -1: - *errnum = "Couldn't exec \"%s\""; - goto bad; - - default: - /* - * No need for the writing half - */ - (void)close(fds[1]); - - savederr = 0; - Buf_Init(&buf, 0); - - do { - char result[BUFSIZ]; - cc = read(fds[0], result, sizeof(result)); - if (cc > 0) - Buf_AddBytes(&buf, cc, result); - } - while (cc > 0 || (cc == -1 && errno == EINTR)); - if (cc == -1) - savederr = errno; - - /* - * Close the input side of the pipe. - */ - (void)close(fds[0]); - - /* - * Wait for the process to exit. - */ - while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) { - JobReapChild(pid, status, FALSE); - continue; - } - cc = Buf_Size(&buf); - res = Buf_Destroy(&buf, FALSE); - - if (savederr != 0) - *errnum = "Couldn't read shell's output for \"%s\""; - - if (WIFSIGNALED(status)) - *errnum = "\"%s\" exited on a signal"; - else if (WEXITSTATUS(status) != 0) - *errnum = "\"%s\" returned non-zero status"; - - /* - * Null-terminate the result, convert newlines to spaces and - * install it in the variable. - */ - res[cc] = '\0'; - cp = &res[cc]; - - if (cc > 0 && *--cp == '\n') { - /* - * A final newline is just stripped - */ - *cp-- = '\0'; - } - while (cp >= res) { - if (*cp == '\n') { - *cp = ' '; - } - cp--; - } - break; - } - return res; -bad: - res = bmake_malloc(1); - *res = '\0'; - return res; -} - -/*- - * Error -- - * Print an error message given its format. - * - * Results: - * None. - * - * Side Effects: - * The message is printed. - */ -/* VARARGS */ -void -Error(const char *fmt, ...) -{ - va_list ap; - FILE *err_file; - - err_file = debug_file; - if (err_file == stdout) - err_file = stderr; - (void)fflush(stdout); - for (;;) { - va_start(ap, fmt); - fprintf(err_file, "%s: ", progname); - (void)vfprintf(err_file, fmt, ap); - va_end(ap); - (void)fprintf(err_file, "\n"); - (void)fflush(err_file); - if (err_file == stderr) - break; - err_file = stderr; - } -} - -/*- - * Fatal -- - * Produce a Fatal error message. If jobs are running, waits for them - * to finish. - * - * Results: - * None - * - * Side Effects: - * The program exits - */ -/* VARARGS */ -void -Fatal(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if (jobsRunning) - Job_Wait(); - - (void)fflush(stdout); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - - PrintOnError(NULL, NULL); - - if (DEBUG(GRAPH2) || DEBUG(GRAPH3)) - Targ_PrintGraph(2); - Trace_Log(MAKEERROR, 0); - exit(2); /* Not 1 so -q can distinguish error */ -} - -/* - * Punt -- - * Major exception once jobs are being created. Kills all jobs, prints - * a message and exits. - * - * Results: - * None - * - * Side Effects: - * All children are killed indiscriminately and the program Lib_Exits - */ -/* VARARGS */ -void -Punt(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - (void)fflush(stdout); - (void)fprintf(stderr, "%s: ", progname); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - - PrintOnError(NULL, NULL); - - DieHorribly(); -} - -/*- - * DieHorribly -- - * Exit without giving a message. - * - * Results: - * None - * - * Side Effects: - * A big one... - */ -void -DieHorribly(void) -{ - if (jobsRunning) - Job_AbortAll(); - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - Trace_Log(MAKEERROR, 0); - exit(2); /* Not 1, so -q can distinguish error */ -} - -/* - * Finish -- - * Called when aborting due to errors in child shell to signal - * abnormal exit. - * - * Results: - * None - * - * Side Effects: - * The program exits - */ -void -Finish(int errors) - /* number of errors encountered in Make_Make */ -{ - Fatal("%d error%s", errors, errors == 1 ? "" : "s"); -} - -/* - * eunlink -- - * Remove a file carefully, avoiding directories. - */ -int -eunlink(const char *file) -{ - struct stat st; - - if (lstat(file, &st) == -1) - return -1; - - if (S_ISDIR(st.st_mode)) { - errno = EISDIR; - return -1; - } - return unlink(file); -} - -/* - * execError -- - * Print why exec failed, avoiding stdio. - */ -void -execError(const char *af, const char *av) -{ -#ifdef USE_IOVEC - int i = 0; - struct iovec iov[8]; -#define IOADD(s) \ - (void)(iov[i].iov_base = UNCONST(s), \ - iov[i].iov_len = strlen(iov[i].iov_base), \ - i++) -#else -#define IOADD(s) (void)write(2, s, strlen(s)) -#endif - - IOADD(progname); - IOADD(": "); - IOADD(af); - IOADD("("); - IOADD(av); - IOADD(") failed ("); - IOADD(strerror(errno)); - IOADD(")\n"); - -#ifdef USE_IOVEC - while (writev(2, iov, 8) == -1 && errno == EAGAIN) - continue; -#endif -} - -/* - * usage -- - * exit with usage message - */ -static void -usage(void) -{ - char *p; - if ((p = strchr(progname, '[')) != NULL) - *p = '\0'; - - (void)fprintf(stderr, -"usage: %s [-BeikNnqrstWwX] \n\ - [-C directory] [-D variable] [-d flags] [-f makefile]\n\ - [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\ - [-V variable] [variable=value] [target ...]\n", progname); - exit(2); -} - - -int -PrintAddr(void *a, void *b) -{ - printf("%lx ", (unsigned long) a); - return b ? 0 : 0; -} - - - -void -PrintOnError(GNode *gn, const char *s) -{ - static GNode *en = NULL; - char tmp[64]; - char *cp; - - if (s) - printf("%s", s); - - printf("\n%s: stopped in %s\n", progname, curdir); - - if (en) - return; /* we've been here! */ - if (gn) { - /* - * We can print this even if there is no .ERROR target. - */ - Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0); - } - strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", - sizeof(tmp) - 1); - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - if (cp) { - if (*cp) - printf("%s", cp); - free(cp); - } - /* - * Finally, see if there is a .ERROR target, and run it if so. - */ - en = Targ_FindNode(".ERROR", TARG_NOCREATE); - if (en) { - en->type |= OP_SPECIAL; - Compat_Make(en, en); - } -} - -void -Main_ExportMAKEFLAGS(Boolean first) -{ - static int once = 1; - char tmp[64]; - char *s; - - if (once != first) - return; - once = 0; - - strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", - sizeof(tmp)); - s = Var_Subst(NULL, tmp, VAR_CMD, 0); - if (s && *s) { -#ifdef POSIX - setenv("MAKEFLAGS", s, 1); -#else - setenv("MAKE", s, 1); -#endif - } -} - -char * -getTmpdir(void) -{ - static char *tmpdir = NULL; - - if (!tmpdir) { - struct stat st; - - /* - * Honor $TMPDIR but only if it is valid. - * Ensure it ends with /. - */ - tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, 0); - if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) { - free(tmpdir); - tmpdir = bmake_strdup(_PATH_TMP); - } - } - return tmpdir; -} - -/* - * Create and open a temp file using "pattern". - * If "fnamep" is provided set it to a copy of the filename created. - * Otherwise unlink the file once open. - */ -int -mkTempFile(const char *pattern, char **fnamep) -{ - static char *tmpdir = NULL; - char tfile[MAXPATHLEN]; - int fd; - - if (!pattern) - pattern = TMPPAT; - if (!tmpdir) - tmpdir = getTmpdir(); - if (pattern[0] == '/') { - snprintf(tfile, sizeof(tfile), "%s", pattern); - } else { - snprintf(tfile, sizeof(tfile), "%s%s", tmpdir, pattern); - } - if ((fd = mkstemp(tfile)) < 0) - Punt("Could not create temporary file %s: %s", tfile, strerror(errno)); - if (fnamep) { - *fnamep = bmake_strdup(tfile); - } else { - unlink(tfile); /* we just want the descriptor */ - } - return fd; -} - - -/* - * Return a Boolean based on setting of a knob. - * - * If the knob is not set, the supplied default is the return value. - * If set, anything that looks or smells like "No", "False", "Off", "0" etc, - * is FALSE, otherwise TRUE. - */ -Boolean -getBoolean(const char *name, Boolean bf) -{ - char tmp[64]; - char *cp; - - if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) { - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - - if (cp) { - switch(*cp) { - case '\0': /* not set - the default wins */ - break; - case '0': - case 'f': - case 'n': - bf = FALSE; - break; - case 'o': - switch (cp[1]) { - case 'f': - bf = FALSE; - break; - default: - bf = TRUE; - break; - } - break; - default: - bf = TRUE; - break; - } - free(cp); - } - } - return (bf); -} diff --git a/.pc/160_manpage.diff/bmake.1 b/.pc/160_manpage.diff/bmake.1 deleted file mode 100644 index ddfb4d1..0000000 --- a/.pc/160_manpage.diff/bmake.1 +++ /dev/null @@ -1,2290 +0,0 @@ -.\" $NetBSD: make.1,v 1.249 2015/06/05 07:33:40 wiz Exp $ -.\" -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 -.\" -.Dd June 4, 2015 -.Dt MAKE 1 -.Os -.Sh NAME -.Nm bmake -.Nd maintain program dependencies -.Sh SYNOPSIS -.Nm -.Op Fl BeikNnqrstWwX -.Op Fl C Ar directory -.Op Fl D Ar variable -.Op Fl d Ar flags -.Op Fl f Ar makefile -.Op Fl I Ar directory -.Op Fl J Ar private -.Op Fl j Ar max_jobs -.Op Fl m Ar directory -.Op Fl T Ar file -.Op Fl V Ar variable -.Op Ar variable=value -.Op Ar target ... -.Sh DESCRIPTION -.Nm -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 -.Fl f Ar makefile -makefile option is given, -.Nm -will try to open -.Ql Pa makefile -then -.Ql Pa Makefile -in order to find the specifications. -If the file -.Ql Pa .depend -exists, it is read (see -.Xr mkdep 1 ) . -.Pp -This manual page is intended as a reference document only. -For a more thorough description of -.Nm -and makefiles, please refer to -.%T "PMake \- A Tutorial" . -.Pp -.Nm -will prepend the contents of the -.Va MAKEFLAGS -environment variable to the command line arguments before parsing them. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl B -Try to be backwards compatible by executing a single shell per command and -by executing the commands to make the sources of a dependency line in sequence. -.It Fl C Ar directory -Change to -.Ar directory -before reading the makefiles or doing anything else. -If multiple -.Fl C -options are specified, each is interpreted relative to the previous one: -.Fl C Pa / Fl C Pa etc -is equivalent to -.Fl C Pa /etc . -.It Fl D Ar variable -Define -.Ar variable -to be 1, in the global context. -.It Fl d Ar [-]flags -Turn on debugging, and specify which portions of -.Nm -are to print debugging information. -Unless the flags are preceded by -.Ql \- -they are added to the -.Va MAKEFLAGS -environment variable and will be processed by any child make processes. -By default, debugging information is printed to standard error, -but this can be changed using the -.Ar F -debugging flag. -The debugging output is always unbuffered; in addition, if debugging -is enabled but debugging output is not directed to standard output, -then the standard output is line buffered. -.Ar Flags -is one or more of the following: -.Bl -tag -width Ds -.It Ar A -Print all possible debugging information; -equivalent to specifying all of the debugging flags. -.It Ar a -Print debugging information about archive searching and caching. -.It Ar C -Print debugging information about current working directory. -.It Ar c -Print debugging information about conditional evaluation. -.It Ar d -Print debugging information about directory searching and caching. -.It Ar e -Print debugging information about failed commands and targets. -.It Ar F Ns Oo Sy \&+ Oc Ns Ar filename -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 -.Ql F -flag is -.Ql \&+ , -then the file will be opened in append mode; -otherwise the file will be overwritten. -If the file name is -.Ql stdout -or -.Ql stderr -then debugging output will be written to the -standard output or standard error output file descriptors respectively -(and the -.Ql \&+ -option has no effect). -Otherwise, the output will be written to the named file. -If the file name ends -.Ql .%d -then the -.Ql %d -is replaced by the pid. -.It Ar f -Print debugging information about loop evaluation. -.It Ar "g1" -Print the input graph before making anything. -.It Ar "g2" -Print the input graph after making everything, or before exiting -on error. -.It Ar "g3" -Print the input graph before exiting on error. -.It Ar j -Print debugging information about running multiple shells. -.It Ar l -Print commands in Makefiles regardless of whether or not they are prefixed by -.Ql @ -or other "quiet" flags. -Also known as "loud" behavior. -.It Ar M -Print debugging information about "meta" mode decisions about targets. -.It Ar m -Print debugging information about making targets, including modification -dates. -.It Ar n -Don't delete the temporary command scripts created when running commands. -These temporary scripts are created in the directory -referred to by the -.Ev TMPDIR -environment variable, or in -.Pa /tmp -if -.Ev TMPDIR -is unset or set to the empty string. -The temporary scripts are created by -.Xr mkstemp 3 , -and have names of the form -.Pa makeXXXXXX . -.Em NOTE : -This can create many files in -.Ev TMPDIR -or -.Pa /tmp , -so use with care. -.It Ar p -Print debugging information about makefile parsing. -.It Ar s -Print debugging information about suffix-transformation rules. -.It Ar t -Print debugging information about target list maintenance. -.It Ar V -Force the -.Fl V -option to print raw values of variables. -.It Ar v -Print debugging information about variable assignment. -.It Ar x -Run shell commands with -.Fl x -so the actual commands are printed as they are executed. -.El -.It Fl e -Specify that environment variables override macro assignments within -makefiles. -.It Fl f Ar makefile -Specify a makefile to read instead of the default -.Ql Pa makefile . -If -.Ar makefile -is -.Ql Fl , -standard input is read. -Multiple makefiles may be specified, and are read in the order specified. -.It Fl I Ar directory -Specify a directory in which to search for makefiles and included makefiles. -The system makefile directory (or directories, see the -.Fl m -option) is automatically included as part of this list. -.It Fl i -Ignore non-zero exit of shell commands in the makefile. -Equivalent to specifying -.Ql Fl -before each command line in the makefile. -.It Fl J Ar private -This option should -.Em not -be specified by the user. -.Pp -When the -.Ar j -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. -.It Fl j Ar max_jobs -Specify the maximum number of jobs that -.Nm -may have running at any one time. -The value is saved in -.Va .MAKE.JOBS . -Turns compatibility mode off, unless the -.Ar B -flag 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. -.It Fl k -Continue processing after errors are encountered, but only on those targets -that do not depend on the target whose creation caused the error. -.It Fl m Ar directory -Specify a directory in which to search for sys.mk and makefiles included -via the -.Ao Ar file Ac Ns -style -include statement. -The -.Fl m -option can be used multiple times to form a search path. -This path will override the default system include path: /usr/share/mk. -Furthermore the system include path will be appended to the search path used -for -.Qo Ar file Qc Ns -style -include statements (see the -.Fl I -option). -.Pp -If a file or directory name in the -.Fl m -argument (or the -.Ev MAKESYSPATH -environment variable) starts with the string -.Qq \&.../ -then -.Nm -will search for the specified file or directory named in the remaining part -of the argument string. -The search starts with the current directory of -the Makefile and then works upward towards the root of the filesystem. -If the search is successful, then the resulting directory replaces the -.Qq \&.../ -specification in the -.Fl m -argument. -If used, this feature allows -.Nm -to easily search in the current source tree for customized sys.mk files -(e.g., by using -.Qq \&.../mk/sys.mk -as an argument). -.It Fl n -Display the commands that would have been executed, but do not -actually execute them unless the target depends on the .MAKE special -source (see below). -.It Fl N -Display the commands which would have been executed, but do not -actually execute any of them; useful for debugging top-level makefiles -without descending into subdirectories. -.It Fl q -Do not execute any commands, but exit 0 if the specified targets are -up-to-date and 1, otherwise. -.It Fl r -Do not use the built-in rules specified in the system makefile. -.It Fl s -Do not echo any commands as they are executed. -Equivalent to specifying -.Ql Ic @ -before each command line in the makefile. -.It Fl T Ar tracefile -When used with the -.Fl j -flag, -append a trace record to -.Ar tracefile -for each job started and completed. -.It Fl t -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. -.It Fl V Ar variable -Print -.Nm Ns 's -idea of the value of -.Ar variable , -in the global context. -Do not build any targets. -Multiple instances of this option may be specified; -the variables will be printed one per line, -with a blank line for each null or undefined variable. -If -.Ar variable -contains a -.Ql \&$ -then the value will be expanded before printing. -.It Fl W -Treat any warnings during makefile parsing as errors. -.It Fl w -Print entering and leaving directory messages, pre and post processing. -.It Fl X -Don't export variables passed on the command line to the environment -individually. -Variables passed on the command line are still exported -via the -.Va MAKEFLAGS -environment variable. -This option may be useful on systems which have a small limit on the -size of command arguments. -.It Ar variable=value -Set the value of the variable -.Ar variable -to -.Ar value . -Normally, all values passed on the command line are also exported to -sub-makes in the environment. -The -.Fl X -flag disables this behavior. -Variable assignments should follow options for POSIX compatibility -but no ordering is enforced. -.El -.Pp -There are seven different types of lines in a makefile: file dependency -specifications, shell commands, variable assignments, include statements, -conditional directives, for loops, and comments. -.Pp -In general, lines may be continued from one line to the next by ending -them with a backslash -.Pq Ql \e . -The trailing newline character and initial whitespace on the following -line are compressed into a single space. -.Sh FILE DEPENDENCY SPECIFICATIONS -Dependency lines consist of one or more targets, an operator, and zero -or more sources. -This creates a relationship where the targets -.Dq depend -on the sources -and are usually created from them. -The exact relationship between the target and the source is determined -by the operator that separates them. -The three operators are as follows: -.Bl -tag -width flag -.It Ic \&: -A target is considered out-of-date if its modification time is less than -those of any of its sources. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&! -Targets are always re-created, but not until all sources have been -examined and re-created as necessary. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&:: -If no sources are specified, the target is always re-created. -Otherwise, a target is considered out-of-date if any of its sources has -been modified more recently than the target. -Sources for a target do not accumulate over dependency lines when this -operator is used. -The target will not be removed if -.Nm -is interrupted. -.El -.Pp -Targets and sources may contain the shell wildcard values -.Ql \&? , -.Ql * , -.Ql [] , -and -.Ql {} . -The values -.Ql \&? , -.Ql * , -and -.Ql [] -may only be used as part of the final -component of the target or source, and must be used to describe existing -files. -The value -.Ql {} -need not necessarily be used to describe existing files. -Expansion is in directory order, not alphabetically as done in the shell. -.Sh SHELL COMMANDS -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 -.Em must -be preceded by a tab. -(For historical reasons, spaces are not accepted.) -While targets can appear in many dependency lines if desired, by -default only one of these rules may be followed by a creation -script. -If the -.Ql Ic \&:: -operator is used, however, all rules may include scripts and the -scripts are executed in the order found. -.Pp -Each line is treated as a separate shell command, unless the end of -line is escaped with a backslash -.Pq Ql \e -in which case that line and the next are combined. -.\" The escaped newline is retained and passed to the shell, which -.\" normally ignores it. -.\" However, the tab at the beginning of the following line is removed. -If the first characters of the command are any combination of -.Ql Ic @ , -.Ql Ic + , -or -.Ql Ic \- , -the command is treated specially. -A -.Ql Ic @ -causes the command not to be echoed before it is executed. -A -.Ql Ic + -causes the command to be executed even when -.Fl n -is given. -This is similar to the effect of the .MAKE special source, -except that the effect can be limited to a single line of a script. -A -.Ql Ic \- -in compatibility mode -causes any non-zero exit status of the command line to be ignored. -.Pp -When -.Nm -is run in jobs mode with -.Fl j Ar max_jobs , -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 -.Pq Ql #=|^(){};&<>*?[]:$`\e\en -it will be passed to the shell; otherwise -.Nm -will attempt direct execution. -If a line starts with -.Ql Ic \- -and the shell has ErrCtl enabled then failure of the command line -will be ignored as in compatibility mode. -Otherwise -.Ql Ic \- -affects the entire job; -the script will stop at the first command line that fails, -but the target will not be deemed to have failed. -.Pp -Makefiles should be written so that the mode of -.Nm -operation does not change their behavior. -For example, any command which needs to use -.Dq cd -or -.Dq chdir -without potentially changing the directory for subsequent commands -should be put in parentheses so it executes in a subshell. -To force the use of one shell, escape the line breaks so as to make -the whole script one command. -For example: -.Bd -literal -offset indent -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`; \e - (cd ${.CURDIR} && ${MAKE} $@); \e - echo Back in `pwd` -.Ed -.Pp -Since -.Nm -will -.Xr chdir 2 -to -.Ql Va .OBJDIR -before executing any targets, each child process -starts with that as its current working directory. -.Sh VARIABLE ASSIGNMENTS -Variables in make are much like variables in the shell, and, by tradition, -consist of all upper-case letters. -.Ss Variable assignment modifiers -The five operators that can be used to assign values to variables are as -follows: -.Bl -tag -width Ds -.It Ic \&= -Assign the value to the variable. -Any previous value is overridden. -.It Ic \&+= -Append the value to the current value of the variable. -.It Ic \&?= -Assign the value to the variable if it is not already defined. -.It Ic \&:= -Assign with expansion, i.e. expand the value before assigning it -to the variable. -Normally, expansion is not done until the variable is referenced. -.Em NOTE : -References to undefined variables are -.Em not -expanded. -This can cause problems when variable modifiers are used. -.It Ic \&!= -Expand the value and pass it to the shell for execution and assign -the result to the variable. -Any newlines in the result are replaced with spaces. -.El -.Pp -Any white-space before the assigned -.Ar value -is removed; if the value is being appended, a single space is inserted -between the previous contents of the variable and the appended value. -.Pp -Variables are expanded by surrounding the variable name with either -curly braces -.Pq Ql {} -or parentheses -.Pq Ql () -and preceding it with -a dollar sign -.Pq Ql \&$ . -If the variable name contains only a single letter, the surrounding -braces or parentheses are not required. -This shorter form is not recommended. -.Pp -If the variable name contains a dollar, then the name itself is expanded first. -This allows almost arbitrary variable names, however names containing dollar, -braces, parenthesis, or whitespace are really best avoided! -.Pp -If the result of expanding a variable contains a dollar sign -.Pq Ql \&$ -the string is expanded again. -.Pp -Variable substitution occurs at three distinct times, depending on where -the variable is being used. -.Bl -enum -.It -Variables in dependency lines are expanded as the line is read. -.It -Variables in shell commands are expanded when the shell command is -executed. -.It -.Dq .for -loop index variables are expanded on each loop iteration. -Note that other variables are not expanded inside loops so -the following example code: -.Bd -literal -offset indent - -.Dv .for i in 1 2 3 -a+= ${i} -j= ${i} -b+= ${j} -.Dv .endfor - -all: - @echo ${a} - @echo ${b} - -.Ed -will print: -.Bd -literal -offset indent -1 2 3 -3 3 3 - -.Ed -Because while ${a} contains -.Dq 1 2 3 -after the loop is executed, ${b} -contains -.Dq ${j} ${j} ${j} -which expands to -.Dq 3 3 3 -since after the loop completes ${j} contains -.Dq 3 . -.El -.Ss Variable classes -The four different classes of variables (in order of increasing precedence) -are: -.Bl -tag -width Ds -.It Environment variables -Variables defined as part of -.Nm Ns 's -environment. -.It Global variables -Variables defined in the makefile or in included makefiles. -.It Command line variables -Variables defined as part of the command line. -.It Local variables -Variables that are defined specific to a certain target. -.El -.Pp -Local variables are all built in and their values vary magically from -target to target. -It is not currently possible to define new local variables. -The seven local variables are as follows: -.Bl -tag -width ".ARCHIVE" -offset indent -.It Va .ALLSRC -The list of all sources for this target; also known as -.Ql Va \&\*[Gt] . -.It Va .ARCHIVE -The name of the archive file; also known as -.Ql Va \&! . -.It Va .IMPSRC -In suffix-transformation rules, the name/path of the source from which the -target is to be transformed (the -.Dq implied -source); also known as -.Ql Va \&\*[Lt] . -It is not defined in explicit rules. -.It Va .MEMBER -The name of the archive member; also known as -.Ql Va % . -.It Va .OODATE -The list of sources for this target that were deemed out-of-date; also -known as -.Ql Va \&? . -.It Va .PREFIX -The file prefix of the target, containing only the file portion, no suffix -or preceding directory components; also known as -.Ql Va * . -The suffix must be one of the known suffixes declared with -.Ic .SUFFIXES -or it will not be recognized. -.It Va .TARGET -The name of the target; also known as -.Ql Va @ . -.El -.Pp -The shorter forms -.Ql ( Va \*[Gt] , -.Ql Va \&! , -.Ql Va \*[Lt] , -.Ql Va % , -.Ql Va \&? , -.Ql Va * , -and -.Ql Va @ ) -are permitted for backward -compatibility with historical makefiles and legacy POSIX make and are -not recommended. -.Pp -Variants of these variables with the punctuation followed immediately by -.Ql D -or -.Ql F , -e.g. -.Ql Va $(@D) , -are legacy forms equivalent to using the -.Ql :H -and -.Ql :T -modifiers. -These forms are accepted for compatibility with -.At V -makefiles and POSIX but are not recommended. -.Pp -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 -.Ql Va .TARGET , -.Ql Va .PREFIX , -.Ql Va .ARCHIVE , -and -.Ql Va .MEMBER . -.Ss Additional built-in variables -In addition, -.Nm -sets or knows about the following variables: -.Bl -tag -width .MAKEOVERRIDES -.It Va \&$ -A single dollar sign -.Ql \&$ , -i.e. -.Ql \&$$ -expands to a single dollar -sign. -.It Va .ALLTARGETS -The list of all targets encountered in the Makefile. -If evaluated during -Makefile parsing, lists only those targets encountered thus far. -.It Va .CURDIR -A path to the directory where -.Nm -was executed. -Refer to the description of -.Ql Ev PWD -for more details. -.It Va .INCLUDEDFROMDIR -The directory of the file this Makefile was included from. -.It Va .INCLUDEDFROMFILE -The filename of the file this Makefile was included from. -.It Ev MAKE -The name that -.Nm -was executed with -.Pq Va argv[0] . -For compatibility -.Nm -also sets -.Va .MAKE -with the same value. -The preferred variable to use is the environment variable -.Ev MAKE -because it is more compatible with other versions of -.Nm -and cannot be confused with the special target with the same name. -.It Va .MAKE.DEPENDFILE -Names the makefile (default -.Ql Pa .depend ) -from which generated dependencies are read. -.It Va .MAKE.EXPAND_VARIABLES -A boolean that controls the default behavior of the -.Fl V -option. -.It Va .MAKE.EXPORTED -The list of variables exported by -.Nm . -.It Va .MAKE.JOBS -The argument to the -.Fl j -option. -.It Va .MAKE.JOB.PREFIX -If -.Nm -is run with -.Ar j -then output for each target is prefixed with a token -.Ql --- target --- -the first part of which can be controlled via -.Va .MAKE.JOB.PREFIX . -If -.Va .MAKE.JOB.PREFIX -is empty, no token is printed. -.br -For example: -.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}] -would produce tokens like -.Ql ---make[1234] target --- -making it easier to track the degree of parallelism being achieved. -.It Ev MAKEFLAGS -The environment variable -.Ql Ev MAKEFLAGS -may contain anything that -may be specified on -.Nm Ns 's -command line. -Anything specified on -.Nm Ns 's -command line is appended to the -.Ql Ev MAKEFLAGS -variable which is then -entered into the environment for all programs which -.Nm -executes. -.It Va .MAKE.LEVEL -The recursion depth of -.Nm . -The initial instance of -.Nm -will be 0, and an incremented value is put into the environment -to be seen by the next generation. -This allows tests like: -.Li .if ${.MAKE.LEVEL} == 0 -to protect things which should only be evaluated in the initial instance of -.Nm . -.It Va .MAKE.MAKEFILE_PREFERENCE -The ordered list of makefile names -(default -.Ql Pa makefile , -.Ql Pa Makefile ) -that -.Nm -will look for. -.It Va .MAKE.MAKEFILES -The list of makefiles read by -.Nm , -which is useful for tracking dependencies. -Each makefile is recorded only once, regardless of the number of times read. -.It Va .MAKE.MODE -Processed after reading all makefiles. -Can affect the mode that -.Nm -runs in. -It can contain a number of keywords: -.Bl -hang -width ignore-cmd -.It Pa compat -Like -.Fl B , -puts -.Nm -into "compat" mode. -.It Pa meta -Puts -.Nm -into "meta" mode, where meta files are created for each target -to capture the command run, the output generated and if -.Xr filemon 4 -is available, the system calls which are of interest to -.Nm . -The captured output can be very useful when diagnosing errors. -.It Pa curdirOk= Ar bf -Normally -.Nm -will not create .meta files in -.Ql Va .CURDIR . -This can be overridden by setting -.Va bf -to a value which represents True. -.It Pa env -For debugging, it can be useful to inlcude the environment -in the .meta file. -.It Pa verbose -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 the value of: -.Va .MAKE.META.PREFIX . -.It Pa ignore-cmd -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 -.Ic .NOMETA_CMP . -.It Pa silent= Ar bf -If -.Va bf -is True, when a .meta file is created, mark the target -.Ic .SILENT . -.El -.It Va .MAKE.META.BAILIWICK -In "meta" mode, provides a list of prefixes which -match the directories controlled by -.Nm . -If a file that was generated outside of -.Va .OBJDIR -but within said bailiwick is missing, -the current target is considered out-of-date. -.It Va .MAKE.META.CREATED -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 -.Va .MAKE.META.FILES . -.It Va .MAKE.META.FILES -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. -.It Va .MAKE.META.IGNORE_PATHS -Provides a list of path prefixes that should be ignored; -because the contents are expected to change over time. -The default list includes: -.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp -.It Va .MAKE.META.PREFIX -Defines the message printed for each meta file updated in "meta verbose" mode. -The default value is: -.Dl Building ${.TARGET:H:tA}/${.TARGET:T} -.It Va .MAKEOVERRIDES -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 -.Ql Ev MAKEFLAGS . -This behaviour can be disabled by assigning an empty value to -.Ql Va .MAKEOVERRIDES -within a makefile. -Extra variables can be exported from a makefile -by appending their names to -.Ql Va .MAKEOVERRIDES . -.Ql Ev MAKEFLAGS -is re-exported whenever -.Ql Va .MAKEOVERRIDES -is modified. -.It Va .MAKE.PATH_FILEMON -If -.Nm -was built with -.Xr filemon 4 -support, this is set to the path of the device node. -This allows makefiles to test for this support. -.It Va .MAKE.PID -The process-id of -.Nm . -.It Va .MAKE.PPID -The parent process-id of -.Nm . -.It Va MAKE_PRINT_VAR_ON_ERROR -When -.Nm -stops due to an error, it prints its name and the value of -.Ql Va .CURDIR -as well as the value of any variables named in -.Ql Va MAKE_PRINT_VAR_ON_ERROR . -.It Va .newline -This variable is simply assigned a newline character as its value. -This allows expansions using the -.Cm \&:@ -modifier to put a newline between -iterations of the loop rather than a space. -For example, the printing of -.Ql Va MAKE_PRINT_VAR_ON_ERROR -could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}. -.It Va .OBJDIR -A path to the directory where the targets are built. -Its value is determined by trying to -.Xr chdir 2 -to the following directories in order and using the first match: -.Bl -enum -.It -.Ev ${MAKEOBJDIRPREFIX}${.CURDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIRPREFIX -is set in the environment or on the command line.) -.It -.Ev ${MAKEOBJDIR} -.Pp -(Only if -.Ql Ev MAKEOBJDIR -is set in the environment or on the command line.) -.It -.Ev ${.CURDIR} Ns Pa /obj. Ns Ev ${MACHINE} -.It -.Ev ${.CURDIR} Ns Pa /obj -.It -.Pa /usr/obj/ Ns Ev ${.CURDIR} -.It -.Ev ${.CURDIR} -.El -.Pp -Variable expansion is performed on the value before it's used, -so expressions such as -.Dl ${.CURDIR:S,^/usr/src,/var/obj,} -may be used. -This is especially useful with -.Ql Ev MAKEOBJDIR . -.Pp -.Ql Va .OBJDIR -may be modified in the makefile via the special target -.Ql Ic .OBJDIR . -In all cases, -.Nm -will -.Xr chdir 2 -to the specified directory if it exists, and set -.Ql Va .OBJDIR -and -.Ql Ev PWD -to that directory before executing any targets. -. -.It Va .PARSEDIR -A path to the directory of the current -.Ql Pa Makefile -being parsed. -.It Va .PARSEFILE -The basename of the current -.Ql Pa Makefile -being parsed. -This variable and -.Ql Va .PARSEDIR -are both set only while the -.Ql Pa Makefiles -are being parsed. -If you want to retain their current values, assign them to a variable -using assignment with expansion: -.Pq Ql Cm \&:= . -.It Va .PATH -A variable that represents the list of directories that -.Nm -will search for files. -The search list should be updated using the target -.Ql Va .PATH -rather than the variable. -.It Ev PWD -Alternate path to the current directory. -.Nm -normally sets -.Ql Va .CURDIR -to the canonical path given by -.Xr getcwd 3 . -However, if the environment variable -.Ql Ev PWD -is set and gives a path to the current directory, then -.Nm -sets -.Ql Va .CURDIR -to the value of -.Ql Ev PWD -instead. -This behaviour is disabled if -.Ql Ev MAKEOBJDIRPREFIX -is set or -.Ql Ev MAKEOBJDIR -contains a variable transform. -.Ql Ev PWD -is set to the value of -.Ql Va .OBJDIR -for all programs which -.Nm -executes. -.It Ev .TARGETS -The list of targets explicitly specified on the command line, if any. -.It Ev VPATH -Colon-separated -.Pq Dq \&: -lists of directories that -.Nm -will search for files. -The variable is supported for compatibility with old make programs only, -use -.Ql Va .PATH -instead. -.El -.Ss Variable modifiers -Variable expansion may be modified to select or modify each word of the -variable (where a -.Dq word -is white-space delimited sequence of characters). -The general format of a variable expansion is as follows: -.Pp -.Dl ${variable[:modifier[:...]]} -.Pp -Each modifier begins with a colon, -which may be escaped with a backslash -.Pq Ql \e . -.Pp -A set of modifiers can be specified via a variable, as follows: -.Pp -.Dl modifier_variable=modifier[:...] -.Dl ${variable:${modifier_variable}[:...]} -.Pp -In this case the first modifier in the modifier_variable does not -start with a colon, since that must appear in the referencing -variable. -If any of the modifiers in the modifier_variable contain a dollar sign -.Pq Ql $ , -these must be doubled to avoid early expansion. -.Pp -The supported modifiers are: -.Bl -tag -width EEE -.It Cm \&:E -Replaces each word in the variable with its suffix. -.It Cm \&:H -Replaces each word in the variable with everything but the last component. -.It Cm \&:M Ns Ar pattern -Select only those words that match -.Ar pattern . -The standard shell wildcard characters -.Pf ( Ql * , -.Ql \&? , -and -.Ql Oo Oc ) -may -be used. -The wildcard characters may be escaped with a backslash -.Pq Ql \e . -As a consequence of the way values are split into words, matched, -and then joined, a construct like -.Dl ${VAR:M*} -will normalise the inter-word spacing, removing all leading and -trailing space, and converting multiple consecutive spaces -to single spaces. -. -.It Cm \&:N Ns Ar pattern -This is identical to -.Ql Cm \&:M , -but selects all words which do not match -.Ar pattern . -.It Cm \&:O -Order every word in variable alphabetically. -To sort words in -reverse order use the -.Ql Cm \&:O:[-1..1] -combination of modifiers. -.It Cm \&:Ox -Randomize words in variable. -The results will be different each time you are referring to the -modified variable; use the assignment with expansion -.Pq Ql Cm \&:= -to prevent such behaviour. -For example, -.Bd -literal -offset indent -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}" -.Ed -may produce output similar to: -.Bd -literal -offset indent -quattro due tre uno -tre due quattro uno -due uno quattro tre -due uno quattro tre -.Ed -.It Cm \&:Q -Quotes every shell meta-character in the variable, so that it can be passed -safely through recursive invocations of -.Nm . -.It Cm \&:R -Replaces each word in the variable with everything but its suffix. -.It Cm \&:gmtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr gmtime 3 . -.It Cm \&:hash -Compute a 32bit hash of the value and encode it as hex digits. -.It Cm \&:localtime -The value is a format string for -.Xr strftime 3 , -using the current -.Xr localtime 3 . -.It Cm \&:tA -Attempt to convert variable to an absolute path using -.Xr realpath 3 , -if that fails, the value is unchanged. -.It Cm \&:tl -Converts variable to lower-case letters. -.It Cm \&:ts Ns Ar c -Words in the variable are normally separated by a space on expansion. -This modifier sets the separator to the character -.Ar c . -If -.Ar c -is omitted, then no separator is used. -The common escapes (including octal numeric codes), work as expected. -.It Cm \&:tu -Converts variable to upper-case letters. -.It Cm \&:tW -Causes the value to be treated as a single word -(possibly containing embedded white space). -See also -.Ql Cm \&:[*] . -.It Cm \&:tw -Causes the value to be treated as a sequence of -words delimited by white space. -See also -.Ql Cm \&:[@] . -.Sm off -.It Cm \&:S No \&/ Ar old_string No \&/ Ar new_string No \&/ Op Cm 1gW -.Sm on -Modify the first occurrence of -.Ar old_string -in the variable's value, replacing it with -.Ar new_string . -If a -.Ql g -is appended to the last slash of the pattern, all occurrences -in each word are replaced. -If a -.Ql 1 -is appended to the last slash of the pattern, only the first word -is affected. -If a -.Ql W -is appended to the last slash of the pattern, -then the value is treated as a single word -(possibly containing embedded white space). -If -.Ar old_string -begins with a caret -.Pq Ql ^ , -.Ar old_string -is anchored at the beginning of each word. -If -.Ar old_string -ends with a dollar sign -.Pq Ql \&$ , -it is anchored at the end of each word. -Inside -.Ar new_string , -an ampersand -.Pq Ql \*[Am] -is replaced by -.Ar old_string -(without any -.Ql ^ -or -.Ql \&$ ) . -Any character may be used as a delimiter for the parts of the modifier -string. -The anchoring, ampersand and delimiter characters may be escaped with a -backslash -.Pq Ql \e . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the expansion -of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:C No \&/ Ar pattern No \&/ Ar replacement No \&/ Op Cm 1gW -.Sm on -The -.Cm \&:C -modifier is just like the -.Cm \&:S -modifier except that the old and new strings, instead of being -simple strings, are an extended regular expression (see -.Xr regex 3 ) -string -.Ar pattern -and an -.Xr ed 1 Ns \-style -string -.Ar replacement . -Normally, the first occurrence of the pattern -.Ar pattern -in each word of the value is substituted with -.Ar replacement . -The -.Ql 1 -modifier causes the substitution to apply to at most one word; the -.Ql g -modifier causes the substitution to apply to as many instances of the -search pattern -.Ar pattern -as occur in the word or words it is found in; the -.Ql W -modifier causes the value to be treated as a single word -(possibly containing embedded white space). -Note that -.Ql 1 -and -.Ql g -are orthogonal; the former specifies whether multiple words are -potentially affected, the latter whether multiple substitutions can -potentially occur within each affected word. -.Pp -As for the -.Cm \&:S -modifier, the -.Ar pattern -and -.Ar replacement -are subjected to variable expansion before being parsed as -regular expressions. -.It Cm \&:T -Replaces each word in the variable with its last component. -.It Cm \&:u -Remove adjacent duplicate words (like -.Xr uniq 1 ) . -.Sm off -.It Cm \&:\&? Ar true_string Cm \&: Ar false_string -.Sm on -If the variable name (not its value), when parsed as a .if conditional -expression, evaluates to true, return as its value the -.Ar true_string , -otherwise return the -.Ar false_string . -Since the variable name is used as the expression, \&:\&? must be the -first modifier after the variable name itself - which will, of course, -usually contain variable expansions. -A common error is trying to use expressions like -.Dl ${NUMBERS:M42:?match:no} -which actually tests defined(NUMBERS), -to determine is any words match "42" you need to use something like: -.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} . -.It Ar :old_string=new_string -This is the -.At V -style variable substitution. -It must be the last modifier specified. -If -.Ar old_string -or -.Ar new_string -do not contain the pattern matching character -.Ar % -then it is assumed that they are -anchored at the end of each word, so only suffixes or entire -words may be replaced. -Otherwise -.Ar % -is the substring of -.Ar old_string -to be replaced in -.Ar new_string . -.Pp -Variable expansion occurs in the normal fashion inside both -.Ar old_string -and -.Ar new_string -with the single exception that a backslash is used to prevent the -expansion of a dollar sign -.Pq Ql \&$ , -not a preceding dollar sign as is usual. -.Sm off -.It Cm \&:@ Ar temp Cm @ Ar string Cm @ -.Sm on -This is the loop expansion mechanism from the OSF Development -Environment (ODE) make. -Unlike -.Cm \&.for -loops expansion occurs at the time of -reference. -Assign -.Ar temp -to each word in the variable and evaluate -.Ar string . -The ODE convention is that -.Ar temp -should start and end with a period. -For example. -.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@} -.Pp -However a single character variable is often more readable: -.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@} -.It Cm \&:U Ns Ar newval -If the variable is undefined -.Ar newval -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: -.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}} -If a value is only required if the variable is undefined, use: -.Dl ${VAR:D:Unewval} -.It Cm \&:D Ns Ar newval -If the variable is defined -.Ar newval -is the value. -.It Cm \&:L -The name of the variable is the value. -.It Cm \&:P -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, then the -name of the variable is used. -In order for this modifier to work, the name (node) must at least have -appeared on the rhs of a dependency. -.Sm off -.It Cm \&:\&! Ar cmd Cm \&! -.Sm on -The output of running -.Ar cmd -is the value. -.It Cm \&:sh -If the variable is non-empty it is run as a command and the output -becomes the new value. -.It Cm \&::= Ns Ar str -The variable is assigned the value -.Ar str -after substitution. -This modifier and its variations are useful in -obscure situations such as wanting to set a variable when shell commands -are being parsed. -These assignment modifiers always expand to -nothing, so if appearing in a rule line by themselves should be -preceded with something to keep -.Nm -happy. -.Pp -The -.Ql Cm \&:: -helps avoid false matches with the -.At V -style -.Cm \&:= -modifier and since substitution always occurs the -.Cm \&::= -form is vaguely appropriate. -.It Cm \&::?= Ns Ar str -As for -.Cm \&::= -but only if the variable does not already have a value. -.It Cm \&::+= Ns Ar str -Append -.Ar str -to the variable. -.It Cm \&::!= Ns Ar cmd -Assign the output of -.Ar cmd -to the variable. -.It Cm \&:\&[ Ns Ar range Ns Cm \&] -Selects one or more words from the value, -or performs other operations related to the way in which the -value is divided into words. -.Pp -Ordinarily, a value is treated as a sequence of words -delimited by white space. -Some modifiers suppress this behaviour, -causing a value to be treated as a single word -(possibly containing embedded white space). -An empty value, or a value that consists entirely of white-space, -is treated as a single word. -For the purposes of the -.Ql Cm \&:[] -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). -.Pp -The -.Ar range -is subjected to variable expansion, and the expanded result is -then interpreted as follows: -.Bl -tag -width index -.\" :[n] -.It Ar index -Selects a single word from the value. -.\" :[start..end] -.It Ar start Ns Cm \&.. Ns Ar end -Selects all words from -.Ar start -to -.Ar end , -inclusive. -For example, -.Ql Cm \&:[2..-1] -selects all words from the second word to the last word. -If -.Ar start -is greater than -.Ar end , -then the words are output in reverse order. -For example, -.Ql Cm \&:[-1..1] -selects all the words from last to first. -.\" :[*] -.It Cm \&* -Causes subsequent modifiers to treat the value as a single word -(possibly containing embedded white space). -Analogous to the effect of -\&"$*\&" -in Bourne shell. -.\" :[0] -.It 0 -Means the same as -.Ql Cm \&:[*] . -.\" :[*] -.It Cm \&@ -Causes subsequent modifiers to treat the value as a sequence of words -delimited by white space. -Analogous to the effect of -\&"$@\&" -in Bourne shell. -.\" :[#] -.It Cm \&# -Returns the number of words in the value. -.El \" :[range] -.El -.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS -Makefile inclusion, conditional structures and for loops reminiscent -of the C programming language are provided in -.Nm . -All such structures are identified by a line beginning with a single -dot -.Pq Ql \&. -character. -Files are included with either -.Cm \&.include Aq Ar file -or -.Cm \&.include Pf \*q Ar file Ns \*q . -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 -.Fl I -option are searched before the system -makefile directory. -For compatibility with other versions of -.Nm -.Ql include file ... -is also accepted. -If the include statement is written as -.Cm .-include -or as -.Cm .sinclude -then errors locating and/or opening include files are ignored. -.Pp -Conditional expressions are also preceded by a single dot as the first -character of a line. -The possible conditionals are as follows: -.Bl -tag -width Ds -.It Ic .error Ar message -The message is printed along with the name of the makefile and line number, -then -.Nm -will exit. -.It Ic .export Ar variable ... -Export the specified global variable. -If no variable list is provided, all globals are exported -except for internal variables (those that start with -.Ql \&. ) . -This is not affected by the -.Fl X -flag, so should be used with caution. -For compatibility with other -.Nm -programs -.Ql export variable=value -is also accepted. -.Pp -Appending a variable name to -.Va .MAKE.EXPORTED -is equivalent to exporting a variable. -.It Ic .export-env Ar variable ... -The same as -.Ql .export , -except that the variable is not appended to -.Va .MAKE.EXPORTED . -This allows exporting a value to the environment which is different from that -used by -.Nm -internally. -.It Ic .info Ar message -The message is printed along with the name of the makefile and line number. -.It Ic .undef Ar variable -Un-define the specified global variable. -Only global variables may be un-defined. -.It Ic .unexport Ar variable ... -The opposite of -.Ql .export . -The specified global -.Va variable -will be removed from -.Va .MAKE.EXPORTED . -If no variable list is provided, all globals are unexported, -and -.Va .MAKE.EXPORTED -deleted. -.It Ic .unexport-env -Unexport all globals previously exported and -clear the environment inherited from the parent. -This operation will cause a memory leak of the original environment, -so should be used sparingly. -Testing for -.Va .MAKE.LEVEL -being 0, would make sense. -Also note that any variables which originated in the parent environment -should be explicitly preserved if desired. -For example: -.Bd -literal -offset indent -.Li .if ${.MAKE.LEVEL} == 0 -PATH := ${PATH} -.Li .unexport-env -.Li .export PATH -.Li .endif -.Pp -.Ed -Would result in an environment containing only -.Ql Ev PATH , -which is the minimal useful environment. -Actually -.Ql Ev .MAKE.LEVEL -will also be pushed into the new environment. -.It Ic .warning Ar message -The message prefixed by -.Ql Pa warning: -is printed along with the name of the makefile and line number. -.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ... -Test the value of an expression. -.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -Test the value of a variable. -.It Ic .ifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -Test the target being built. -.It Ic .ifnmake Oo \&! Ns Oc Ar target Op Ar operator target ... -Test the target being built. -.It Ic .else -Reverse the sense of the last conditional. -.It Ic .elif Oo \&! Ns Oc Ar expression Op Ar operator expression ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .if . -.It Ic .elifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifdef . -.It Ic .elifndef Oo \&! Oc Ns Ar variable Op Ar operator variable ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifndef . -.It Ic .elifmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifmake . -.It Ic .elifnmake Oo \&! Oc Ns Ar target Op Ar operator target ... -A combination of -.Ql Ic .else -followed by -.Ql Ic .ifnmake . -.It Ic .endif -End the body of the conditional. -.El -.Pp -The -.Ar operator -may be any one of the following: -.Bl -tag -width "Cm XX" -.It Cm \&|\&| -Logical OR. -.It Cm \&\*[Am]\*[Am] -Logical -.Tn AND ; -of higher precedence than -.Dq \&|\&| . -.El -.Pp -As in C, -.Nm -will only evaluate a conditional as far as is necessary to determine -its value. -Parentheses may be used to change the order of evaluation. -The boolean operator -.Ql Ic \&! -may be used to logically negate an entire -conditional. -It is of higher precedence than -.Ql Ic \&\*[Am]\*[Am] . -.Pp -The value of -.Ar expression -may be any of the following: -.Bl -tag -width defined -.It Ic defined -Takes a variable name as an argument and evaluates to true if the variable -has been defined. -.It Ic make -Takes a target name as an argument and evaluates to true if the target -was specified as part of -.Nm Ns 's -command line or was declared the default target (either implicitly or -explicitly, see -.Va .MAIN ) -before the line containing the conditional. -.It Ic empty -Takes a variable, with possible modifiers, and evaluates to true if -the expansion of the variable would result in an empty string. -.It Ic exists -Takes a file name as an argument and evaluates to true if the file exists. -The file is searched for on the system search path (see -.Va .PATH ) . -.It Ic target -Takes a target name as an argument and evaluates to true if the target -has been defined. -.It Ic commands -Takes a target name as an argument and evaluates to true if the target -has been defined and has commands associated with it. -.El -.Pp -.Ar Expression -may also be an arithmetic or string comparison. -Variable expansion is -performed on both sides of the comparison, after which the integral -values are compared. -A value is interpreted as hexadecimal if it is -preceded by 0x, otherwise it is decimal; octal numbers are not supported. -The standard C relational operators are all supported. -If after -variable expansion, either the left or right hand side of a -.Ql Ic == -or -.Ql Ic "!=" -operator is not an integral value, then -string comparison is performed between the expanded -variables. -If no relational operator is given, it is assumed that the expanded -variable is being compared against 0 or an empty string in the case -of a string comparison. -.Pp -When -.Nm -is evaluating one of these conditional expressions, and it encounters -a (white-space separated) word it doesn't recognize, either the -.Dq make -or -.Dq defined -expression is applied to it, depending on the form of the conditional. -If the form is -.Ql Ic .ifdef , -.Ql Ic .ifndef , -or -.Ql Ic .if -the -.Dq defined -expression is applied. -Similarly, if the form is -.Ql Ic .ifmake -or -.Ql Ic .ifnmake , the -.Dq make -expression is applied. -.Pp -If the conditional evaluates to true the parsing of the makefile continues -as before. -If it evaluates to false, the following lines are skipped. -In both cases this continues until a -.Ql Ic .else -or -.Ql Ic .endif -is found. -.Pp -For loops are typically used to apply a set of rules to a list of files. -The syntax of a for loop is: -.Pp -.Bl -tag -compact -width Ds -.It Ic \&.for Ar variable Oo Ar variable ... Oc Ic in Ar expression -.It Aq make-rules -.It Ic \&.endfor -.El -.Pp -After the for -.Ic expression -is evaluated, it is split into words. -On each iteration of the loop, one word is taken and assigned to each -.Ic variable , -in order, and these -.Ic variables -are substituted into the -.Ic make-rules -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. -.Sh COMMENTS -Comments begin with a hash -.Pq Ql \&# -character, anywhere but in a shell -command line, and continue to the end of an unescaped new line. -.Sh SPECIAL SOURCES (ATTRIBUTES) -.Bl -tag -width .IGNOREx -.It Ic .EXEC -Target is never out of date, but always execute commands anyway. -.It Ic .IGNORE -Ignore any errors from the commands associated with this target, exactly -as if they all were preceded by a dash -.Pq Ql \- . -.\" .It Ic .INVISIBLE -.\" XXX -.\" .It Ic .JOIN -.\" XXX -.It Ic .MADE -Mark all sources of this target as being up-to-date. -.It Ic .MAKE -Execute the commands associated with this target even if the -.Fl n -or -.Fl t -options were specified. -Normally used to mark recursive -.Nm Ns s . -.It Ic .META -Create a meta file for the target, even if it is flagged as -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL . -Usage in conjunction with -.Ic .MAKE -is the most likely case. -In "meta" mode, the target is out-of-date if the meta file is missing. -.It Ic .NOMETA -Do not create a meta file for the target. -Meta files are also not created for -.Ic .PHONY , -.Ic .MAKE , -or -.Ic .SPECIAL -targets. -.It Ic .NOMETA_CMP -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 will still be out of date. -The same effect applies to any command line that uses the variable -.Va .OODATE , -which can be used for that purpose even when not otherwise needed or desired: -.Bd -literal -offset indent - -skip-compare-for-some: - @echo this will be compared - @echo this will not ${.OODATE:M.NOMETA_CMP} - @echo this will also be compared - -.Ed -The -.Cm \&:M -pattern suppresses any expansion of the unwanted variable. -.It Ic .NOPATH -Do not search for the target in the directories specified by -.Ic .PATH . -.It Ic .NOTMAIN -Normally -.Nm -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. -.It Ic .OPTIONAL -If a target is marked with this attribute and -.Nm -can't figure out how to create it, it will ignore this fact and assume -the file isn't needed or already exists. -.It Ic .PHONY -The target does not -correspond to an actual file; it is always considered to be out of date, -and will not be created with the -.Fl t -option. -Suffix-transformation rules are not applied to -.Ic .PHONY -targets. -.It Ic .PRECIOUS -When -.Nm -is interrupted, it normally removes any partially made targets. -This source prevents the target from being removed. -.It Ic .RECURSIVE -Synonym for -.Ic .MAKE . -.It Ic .SILENT -Do not echo any of the commands associated with this target, exactly -as if they all were preceded by an at sign -.Pq Ql @ . -.It Ic .USE -Turn the target into -.Nm Ns '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 -.Ic .USE ) -of the -source. -If the target already has commands, the -.Ic .USE -target's commands are appended -to them. -.It Ic .USEBEFORE -Exactly like -.Ic .USE , -but prepend the -.Ic .USEBEFORE -target commands to the target. -.It Ic .WAIT -If -.Ic .WAIT -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: -.Bd -literal -x: a .WAIT b - echo x -a: - echo a -b: b1 - echo b -b1: - echo b1 - -.Ed -the output is always -.Ql a , -.Ql b1 , -.Ql b , -.Ql x . -.br -The ordering imposed by -.Ic .WAIT -is only relevant for parallel makes. -.El -.Sh SPECIAL TARGETS -Special targets may not be included with other targets, i.e. they must be -the only target specified. -.Bl -tag -width .BEGINx -.It Ic .BEGIN -Any command lines attached to this target are executed before anything -else is done. -.It Ic .DEFAULT -This is sort of a -.Ic .USE -rule for any target (that was used only as a -source) that -.Nm -can't figure out any other way to create. -Only the shell script is used. -The -.Ic .IMPSRC -variable of a target that inherits -.Ic .DEFAULT Ns 's -commands is set -to the target's own name. -.It Ic .END -Any command lines attached to this target are executed after everything -else is done. -.It Ic .ERROR -Any command lines attached to this target are executed when another target fails. -The -.Ic .ERROR_TARGET -variable is set to the target that failed. -See also -.Ic MAKE_PRINT_VAR_ON_ERROR . -.It Ic .IGNORE -Mark each of the sources with the -.Ic .IGNORE -attribute. -If no sources are specified, this is the equivalent of specifying the -.Fl i -option. -.It Ic .INTERRUPT -If -.Nm -is interrupted, the commands for this target will be executed. -.It Ic .MAIN -If no target is specified when -.Nm -is invoked, this target will be built. -.It Ic .MAKEFLAGS -This target provides a way to specify flags for -.Nm -when the makefile is used. -The flags are as if typed to the shell, though the -.Fl f -option will have -no effect. -.\" XXX: NOT YET!!!! -.\" .It Ic .NOTPARALLEL -.\" The named targets are executed in non parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in non parallel mode. -.It Ic .NOPATH -Apply the -.Ic .NOPATH -attribute to any specified sources. -.It Ic .NOTPARALLEL -Disable parallel mode. -.It Ic .NO_PARALLEL -Synonym for -.Ic .NOTPARALLEL , -for compatibility with other pmake variants. -.It Ic .OBJDIR -The source is a new value for -.Ql Va .OBJDIR . -If it exists, -.Nm -will -.Xr chdir 2 -to it and update the value of -.Ql Va .OBJDIR . -.It Ic .ORDER -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 -.Ql a -is built by another part of the dependency graph, -the following is a dependency loop: -.Bd -literal -\&.ORDER: b a -b: a -.Ed -.Pp -The ordering imposed by -.Ic .ORDER -is only relevant for parallel makes. -.\" XXX: NOT YET!!!! -.\" .It Ic .PARALLEL -.\" The named targets are executed in parallel mode. -.\" If no targets are -.\" specified, then all targets are executed in parallel mode. -.It Ic .PATH -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 -deleted. -If the source is the special -.Ic .DOTLAST -target, then the current working -directory is searched last. -.It Ic .PATH. Ns Va suffix -Like -.Ic .PATH -but applies only to files with a particular suffix. -The suffix must have been previously declared with -.Ic .SUFFIXES . -.It Ic .PHONY -Apply the -.Ic .PHONY -attribute to any specified sources. -.It Ic .PRECIOUS -Apply the -.Ic .PRECIOUS -attribute to any specified sources. -If no sources are specified, the -.Ic .PRECIOUS -attribute is applied to every -target in the file. -.It Ic .SHELL -Sets the shell that -.Nm -will use to execute commands. -The sources are a set of -.Ar field=value -pairs. -.Bl -tag -width hasErrCtls -.It Ar name -This is the minimal specification, used to select one of the builtin -shell specs; -.Ar sh , -.Ar ksh , -and -.Ar csh . -.It Ar path -Specifies the path to the shell. -.It Ar hasErrCtl -Indicates whether the shell supports exit on error. -.It Ar check -The command to turn on error checking. -.It Ar ignore -The command to disable error checking. -.It Ar echo -The command to turn on echoing of commands executed. -.It Ar quiet -The command to turn off echoing of commands executed. -.It Ar filter -The output to filter after issuing the -.Ar quiet -command. -It is typically identical to -.Ar quiet . -.It Ar errFlag -The flag to pass the shell to enable error checking. -.It Ar echoFlag -The flag to pass the shell to enable command echoing. -.It Ar newline -The string literal to pass the shell that results in a single newline -character when used outside of any quoting characters. -.El -Example: -.Bd -literal -\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e - check="set \-e" ignore="set +e" \e - echo="set \-v" quiet="set +v" filter="set +v" \e - echoFlag=v errFlag=e newline="'\en'" -.Ed -.It Ic .SILENT -Apply the -.Ic .SILENT -attribute to any specified sources. -If no sources are specified, the -.Ic .SILENT -attribute is applied to every -command in the file. -.It Ic .STALE -This target gets run when a dependency file contains stale entries, having -.Va .ALLSRC -set to the name of that dependency file. -.It Ic .SUFFIXES -Each source specifies a suffix to -.Nm . -If no sources are specified, any previously specified suffixes are deleted. -It allows the creation of suffix-transformation rules. -.Pp -Example: -.Bd -literal -\&.SUFFIXES: .o -\&.c.o: - cc \-o ${.TARGET} \-c ${.IMPSRC} -.Ed -.El -.Sh ENVIRONMENT -.Nm -uses the following environment variables, if they exist: -.Ev MACHINE , -.Ev MACHINE_ARCH , -.Ev MACHINE_MULTIARCH , -.Ev MAKE , -.Ev MAKEFLAGS , -.Ev MAKEOBJDIR , -.Ev MAKEOBJDIRPREFIX , -.Ev MAKESYSPATH , -.Ev PWD , -and -.Ev TMPDIR . -.Pp -.Ev MAKEOBJDIRPREFIX -and -.Ev MAKEOBJDIR -may only be set in the environment or on the command line to -.Nm -and not as makefile variables; -see the description of -.Ql Va .OBJDIR -for more details. -.Sh FILES -.Bl -tag -width /usr/share/mk -compact -.It .depend -list of dependencies -.It Makefile -list of dependencies -.It makefile -list of dependencies -.It sys.mk -system makefile -.It /usr/share/mk -system makefile directory -.El -.Sh COMPATIBILITY -The basic make syntax is compatible between different versions of make; -however the special variables, variable modifiers and conditionals are not. -.Ss Older versions -An incomplete list of changes in older versions of -.Nm : -.Pp -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. -.Pp -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. -.Ss Other make dialects -Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not -support most of the features of -.Nm -as described in this manual. -Most notably: -.Bl -bullet -offset indent -.It -The -.Ic .WAIT -and -.Ic .ORDER -declarations and most functionality pertaining to parallelization. -(GNU make supports parallelization but lacks these features needed to -control it effectively.) -.It -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.) -.It -All built-in variables that begin with a dot. -.It -Most of the special sources and targets that begin with a dot, -with the notable exception of -.Ic .PHONY , -.Ic .PRECIOUS , -and -.Ic .SUFFIXES . -.It -Variable modifiers, except for the -.Dl :old=new -string substitution, which does not portably support globbing with -.Ql % -and historically only works on declared suffixes. -.It -The -.Ic $> -variable even in its short form; most makes support this functionality -but its name varies. -.El -.Pp -Some features are somewhat more portable, such as assignment with -.Ic += , -.Ic ?= , -and -.Ic != . -The -.Ic .PATH -functionality is based on an older feature -.Ic VPATH -found in GNU make and many versions of SVR4 make; however, -historically its behavior is too ill-defined (and too buggy) to rely -upon. -.Pp -The -.Ic $@ -and -.Ic $< -variables are more or less universally portable, as is the -.Ic $(MAKE) -variable. -Basic use of suffix rules (for files only in the current directory, -not trying to chain transformations together, etc.) is also reasonably -portable. -.Sh SEE ALSO -.Xr mkdep 1 -.Sh HISTORY -.Nm -is derived from NetBSD -.Xr make 1 . -It uses autoconf to facilitate portability to other platforms. -.Pp -A -make -command appeared in -.At v7 . -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 -.Dq customs . -.Pp -Historically the target/dependency -.Dq FRC -has been used to FoRCe rebuilding (since the target/dependency -does not exist... unless someone creates an -.Dq FRC -file). -.Sh BUGS -The -make -syntax is difficult to parse without actually acting of the data. -For instance finding the end of a variable use should involve scanning each -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. -.Pp -There is no way of escaping a space character in a filename. diff --git a/.pc/applied-patches b/.pc/applied-patches deleted file mode 100644 index 014cb67..0000000 --- a/.pc/applied-patches +++ /dev/null @@ -1,3 +0,0 @@ -100_makefile.boot.diff -140_multiarch.diff -160_manpage.diff |