text: /* $NetBSD: make.h,v 1.92 2013/09/04 15:38:26 */ /*- * make.h -- * The global definitions for pmake */ #ifndef _MAKE_H_ #define _MAKE_H_ #include <sys/types.h> #include <sys/param.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #ifdef BSD4_4 # include <sys/cdefs.h> #endif #if defined(__GNUC__) #define MAKE_GNUC_PREREQ(x, y) \ ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \ (__GNUC__ > (x))) #else /* defined(__GNUC__) */ #define MAKE_GNUC_PREREQ(x, y) 0 #endif /* defined(__GNUC__) */ #if MAKE_GNUC_PREREQ(2, 7) #define MAKE_ATTR_UNUSED __attribute__((__unused__)) #else #define MAKE_ATTR_UNUSED /* delete */ #endif #if MAKE_GNUC_PREREQ(2, 5) #define MAKE_ATTR_DEAD __attribute__((__noreturn__)) #elif defined(__GNUC__) #define MAKE_ATTR_DEAD __volatile #else #define MAKE_ATTR_DEAD /* delete */ #endif #if MAKE_GNUC_PREREQ(2, 7) #define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \ __attribute__((__format__ (__printf__, fmtarg, firstvararg))) #else #define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */ #endif #include "sprite.h" #include "lst.h" #include "hash.h" #include "config.h" #include "buf.h" #include "make_malloc.h" /*- * The structure for an individual graph node. Each node has several * pieces of data associated with it. * 1) the name of the target it describes * 2) the location of the target file in the file system. * (parents) * 11) a list of nodes on which this depends (children) * 12) a list of nodes that depend on this, as gleaned from the * transformation rules (iParents) * 13) a list of ancestor nodes, which includes parents, iParents, * and recursive parents of parents * 14) a list of nodes of the same name created by the :: operator * 15) a list of nodes that must be made (if they're made) before * this node can be, but that do not enter into the datedness of * this node. * 16) a list of nodes that must be made (if they're made) before * this node or any child of this node can be, but that do not * enter into the datedness of this node. * 17) a list of nodes that must be made (if they're made) after * this node is, but that do not depend on this node, in the * normal sense. * 18) a Lst of ``local'' variables that are specific to this target * and this target only (qv. var.c [$@ $< $?, etc.]) * 19) a Lst of strings that are commands to be given to a shell * to create this target. */ typedef struct GNode { char *name; /* The target's name */ char *uname; /* The unexpanded name of a .USE node */ char *path; /* The full pathname of the file */ int type; /* Its type (see the OP flags, below) */ int flags; #define REMAKE 0x1 /* this target needs to be (re)made */ #define CHILDMADE 0x2 /* children of this target were made */ #define FORCE 0x4 /* children don't exist, and we pretend made */ #define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */ #define DONE_ORDER 0x10 /* Build requested by .ORDER processing */ #define FROM_DEPEND 0x20 /* Node created from .depend */ #define DONE_ALLSRC 0x40 /* We do it once only */ #define CYCLE 0x1000 /* Used by MakePrintStatus */ #define DONECYCLE 0x2000 /* Used by MakePrintStatus */ enum enum_made { UNMADE, DEFERRED, REQUESTED, BEINGMADE, MADE, UPTODATE, ERROR, ABORTED } made; /* Set to reflect the state of processing * on this node: * UNMADE - Not examined yet * DEFERRED - Examined once (building child) * REQUESTED - on toBeMade list * BEINGMADE - Target is already being made. * Indicates a cycle in the graph. * MADE - Was out-of-date and has been made * UPTODATE - Was already up-to-date * ERROR - An error occurred while it was being * made (used only in compat mode) * ABORTED - The target was aborted due to * an error making an inferior (compat). */ int unmade; /* The number of unmade children */ time_t mtime; /* Its modification time */ struct GNode *cmgn; /* The youngest child */ Lst iParents; /* Links to parents for which this is an * implied source, if any */ Lst cohorts; /* Other nodes for the :: operator */ Lst parents; /* Nodes that depend on this one */ Lst children; /* Nodes on which this one depends */ Lst order_pred; /* .ORDER nodes we need made */ Lst order_succ; /* .ORDER nodes who need us */ char cohort_num[8]; /* #n for this cohort */ int unmade_cohorts;/* # of unmade instances on the cohorts list */ struct GNode *centurion; /* Pointer to the first instance of a :: node; only set when on a cohorts list */ unsigned int checked; /* Last time we tried to makle this node */ Hash_Table context; /* The local variables */ Lst commands; /* Creation commands */ struct _Suff *suffix; /* Suffix for the node (determined by * Suff_FindDeps and opaque to everyone * but the Suff module) */ const char *fname; /* filename where the GNode got defined */ int lineno; /* line number where the GNode got defined */ } GNode; /* * recursive make so its * commands should always be executed when * it is out of date, regardless of the * state of the -n or -t flags */ #define OP_JOIN 0x00000400 /* Target is out-of-date only if any of its * children was out-of-date */ #define OP_MADE 0x00000800 /* Assume the children of the node have * been already made */ #define OP_SPECIAL 0x00001000 /* Special .BEGIN, .END, .INTERRUPT */ #define OP_USEBEFORE 0x00002000 /* Like .USE, only prepend commands */  */ #define OP_NOPATH 0x00020000 /* Don't search for file in the path */ #define OP_WAIT 0x00040000 /* .WAIT phony node */ #define OP_NOMETA 0x00080000 /* .NOMETA do not create a .meta file */ #define OP_META 0x00100000 /* .META we _do_ want a .meta file */ #define OP_NOMETA_CMP 0x00200000 /* Do not compare commands in .meta file */ /* */ #define OP_MARK 0x01000000 /* Node found while expanding .ALLSRC */ #define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute) /* * OP_NOP will return TRUE if the node with the given type was not the * object of a dependency operator */ #define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000) #define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM) /* *_NOCREATE 0x00 /* don't create it */ #define TARG_CREATE 0x01 /* create node if not found */ #define TARG_NOHASH 0x02 /* don't look in/add to hash table */ /* *_ADDSLASH 0x Boolean compatMake; /* True if we are make compatible */ extern Boolean ignoreErrors; /* True if should ignore all errors */ extern Boolean beSilent; /* True if should print no commands */ extern Boolean noExecute; /* True if should execute nothing */ extern Boolean noRecursive queryFlag; /* TRUE if we aren't supposed to really make * anything, just see if the targets are out- * of-date */ extern Boolean doing_depend; /* TRUE if processing .depend */ extern Boolean checkEnvFirst; /* TRUE if environment should be searched for * variables before the global context */ extern Boolean jobServer; /* a jobServer already exists */ extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are * treated as errors */ extern Boolean varNoExportEnv; /* TRUE if we should not export variables * set on the command line to the env. */ extern GNode *DEFAULT; /* .DEFAULT rule */ extern GNode *VAR_INTERNAL; /* Variables defined internally by make * which should not override those set by * makefiles. */ extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g * in the Makefile itself */ extern GNode *VAR_CMD; /* Variables defined on the command line */ extern GNode *VAR_FOR; /* Iteration variables */. */ extern Lst defIncPath; /* The default include path. */ extern char curdir[]; /* Startup directory */ extern char *progname; /* The program name */ extern char *makeDependfile; /* .depend */ extern char **savedEnv; /* if we replaced environ this will be non-NULL */ /* * We cannot vfork() in a child of vfork(). * Most systems do not enforce this but some do. */ #define vFork() ((getpid() == myPid) ? vfork() : fork()) extern pid_t myPid; #define MAKEFLAGS ".MAKEFLAGS" #define MAKEOVERRIDES ".MAKEOVERRIDES" #define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */ #define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */ #define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */ #define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */ #define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE" #define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */ #define MAKE_MODE ".MAKE.MODE" #ifndef MAKE_LEVEL_ENV # define MAKE_LEVEL_ENV "MAKELEVEL" #endif /* * debug control: * There is one bit per module. It is up to the module what debug * information to print. */ FILE *debug_file; /* Output written here - default stdout */ extern int debug; #define DEBUG_ARCH 0x00001 #define DEBUG_COND 0x00002 #define DEBUG_DIR 0x00004 #define DEBUG_GRAPH1 0x00008 #define DEBUG_GRAPH2 0x00010 #define DEBUG_JOB 0x00020 #define DEBUG_MAKE 0x00040 #define DEBUG_SUFF 0x00080 #define DEBUG_TARG 0x00100 #define DEBUG_VAR 0x00200 #define DEBUG_FOR 0x00400 #define DEBUG_SHELL 0x00800 #define DEBUG_ERROR 0x01000 #define DEBUG_LOUD 0x02000 #define DEBUG_META 0x04000 #define DEBUG_GRAPH3 0x10000 #define DEBUG_SCRIPT 0x20000 #define DEBUG_PARSE 0x40000 #define DEBUG_CWD 0x80000 #define CONCAT(a,b) a##b #define DEBUG(module) (debug & CONCAT(DEBUG_,module)) #include "nonints.h" int Make_TimeStamp(GNode *, GNode *); Boolean Make_OODate(GNode *); void Make_ExpandUse(Lst); time_t Make_Recheck(GNode *); void Make_HandleUse(GNode *, GNode *); void Make_Update(GNode *); void Make_DoAllVar(GNode *); Boolean Make_Run(Lst); char * Check_Cwd_Cmd(const char *); void Check_Cwd(const char **); void PrintOnError(GNode *, const char *); void Main_ExportMAKEFLAGS(Boolean); Boolean Main_SetObjdir(const char *); int mkTempFile(const char *, char **); int str2Lst_Append(Lst, char *, const char *); #ifdef __GNUC__ #define UNCONST(ptr) ({ \ union __unconst { \ const void *__cp; \ void *__p; \ } __d; \ __d.__cp = ptr, __d.__p; }) #else #define UNCONST(ptr) (void *)(ptr) #endif #ifndef MIN #define MIN(a, b) ((a < b) ? a : b) #endif #ifndef MAX #define MAX(a, b) ((a > b) ? a : b) #endif #endif /* _MAKE_H_ */