xref: /freebsd/contrib/bmake/make.h (revision 06b9b3e0ad0dc3f0166b3e8f26ced68c271cf527)
1*06b9b3e0SSimon J. Gerraty /*	$NetBSD: make.h,v 1.242 2021/01/10 21:20:46 rillig Exp $	*/
23955d011SMarcel Moolenaar 
33955d011SMarcel Moolenaar /*
43955d011SMarcel Moolenaar  * Copyright (c) 1988, 1989, 1990, 1993
53955d011SMarcel Moolenaar  *	The Regents of the University of California.  All rights reserved.
63955d011SMarcel Moolenaar  *
73955d011SMarcel Moolenaar  * This code is derived from software contributed to Berkeley by
83955d011SMarcel Moolenaar  * Adam de Boor.
93955d011SMarcel Moolenaar  *
103955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
113955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
123955d011SMarcel Moolenaar  * are met:
133955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
143955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
153955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
163955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
173955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
183955d011SMarcel Moolenaar  * 3. Neither the name of the University nor the names of its contributors
193955d011SMarcel Moolenaar  *    may be used to endorse or promote products derived from this software
203955d011SMarcel Moolenaar  *    without specific prior written permission.
213955d011SMarcel Moolenaar  *
223955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233955d011SMarcel Moolenaar  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243955d011SMarcel Moolenaar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253955d011SMarcel Moolenaar  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263955d011SMarcel Moolenaar  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273955d011SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283955d011SMarcel Moolenaar  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293955d011SMarcel Moolenaar  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303955d011SMarcel Moolenaar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313955d011SMarcel Moolenaar  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323955d011SMarcel Moolenaar  * SUCH DAMAGE.
333955d011SMarcel Moolenaar  *
343955d011SMarcel Moolenaar  *	from: @(#)make.h	8.3 (Berkeley) 6/13/95
353955d011SMarcel Moolenaar  */
363955d011SMarcel Moolenaar 
373955d011SMarcel Moolenaar /*
383955d011SMarcel Moolenaar  * Copyright (c) 1989 by Berkeley Softworks
393955d011SMarcel Moolenaar  * All rights reserved.
403955d011SMarcel Moolenaar  *
413955d011SMarcel Moolenaar  * This code is derived from software contributed to Berkeley by
423955d011SMarcel Moolenaar  * Adam de Boor.
433955d011SMarcel Moolenaar  *
443955d011SMarcel Moolenaar  * Redistribution and use in source and binary forms, with or without
453955d011SMarcel Moolenaar  * modification, are permitted provided that the following conditions
463955d011SMarcel Moolenaar  * are met:
473955d011SMarcel Moolenaar  * 1. Redistributions of source code must retain the above copyright
483955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer.
493955d011SMarcel Moolenaar  * 2. Redistributions in binary form must reproduce the above copyright
503955d011SMarcel Moolenaar  *    notice, this list of conditions and the following disclaimer in the
513955d011SMarcel Moolenaar  *    documentation and/or other materials provided with the distribution.
523955d011SMarcel Moolenaar  * 3. All advertising materials mentioning features or use of this software
533955d011SMarcel Moolenaar  *    must display the following acknowledgement:
543955d011SMarcel Moolenaar  *	This product includes software developed by the University of
553955d011SMarcel Moolenaar  *	California, Berkeley and its contributors.
563955d011SMarcel Moolenaar  * 4. Neither the name of the University nor the names of its contributors
573955d011SMarcel Moolenaar  *    may be used to endorse or promote products derived from this software
583955d011SMarcel Moolenaar  *    without specific prior written permission.
593955d011SMarcel Moolenaar  *
603955d011SMarcel Moolenaar  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
613955d011SMarcel Moolenaar  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
623955d011SMarcel Moolenaar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
633955d011SMarcel Moolenaar  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
643955d011SMarcel Moolenaar  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
653955d011SMarcel Moolenaar  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
663955d011SMarcel Moolenaar  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
673955d011SMarcel Moolenaar  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
683955d011SMarcel Moolenaar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
693955d011SMarcel Moolenaar  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
703955d011SMarcel Moolenaar  * SUCH DAMAGE.
713955d011SMarcel Moolenaar  *
723955d011SMarcel Moolenaar  *	from: @(#)make.h	8.3 (Berkeley) 6/13/95
733955d011SMarcel Moolenaar  */
743955d011SMarcel Moolenaar 
753955d011SMarcel Moolenaar /*-
763955d011SMarcel Moolenaar  * make.h --
773955d011SMarcel Moolenaar  *	The global definitions for pmake
783955d011SMarcel Moolenaar  */
793955d011SMarcel Moolenaar 
802c3632d1SSimon J. Gerraty #ifndef MAKE_MAKE_H
812c3632d1SSimon J. Gerraty #define MAKE_MAKE_H
823955d011SMarcel Moolenaar 
833955d011SMarcel Moolenaar #ifdef HAVE_CONFIG_H
843955d011SMarcel Moolenaar # include "config.h"
853955d011SMarcel Moolenaar #endif
863955d011SMarcel Moolenaar 
873955d011SMarcel Moolenaar #include <sys/types.h>
883955d011SMarcel Moolenaar #include <sys/param.h>
892c3632d1SSimon J. Gerraty #include <sys/stat.h>
903955d011SMarcel Moolenaar 
912c3632d1SSimon J. Gerraty #include <assert.h>
923955d011SMarcel Moolenaar #include <ctype.h>
93be19d90bSSimon J. Gerraty #include <fcntl.h>
94956e45f6SSimon J. Gerraty #include <stdarg.h>
953955d011SMarcel Moolenaar #include <stdio.h>
963955d011SMarcel Moolenaar #include <stdlib.h>
973955d011SMarcel Moolenaar #ifdef HAVE_STRING_H
983955d011SMarcel Moolenaar #include <string.h>
993955d011SMarcel Moolenaar #else
1003955d011SMarcel Moolenaar #include <strings.h>
1013955d011SMarcel Moolenaar #endif
1023955d011SMarcel Moolenaar #include <unistd.h>
1033955d011SMarcel Moolenaar #include <sys/cdefs.h>
1043955d011SMarcel Moolenaar 
105be19d90bSSimon J. Gerraty #ifndef FD_CLOEXEC
106be19d90bSSimon J. Gerraty #define FD_CLOEXEC 1
107be19d90bSSimon J. Gerraty #endif
108be19d90bSSimon J. Gerraty 
1093955d011SMarcel Moolenaar #if defined(__GNUC__)
1103955d011SMarcel Moolenaar #define MAKE_GNUC_PREREQ(x, y)						\
1113955d011SMarcel Moolenaar 	((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||			\
1123955d011SMarcel Moolenaar 	 (__GNUC__ > (x)))
1133955d011SMarcel Moolenaar #else /* defined(__GNUC__) */
1141748de26SSimon J. Gerraty #define MAKE_GNUC_PREREQ(x, y)	0
1153955d011SMarcel Moolenaar #endif /* defined(__GNUC__) */
1163955d011SMarcel Moolenaar 
1173955d011SMarcel Moolenaar #if MAKE_GNUC_PREREQ(2, 7)
1183955d011SMarcel Moolenaar #define MAKE_ATTR_UNUSED	__attribute__((__unused__))
1193955d011SMarcel Moolenaar #else
1203955d011SMarcel Moolenaar #define MAKE_ATTR_UNUSED	/* delete */
1213955d011SMarcel Moolenaar #endif
1223955d011SMarcel Moolenaar 
1233955d011SMarcel Moolenaar #if MAKE_GNUC_PREREQ(2, 5)
1243955d011SMarcel Moolenaar #define MAKE_ATTR_DEAD		__attribute__((__noreturn__))
1253955d011SMarcel Moolenaar #elif defined(__GNUC__)
1263955d011SMarcel Moolenaar #define MAKE_ATTR_DEAD		__volatile
1273955d011SMarcel Moolenaar #else
1283955d011SMarcel Moolenaar #define MAKE_ATTR_DEAD		/* delete */
1293955d011SMarcel Moolenaar #endif
1303955d011SMarcel Moolenaar 
1313955d011SMarcel Moolenaar #if MAKE_GNUC_PREREQ(2, 7)
1323955d011SMarcel Moolenaar #define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg)	\
1333955d011SMarcel Moolenaar 	    __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
1343955d011SMarcel Moolenaar #else
1353955d011SMarcel Moolenaar #define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg)	/* delete */
1363955d011SMarcel Moolenaar #endif
1373955d011SMarcel Moolenaar 
138e2eeea75SSimon J. Gerraty #define MAKE_INLINE static inline MAKE_ATTR_UNUSED
139e2eeea75SSimon J. Gerraty 
1402c3632d1SSimon J. Gerraty /*
1412c3632d1SSimon J. Gerraty  * A boolean type is defined as an integer, not an enum, for historic reasons.
1422c3632d1SSimon J. Gerraty  * The only allowed values are the constants TRUE and FALSE (1 and 0).
1432c3632d1SSimon J. Gerraty  */
144*06b9b3e0SSimon J. Gerraty #if defined(lint) || defined(USE_C99_BOOLEAN)
145*06b9b3e0SSimon J. Gerraty #include <stdbool.h>
146*06b9b3e0SSimon J. Gerraty typedef bool Boolean;
147*06b9b3e0SSimon J. Gerraty #define FALSE false
148*06b9b3e0SSimon J. Gerraty #define TRUE true
149*06b9b3e0SSimon J. Gerraty #elif defined(USE_DOUBLE_BOOLEAN)
1502c3632d1SSimon J. Gerraty /* During development, to find type mismatches in function declarations. */
1512c3632d1SSimon J. Gerraty typedef double Boolean;
152956e45f6SSimon J. Gerraty #define TRUE 1.0
153956e45f6SSimon J. Gerraty #define FALSE 0.0
1542c3632d1SSimon J. Gerraty #elif defined(USE_UCHAR_BOOLEAN)
155*06b9b3e0SSimon J. Gerraty /*
156*06b9b3e0SSimon J. Gerraty  * During development, to find code that depends on the exact value of TRUE or
157*06b9b3e0SSimon J. Gerraty  * that stores other values in Boolean variables.
158*06b9b3e0SSimon J. Gerraty  */
1592c3632d1SSimon J. Gerraty typedef unsigned char Boolean;
1602c3632d1SSimon J. Gerraty #define TRUE ((unsigned char)0xFF)
1612c3632d1SSimon J. Gerraty #define FALSE ((unsigned char)0x00)
162956e45f6SSimon J. Gerraty #elif defined(USE_CHAR_BOOLEAN)
163*06b9b3e0SSimon J. Gerraty /*
164*06b9b3e0SSimon J. Gerraty  * During development, to find code that uses a boolean as array index, via
165*06b9b3e0SSimon J. Gerraty  * -Wchar-subscripts.
166*06b9b3e0SSimon J. Gerraty  */
167956e45f6SSimon J. Gerraty typedef char Boolean;
168956e45f6SSimon J. Gerraty #define TRUE ((char)-1)
169956e45f6SSimon J. Gerraty #define FALSE ((char)0x00)
1702c3632d1SSimon J. Gerraty #elif defined(USE_ENUM_BOOLEAN)
171956e45f6SSimon J. Gerraty typedef enum Boolean { FALSE, TRUE } Boolean;
1722c3632d1SSimon J. Gerraty #else
1732c3632d1SSimon J. Gerraty typedef int Boolean;
1742c3632d1SSimon J. Gerraty #ifndef TRUE
1752c3632d1SSimon J. Gerraty #define TRUE	1
176956e45f6SSimon J. Gerraty #endif
1772c3632d1SSimon J. Gerraty #ifndef FALSE
1782c3632d1SSimon J. Gerraty #define FALSE	0
179956e45f6SSimon J. Gerraty #endif
180956e45f6SSimon J. Gerraty #endif
1812c3632d1SSimon J. Gerraty 
1823955d011SMarcel Moolenaar #include "lst.h"
1832c3632d1SSimon J. Gerraty #include "enum.h"
1843955d011SMarcel Moolenaar #include "hash.h"
1853955d011SMarcel Moolenaar #include "make-conf.h"
1863955d011SMarcel Moolenaar #include "buf.h"
1873955d011SMarcel Moolenaar #include "make_malloc.h"
1883955d011SMarcel Moolenaar 
1893955d011SMarcel Moolenaar /*
1903955d011SMarcel Moolenaar  * some vendors don't have this --sjg
1913955d011SMarcel Moolenaar  */
1923955d011SMarcel Moolenaar #if defined(S_IFDIR) && !defined(S_ISDIR)
1933955d011SMarcel Moolenaar # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
1943955d011SMarcel Moolenaar #endif
1953955d011SMarcel Moolenaar 
1963955d011SMarcel Moolenaar #if defined(sun) && (defined(__svr4__) || defined(__SVR4))
1973955d011SMarcel Moolenaar # define POSIX_SIGNALS
1983955d011SMarcel Moolenaar #endif
1993955d011SMarcel Moolenaar 
200*06b9b3e0SSimon J. Gerraty /*
201*06b9b3e0SSimon J. Gerraty  * The typical flow of states is:
202*06b9b3e0SSimon J. Gerraty  *
203*06b9b3e0SSimon J. Gerraty  * The direct successful path:
204*06b9b3e0SSimon J. Gerraty  * UNMADE -> BEINGMADE -> MADE.
205*06b9b3e0SSimon J. Gerraty  *
206*06b9b3e0SSimon J. Gerraty  * The direct error path:
207*06b9b3e0SSimon J. Gerraty  * UNMADE -> BEINGMADE -> ERROR.
208*06b9b3e0SSimon J. Gerraty  *
209*06b9b3e0SSimon J. Gerraty  * The successful path when dependencies need to be made first:
210*06b9b3e0SSimon J. Gerraty  * UNMADE -> DEFERRED -> REQUESTED -> BEINGMADE -> MADE.
211*06b9b3e0SSimon J. Gerraty  *
212*06b9b3e0SSimon J. Gerraty  * A node that has dependencies, and one of the dependencies cannot be made:
213*06b9b3e0SSimon J. Gerraty  * UNMADE -> DEFERRED -> ABORTED.
214*06b9b3e0SSimon J. Gerraty  *
215*06b9b3e0SSimon J. Gerraty  * A node that turns out to be up-to-date:
216*06b9b3e0SSimon J. Gerraty  * UNMADE -> BEINGMADE -> UPTODATE.
217*06b9b3e0SSimon J. Gerraty  */
218e2eeea75SSimon J. Gerraty typedef enum GNodeMade {
219*06b9b3e0SSimon J. Gerraty 	/* Not examined yet. */
220*06b9b3e0SSimon J. Gerraty 	UNMADE,
221*06b9b3e0SSimon J. Gerraty 	/* The node has been examined but is not yet ready since its
222*06b9b3e0SSimon J. Gerraty 	 * dependencies have to be made first. */
223*06b9b3e0SSimon J. Gerraty 	DEFERRED,
224*06b9b3e0SSimon J. Gerraty 
225*06b9b3e0SSimon J. Gerraty 	/* The node is on the toBeMade list. */
226*06b9b3e0SSimon J. Gerraty 	REQUESTED,
227*06b9b3e0SSimon J. Gerraty 
228*06b9b3e0SSimon J. Gerraty 	/* The node is already being made. Trying to build a node in this
229*06b9b3e0SSimon J. Gerraty 	 * state indicates a cycle in the graph. */
230*06b9b3e0SSimon J. Gerraty 	BEINGMADE,
231*06b9b3e0SSimon J. Gerraty 
232*06b9b3e0SSimon J. Gerraty 	/* Was out-of-date and has been made. */
233*06b9b3e0SSimon J. Gerraty 	MADE,
234*06b9b3e0SSimon J. Gerraty 	/* Was already up-to-date, does not need to be made. */
235*06b9b3e0SSimon J. Gerraty 	UPTODATE,
236*06b9b3e0SSimon J. Gerraty 	/* An error occurred while it was being made.
237*06b9b3e0SSimon J. Gerraty 	 * Used only in compat mode. */
238*06b9b3e0SSimon J. Gerraty 	ERROR,
239*06b9b3e0SSimon J. Gerraty 	/* The target was aborted due to an error making a dependency.
240*06b9b3e0SSimon J. Gerraty 	 * Used only in compat mode. */
241*06b9b3e0SSimon J. Gerraty 	ABORTED
2422c3632d1SSimon J. Gerraty } GNodeMade;
2433955d011SMarcel Moolenaar 
244*06b9b3e0SSimon J. Gerraty /*
245*06b9b3e0SSimon J. Gerraty  * The OP_ constants are used when parsing a dependency line as a way of
2462c3632d1SSimon J. Gerraty  * communicating to other parts of the program the way in which a target
2472c3632d1SSimon J. Gerraty  * should be made.
2482c3632d1SSimon J. Gerraty  *
249*06b9b3e0SSimon J. Gerraty  * Some of the OP_ constants can be combined, others cannot.
250*06b9b3e0SSimon J. Gerraty  */
251956e45f6SSimon J. Gerraty typedef enum GNodeType {
252e2eeea75SSimon J. Gerraty 	OP_NONE		= 0,
253e2eeea75SSimon J. Gerraty 
254*06b9b3e0SSimon J. Gerraty 	/* The dependency operator ':' is the most common one.  The commands
255*06b9b3e0SSimon J. Gerraty 	 * of this node are executed if any child is out-of-date. */
2562c3632d1SSimon J. Gerraty 	OP_DEPENDS	= 1 << 0,
257956e45f6SSimon J. Gerraty 	/* The dependency operator '!' always executes its commands, even if
258956e45f6SSimon J. Gerraty 	 * its children are up-to-date. */
2592c3632d1SSimon J. Gerraty 	OP_FORCE	= 1 << 1,
260*06b9b3e0SSimon J. Gerraty 	/* The dependency operator '::' behaves like ':', except that it
261*06b9b3e0SSimon J. Gerraty 	 * allows multiple dependency groups to be defined.  Each of these
262*06b9b3e0SSimon J. Gerraty 	 * groups is executed on its own, independently from the others.
263*06b9b3e0SSimon J. Gerraty 	 * Each individual dependency group is called a cohort. */
2642c3632d1SSimon J. Gerraty 	OP_DOUBLEDEP	= 1 << 2,
2652c3632d1SSimon J. Gerraty 
266956e45f6SSimon J. Gerraty 	/* Matches the dependency operators ':', '!' and '::'. */
2672c3632d1SSimon J. Gerraty 	OP_OPMASK	= OP_DEPENDS | OP_FORCE | OP_DOUBLEDEP,
2682c3632d1SSimon J. Gerraty 
269*06b9b3e0SSimon J. Gerraty 	/* Don't care if the target doesn't exist and can't be created. */
2702c3632d1SSimon J. Gerraty 	OP_OPTIONAL	= 1 << 3,
271*06b9b3e0SSimon J. Gerraty 	/* Use associated commands for parents. */
2722c3632d1SSimon J. Gerraty 	OP_USE		= 1 << 4,
2732c3632d1SSimon J. Gerraty 	/* Target is never out of date, but always execute commands anyway.
274*06b9b3e0SSimon J. Gerraty 	 * Its time doesn't matter, so it has none...sort of. */
2752c3632d1SSimon J. Gerraty 	OP_EXEC		= 1 << 5,
276*06b9b3e0SSimon J. Gerraty 	/* Ignore non-zero exit status from shell commands when creating the
277*06b9b3e0SSimon J. Gerraty 	 * node. */
2782c3632d1SSimon J. Gerraty 	OP_IGNORE	= 1 << 6,
279*06b9b3e0SSimon J. Gerraty 	/* Don't remove the target when interrupted. */
2802c3632d1SSimon J. Gerraty 	OP_PRECIOUS	= 1 << 7,
281*06b9b3e0SSimon J. Gerraty 	/* Don't echo commands when executed. */
2822c3632d1SSimon J. Gerraty 	OP_SILENT	= 1 << 8,
283*06b9b3e0SSimon J. Gerraty 	/* Target is a recursive make so its commands should always be
284*06b9b3e0SSimon J. Gerraty 	 * executed when it is out of date, regardless of the state of the
285*06b9b3e0SSimon J. Gerraty 	 * -n or -t flags. */
2862c3632d1SSimon J. Gerraty 	OP_MAKE		= 1 << 9,
287*06b9b3e0SSimon J. Gerraty 	/* Target is out-of-date only if any of its children was out-of-date. */
2882c3632d1SSimon J. Gerraty 	OP_JOIN		= 1 << 10,
289*06b9b3e0SSimon J. Gerraty 	/* Assume the children of the node have been already made. */
2902c3632d1SSimon J. Gerraty 	OP_MADE		= 1 << 11,
291*06b9b3e0SSimon J. Gerraty 	/* Special .BEGIN, .END or .INTERRUPT. */
2922c3632d1SSimon J. Gerraty 	OP_SPECIAL	= 1 << 12,
293*06b9b3e0SSimon J. Gerraty 	/* Like .USE, only prepend commands. */
2942c3632d1SSimon J. Gerraty 	OP_USEBEFORE	= 1 << 13,
295*06b9b3e0SSimon J. Gerraty 	/* The node is invisible to its parents. I.e. it doesn't show up in
296*06b9b3e0SSimon J. Gerraty 	 * the parents' local variables (.IMPSRC, .ALLSRC). */
2972c3632d1SSimon J. Gerraty 	OP_INVISIBLE	= 1 << 14,
298*06b9b3e0SSimon J. Gerraty 	/* The node does not become the main target, even if it is the first
299*06b9b3e0SSimon J. Gerraty 	 * target in the first makefile. */
3002c3632d1SSimon J. Gerraty 	OP_NOTMAIN	= 1 << 15,
301*06b9b3e0SSimon J. Gerraty 	/* Not a file target; run always. */
3022c3632d1SSimon J. Gerraty 	OP_PHONY	= 1 << 16,
303*06b9b3e0SSimon J. Gerraty 	/* Don't search for the file in the path. */
3042c3632d1SSimon J. Gerraty 	OP_NOPATH	= 1 << 17,
305*06b9b3e0SSimon J. Gerraty 	/* In a dependency line "target: source1 .WAIT source2", source1 is
306*06b9b3e0SSimon J. Gerraty 	 * made first, including its children.  Once that is finished,
307*06b9b3e0SSimon J. Gerraty 	 * source2 is made, including its children.  The .WAIT keyword may
308*06b9b3e0SSimon J. Gerraty 	 * appear more than once in a single dependency declaration. */
3092c3632d1SSimon J. Gerraty 	OP_WAIT		= 1 << 18,
3102c3632d1SSimon J. Gerraty 	/* .NOMETA do not create a .meta file */
3112c3632d1SSimon J. Gerraty 	OP_NOMETA	= 1 << 19,
3122c3632d1SSimon J. Gerraty 	/* .META we _do_ want a .meta file */
3132c3632d1SSimon J. Gerraty 	OP_META		= 1 << 20,
3142c3632d1SSimon J. Gerraty 	/* Do not compare commands in .meta file */
3152c3632d1SSimon J. Gerraty 	OP_NOMETA_CMP	= 1 << 21,
3162c3632d1SSimon J. Gerraty 	/* Possibly a submake node */
3172c3632d1SSimon J. Gerraty 	OP_SUBMAKE	= 1 << 22,
3182c3632d1SSimon J. Gerraty 
3192c3632d1SSimon J. Gerraty 	/* Attributes applied by PMake */
3202c3632d1SSimon J. Gerraty 
321e2eeea75SSimon J. Gerraty 	/* The node is a transformation rule, such as ".c.o". */
322*06b9b3e0SSimon J. Gerraty 	OP_TRANSFORM	= 1 << 30,
3232c3632d1SSimon J. Gerraty 	/* Target is a member of an archive */
324956e45f6SSimon J. Gerraty 	/* XXX: How does this differ from OP_ARCHV? */
325*06b9b3e0SSimon J. Gerraty 	OP_MEMBER	= 1 << 29,
326956e45f6SSimon J. Gerraty 	/* The node is a library,
327956e45f6SSimon J. Gerraty 	 * its name has the form "-l<libname>" */
328*06b9b3e0SSimon J. Gerraty 	OP_LIB		= 1 << 28,
329956e45f6SSimon J. Gerraty 	/* The node is an archive member,
330956e45f6SSimon J. Gerraty 	 * its name has the form "archive(member)" */
331956e45f6SSimon J. Gerraty 	/* XXX: How does this differ from OP_MEMBER? */
332*06b9b3e0SSimon J. Gerraty 	OP_ARCHV	= 1 << 27,
3332c3632d1SSimon J. Gerraty 	/* Target has all the commands it should. Used when parsing to catch
334*06b9b3e0SSimon J. Gerraty 	 * multiple command groups for a target.  Only applies to the
335*06b9b3e0SSimon J. Gerraty 	 * dependency operators ':' and '!', but not to '::'. */
336*06b9b3e0SSimon J. Gerraty 	OP_HAS_COMMANDS	= 1 << 26,
337956e45f6SSimon J. Gerraty 	/* The special command "..." has been seen. All further commands from
338956e45f6SSimon J. Gerraty 	 * this node will be saved on the .END node instead, to be executed at
339956e45f6SSimon J. Gerraty 	 * the very end. */
340*06b9b3e0SSimon J. Gerraty 	OP_SAVE_CMDS	= 1 << 25,
341*06b9b3e0SSimon J. Gerraty 	/* Already processed by Suff_FindDeps, to find dependencies from
342*06b9b3e0SSimon J. Gerraty 	 * suffix transformation rules. */
343*06b9b3e0SSimon J. Gerraty 	OP_DEPS_FOUND	= 1 << 24,
3442c3632d1SSimon J. Gerraty 	/* Node found while expanding .ALLSRC */
345*06b9b3e0SSimon J. Gerraty 	OP_MARK		= 1 << 23,
346956e45f6SSimon J. Gerraty 
347956e45f6SSimon J. Gerraty 	OP_NOTARGET	= OP_NOTMAIN | OP_USE | OP_EXEC | OP_TRANSFORM
3482c3632d1SSimon J. Gerraty } GNodeType;
3492c3632d1SSimon J. Gerraty 
350956e45f6SSimon J. Gerraty typedef enum GNodeFlags {
351*06b9b3e0SSimon J. Gerraty 	GNF_NONE	= 0,
352*06b9b3e0SSimon J. Gerraty 	/* this target needs to be (re)made */
353*06b9b3e0SSimon J. Gerraty 	REMAKE		= 0x0001,
354*06b9b3e0SSimon J. Gerraty 	/* children of this target were made */
355*06b9b3e0SSimon J. Gerraty 	CHILDMADE	= 0x0002,
356*06b9b3e0SSimon J. Gerraty 	/* children don't exist, and we pretend made */
357*06b9b3e0SSimon J. Gerraty 	FORCE		= 0x0004,
358*06b9b3e0SSimon J. Gerraty 	/* Set by Make_ProcessWait() */
359*06b9b3e0SSimon J. Gerraty 	DONE_WAIT	= 0x0008,
360*06b9b3e0SSimon J. Gerraty 	/* Build requested by .ORDER processing */
361*06b9b3e0SSimon J. Gerraty 	DONE_ORDER	= 0x0010,
362*06b9b3e0SSimon J. Gerraty 	/* Node created from .depend */
363*06b9b3e0SSimon J. Gerraty 	FROM_DEPEND	= 0x0020,
364*06b9b3e0SSimon J. Gerraty 	/* We do it once only */
365*06b9b3e0SSimon J. Gerraty 	DONE_ALLSRC	= 0x0040,
366*06b9b3e0SSimon J. Gerraty 	/* Used by MakePrintStatus */
367*06b9b3e0SSimon J. Gerraty 	CYCLE		= 0x1000,
368*06b9b3e0SSimon J. Gerraty 	/* Used by MakePrintStatus */
369*06b9b3e0SSimon J. Gerraty 	DONECYCLE	= 0x2000,
370*06b9b3e0SSimon J. Gerraty 	/* Internal use only */
371*06b9b3e0SSimon J. Gerraty 	INTERNAL	= 0x4000
3722c3632d1SSimon J. Gerraty } GNodeFlags;
3732c3632d1SSimon J. Gerraty 
374956e45f6SSimon J. Gerraty typedef struct List StringList;
375956e45f6SSimon J. Gerraty typedef struct ListNode StringListNode;
376956e45f6SSimon J. Gerraty 
377956e45f6SSimon J. Gerraty typedef struct List GNodeList;
378956e45f6SSimon J. Gerraty typedef struct ListNode GNodeListNode;
379956e45f6SSimon J. Gerraty 
380956e45f6SSimon J. Gerraty typedef struct List /* of CachedDir */ SearchPath;
381956e45f6SSimon J. Gerraty 
382*06b9b3e0SSimon J. Gerraty /*
383*06b9b3e0SSimon J. Gerraty  * A graph node represents a target that can possibly be made, including its
384*06b9b3e0SSimon J. Gerraty  * relation to other targets and a lot of other details.
385*06b9b3e0SSimon J. Gerraty  */
3862c3632d1SSimon J. Gerraty typedef struct GNode {
3872c3632d1SSimon J. Gerraty 	/* The target's name, such as "clean" or "make.c" */
3882c3632d1SSimon J. Gerraty 	char *name;
3892c3632d1SSimon J. Gerraty 	/* The unexpanded name of a .USE node */
3902c3632d1SSimon J. Gerraty 	char *uname;
3912c3632d1SSimon J. Gerraty 	/* The full pathname of the file belonging to the target.
392*06b9b3e0SSimon J. Gerraty 	 * XXX: What about .PHONY targets? These don't have an associated
393*06b9b3e0SSimon J. Gerraty 	 * path. */
3942c3632d1SSimon J. Gerraty 	char *path;
3952c3632d1SSimon J. Gerraty 
396*06b9b3e0SSimon J. Gerraty 	/* The type of operator used to define the sources (see the OP flags
397*06b9b3e0SSimon J. Gerraty 	 * below).
3982c3632d1SSimon J. Gerraty 	 * XXX: This looks like a wild mixture of type and flags. */
3992c3632d1SSimon J. Gerraty 	GNodeType type;
4002c3632d1SSimon J. Gerraty 	GNodeFlags flags;
4012c3632d1SSimon J. Gerraty 
4022c3632d1SSimon J. Gerraty 	/* The state of processing on this node */
4032c3632d1SSimon J. Gerraty 	GNodeMade made;
404*06b9b3e0SSimon J. Gerraty 	/* The number of unmade children */
405*06b9b3e0SSimon J. Gerraty 	int unmade;
4063955d011SMarcel Moolenaar 
407*06b9b3e0SSimon J. Gerraty 	/* The modification time; 0 means the node does not have a
408*06b9b3e0SSimon J. Gerraty 	 * corresponding file; see GNode_IsOODate. */
409956e45f6SSimon J. Gerraty 	time_t mtime;
410956e45f6SSimon J. Gerraty 	struct GNode *youngestChild;
4113955d011SMarcel Moolenaar 
4122c3632d1SSimon J. Gerraty 	/* The GNodes for which this node is an implied source. May be empty.
4132c3632d1SSimon J. Gerraty 	 * For example, when there is an inference rule for .c.o, the node for
4142c3632d1SSimon J. Gerraty 	 * file.c has the node for file.o in this list. */
415*06b9b3e0SSimon J. Gerraty 	GNodeList implicitParents;
4163955d011SMarcel Moolenaar 
4172c3632d1SSimon J. Gerraty 	/* The nodes that depend on this one, or in other words, the nodes for
4182c3632d1SSimon J. Gerraty 	 * which this is a source. */
419*06b9b3e0SSimon J. Gerraty 	GNodeList parents;
4202c3632d1SSimon J. Gerraty 	/* The nodes on which this one depends. */
421*06b9b3e0SSimon J. Gerraty 	GNodeList children;
4223955d011SMarcel Moolenaar 
4232c3632d1SSimon J. Gerraty 	/* .ORDER nodes we need made. The nodes that must be made (if they're
4242c3632d1SSimon J. Gerraty 	 * made) before this node can be made, but that do not enter into the
4252c3632d1SSimon J. Gerraty 	 * datedness of this node. */
426*06b9b3e0SSimon J. Gerraty 	GNodeList order_pred;
427*06b9b3e0SSimon J. Gerraty 	/* .ORDER nodes who need us. The nodes that must be made (if they're
428*06b9b3e0SSimon J. Gerraty 	 * made at all) after this node is made, but that do not depend on
429*06b9b3e0SSimon J. Gerraty 	 * this node, in the normal sense. */
430*06b9b3e0SSimon J. Gerraty 	GNodeList order_succ;
4312c3632d1SSimon J. Gerraty 
432e2eeea75SSimon J. Gerraty 	/* Other nodes of the same name, for the '::' dependency operator. */
433*06b9b3e0SSimon J. Gerraty 	GNodeList cohorts;
434956e45f6SSimon J. Gerraty 	/* The "#n" suffix for this cohort, or "" for other nodes */
4352c3632d1SSimon J. Gerraty 	char cohort_num[8];
4362c3632d1SSimon J. Gerraty 	/* The number of unmade instances on the cohorts list */
4372c3632d1SSimon J. Gerraty 	int unmade_cohorts;
4382c3632d1SSimon J. Gerraty 	/* Pointer to the first instance of a '::' node; only set when on a
4392c3632d1SSimon J. Gerraty 	 * cohorts list */
4402c3632d1SSimon J. Gerraty 	struct GNode *centurion;
4412c3632d1SSimon J. Gerraty 
4422c3632d1SSimon J. Gerraty 	/* Last time (sequence number) we tried to make this node */
443956e45f6SSimon J. Gerraty 	unsigned int checked_seqno;
4442c3632d1SSimon J. Gerraty 
445*06b9b3e0SSimon J. Gerraty 	/* The "local" variables that are specific to this target and this
446*06b9b3e0SSimon J. Gerraty 	 * target only, such as $@, $<, $?.
447956e45f6SSimon J. Gerraty 	 *
448956e45f6SSimon J. Gerraty 	 * Also used for the global variable scopes VAR_GLOBAL, VAR_CMDLINE,
449956e45f6SSimon J. Gerraty 	 * VAR_INTERNAL, which contain variables with arbitrary names. */
450*06b9b3e0SSimon J. Gerraty 	HashTable /* of Var pointer */ vars;
4512c3632d1SSimon J. Gerraty 
4522c3632d1SSimon J. Gerraty 	/* The commands to be given to a shell to create this target. */
453*06b9b3e0SSimon J. Gerraty 	StringList commands;
4542c3632d1SSimon J. Gerraty 
455*06b9b3e0SSimon J. Gerraty 	/* Suffix for the node (determined by Suff_FindDeps and opaque to
456*06b9b3e0SSimon J. Gerraty 	 * everyone but the Suff module) */
457*06b9b3e0SSimon J. Gerraty 	struct Suffix *suffix;
4582c3632d1SSimon J. Gerraty 
459e2eeea75SSimon J. Gerraty 	/* Filename where the GNode got defined */
460e2eeea75SSimon J. Gerraty 	/* XXX: What is the lifetime of this string? */
4612c3632d1SSimon J. Gerraty 	const char *fname;
462e2eeea75SSimon J. Gerraty 	/* Line number where the GNode got defined */
4632c3632d1SSimon J. Gerraty 	int lineno;
4643955d011SMarcel Moolenaar } GNode;
4653955d011SMarcel Moolenaar 
466e2eeea75SSimon J. Gerraty /* Error levels for diagnostics during parsing. */
467956e45f6SSimon J. Gerraty typedef enum ParseErrorLevel {
468*06b9b3e0SSimon J. Gerraty 	/* Exit when the current top-level makefile has been parsed
469*06b9b3e0SSimon J. Gerraty 	 * completely. */
470956e45f6SSimon J. Gerraty 	PARSE_FATAL = 1,
471e2eeea75SSimon J. Gerraty 	/* Print "warning"; may be upgraded to fatal by the -w option. */
472956e45f6SSimon J. Gerraty 	PARSE_WARNING,
473e2eeea75SSimon J. Gerraty 	/* Informational, mainly used during development of makefiles. */
474956e45f6SSimon J. Gerraty 	PARSE_INFO
475956e45f6SSimon J. Gerraty } ParseErrorLevel;
4763955d011SMarcel Moolenaar 
4773955d011SMarcel Moolenaar /*
478956e45f6SSimon J. Gerraty  * Values returned by Cond_EvalLine and Cond_EvalCondition.
4793955d011SMarcel Moolenaar  */
480956e45f6SSimon J. Gerraty typedef enum CondEvalResult {
4812c3632d1SSimon J. Gerraty 	COND_PARSE,		/* Parse the next lines */
4822c3632d1SSimon J. Gerraty 	COND_SKIP,		/* Skip the next lines */
4832c3632d1SSimon J. Gerraty 	COND_INVALID		/* Not a conditional statement */
4842c3632d1SSimon J. Gerraty } CondEvalResult;
4853955d011SMarcel Moolenaar 
486e2eeea75SSimon J. Gerraty /* Names of the variables that are "local" to a specific target. */
4873955d011SMarcel Moolenaar #define TARGET	"@"	/* Target of dependency */
4883955d011SMarcel Moolenaar #define OODATE	"?"	/* All out-of-date sources */
4893955d011SMarcel Moolenaar #define ALLSRC	">"	/* All sources */
4903955d011SMarcel Moolenaar #define IMPSRC	"<"	/* Source implied by transformation */
4913955d011SMarcel Moolenaar #define PREFIX	"*"	/* Common prefix */
4923955d011SMarcel Moolenaar #define ARCHIVE	"!"	/* Archive in "archive(member)" syntax */
4933955d011SMarcel Moolenaar #define MEMBER	"%"	/* Member in "archive(member)" syntax */
4943955d011SMarcel Moolenaar 
4953955d011SMarcel Moolenaar /*
4963955d011SMarcel Moolenaar  * Global Variables
4973955d011SMarcel Moolenaar  */
4983955d011SMarcel Moolenaar 
499e2eeea75SSimon J. Gerraty /* True if every target is precious */
500e2eeea75SSimon J. Gerraty extern Boolean allPrecious;
501e2eeea75SSimon J. Gerraty /* True if failed targets should be deleted */
502e2eeea75SSimon J. Gerraty extern Boolean deleteOnError;
503e2eeea75SSimon J. Gerraty /* TRUE while processing .depend */
504e2eeea75SSimon J. Gerraty extern Boolean doing_depend;
505e2eeea75SSimon J. Gerraty /* .DEFAULT rule */
506e2eeea75SSimon J. Gerraty extern GNode *defaultNode;
5073955d011SMarcel Moolenaar 
508*06b9b3e0SSimon J. Gerraty /*
509*06b9b3e0SSimon J. Gerraty  * Variables defined internally by make which should not override those set
510*06b9b3e0SSimon J. Gerraty  * by makefiles.
511*06b9b3e0SSimon J. Gerraty  */
512e2eeea75SSimon J. Gerraty extern GNode *VAR_INTERNAL;
513e2eeea75SSimon J. Gerraty /* Variables defined in a global context, e.g in the Makefile itself. */
514e2eeea75SSimon J. Gerraty extern GNode *VAR_GLOBAL;
515e2eeea75SSimon J. Gerraty /* Variables defined on the command line. */
516e2eeea75SSimon J. Gerraty extern GNode *VAR_CMDLINE;
517e2eeea75SSimon J. Gerraty 
518*06b9b3e0SSimon J. Gerraty /*
519*06b9b3e0SSimon J. Gerraty  * Value returned by Var_Parse when an error is encountered. It actually
520*06b9b3e0SSimon J. Gerraty  * points to an empty string, so naive callers needn't worry about it.
521*06b9b3e0SSimon J. Gerraty  */
522e2eeea75SSimon J. Gerraty extern char var_Error[];
523e2eeea75SSimon J. Gerraty 
524e2eeea75SSimon J. Gerraty /* The time at the start of this whole process */
525e2eeea75SSimon J. Gerraty extern time_t now;
526e2eeea75SSimon J. Gerraty 
527e2eeea75SSimon J. Gerraty /*
528*06b9b3e0SSimon J. Gerraty  * The list of directories to search when looking for targets (set by the
529*06b9b3e0SSimon J. Gerraty  * special target .PATH).
5301bbe5942SSimon J. Gerraty  */
531*06b9b3e0SSimon J. Gerraty extern SearchPath dirSearchPath;
532e2eeea75SSimon J. Gerraty /* Used for .include "...". */
533e2eeea75SSimon J. Gerraty extern SearchPath *parseIncPath;
534*06b9b3e0SSimon J. Gerraty /*
535*06b9b3e0SSimon J. Gerraty  * Used for .include <...>, for the built-in sys.mk and makefiles from the
536*06b9b3e0SSimon J. Gerraty  * command line arguments.
537*06b9b3e0SSimon J. Gerraty  */
538e2eeea75SSimon J. Gerraty extern SearchPath *sysIncPath;
539e2eeea75SSimon J. Gerraty /* The default for sysIncPath. */
540e2eeea75SSimon J. Gerraty extern SearchPath *defSysIncPath;
5413955d011SMarcel Moolenaar 
542e2eeea75SSimon J. Gerraty /* Startup directory */
543e2eeea75SSimon J. Gerraty extern char curdir[];
544e2eeea75SSimon J. Gerraty /* The basename of the program name, suffixed with [n] for sub-makes.  */
545*06b9b3e0SSimon J. Gerraty extern const char *progname;
546e2eeea75SSimon J. Gerraty /* Name of the .depend makefile */
547e2eeea75SSimon J. Gerraty extern char *makeDependfile;
548e2eeea75SSimon J. Gerraty /* If we replaced environ, this will be non-NULL. */
549e2eeea75SSimon J. Gerraty extern char **savedEnv;
5503955d011SMarcel Moolenaar 
5512c3632d1SSimon J. Gerraty extern int makelevel;
5522c3632d1SSimon J. Gerraty 
5533955d011SMarcel Moolenaar /*
5543955d011SMarcel Moolenaar  * We cannot vfork() in a child of vfork().
5553955d011SMarcel Moolenaar  * Most systems do not enforce this but some do.
5563955d011SMarcel Moolenaar  */
5573955d011SMarcel Moolenaar #define vFork() ((getpid() == myPid) ? vfork() : fork())
5583955d011SMarcel Moolenaar extern pid_t myPid;
5593955d011SMarcel Moolenaar 
5603955d011SMarcel Moolenaar #define MAKEFLAGS	".MAKEFLAGS"
5613955d011SMarcel Moolenaar #define MAKEOVERRIDES	".MAKEOVERRIDES"
562*06b9b3e0SSimon J. Gerraty /* prefix when printing the target of a job */
563*06b9b3e0SSimon J. Gerraty #define MAKE_JOB_PREFIX	".MAKE.JOB.PREFIX"
564*06b9b3e0SSimon J. Gerraty #define MAKE_EXPORTED	".MAKE.EXPORTED"	/* exported variables */
565*06b9b3e0SSimon J. Gerraty #define MAKE_MAKEFILES	".MAKE.MAKEFILES"	/* all loaded makefiles */
5663955d011SMarcel Moolenaar #define MAKE_LEVEL	".MAKE.LEVEL"		/* recursion level */
567e2eeea75SSimon J. Gerraty #define MAKE_MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
5683955d011SMarcel Moolenaar #define MAKE_DEPENDFILE	".MAKE.DEPENDFILE"	/* .depend */
5693955d011SMarcel Moolenaar #define MAKE_MODE	".MAKE.MODE"
57051ee2c1cSSimon J. Gerraty #ifndef MAKE_LEVEL_ENV
57151ee2c1cSSimon J. Gerraty # define MAKE_LEVEL_ENV	"MAKELEVEL"
5723955d011SMarcel Moolenaar #endif
5733955d011SMarcel Moolenaar 
574956e45f6SSimon J. Gerraty typedef enum DebugFlags {
575e2eeea75SSimon J. Gerraty 	DEBUG_NONE	= 0,
576956e45f6SSimon J. Gerraty 	DEBUG_ARCH	= 1 << 0,
577956e45f6SSimon J. Gerraty 	DEBUG_COND	= 1 << 1,
578e2eeea75SSimon J. Gerraty 	DEBUG_CWD	= 1 << 2,
579e2eeea75SSimon J. Gerraty 	DEBUG_DIR	= 1 << 3,
580e2eeea75SSimon J. Gerraty 	DEBUG_ERROR	= 1 << 4,
581e2eeea75SSimon J. Gerraty 	DEBUG_FOR	= 1 << 5,
582e2eeea75SSimon J. Gerraty 	DEBUG_GRAPH1	= 1 << 6,
583e2eeea75SSimon J. Gerraty 	DEBUG_GRAPH2	= 1 << 7,
584e2eeea75SSimon J. Gerraty 	DEBUG_GRAPH3	= 1 << 8,
585e2eeea75SSimon J. Gerraty 	DEBUG_HASH	= 1 << 9,
586e2eeea75SSimon J. Gerraty 	DEBUG_JOB	= 1 << 10,
587e2eeea75SSimon J. Gerraty 	DEBUG_LOUD	= 1 << 11,
588e2eeea75SSimon J. Gerraty 	DEBUG_MAKE	= 1 << 12,
589e2eeea75SSimon J. Gerraty 	DEBUG_META	= 1 << 13,
590e2eeea75SSimon J. Gerraty 	DEBUG_PARSE	= 1 << 14,
591e2eeea75SSimon J. Gerraty 	DEBUG_SCRIPT	= 1 << 15,
592e2eeea75SSimon J. Gerraty 	DEBUG_SHELL	= 1 << 16,
593e2eeea75SSimon J. Gerraty 	DEBUG_SUFF	= 1 << 17,
594e2eeea75SSimon J. Gerraty 	DEBUG_TARG	= 1 << 18,
595e2eeea75SSimon J. Gerraty 	DEBUG_VAR	= 1 << 19,
596e2eeea75SSimon J. Gerraty 	DEBUG_ALL	= (1 << 20) - 1
597956e45f6SSimon J. Gerraty } DebugFlags;
5982c3632d1SSimon J. Gerraty 
5993955d011SMarcel Moolenaar #define CONCAT(a, b) a##b
6003955d011SMarcel Moolenaar 
601*06b9b3e0SSimon J. Gerraty #define DEBUG(module) ((opts.debug & CONCAT(DEBUG_, module)) != 0)
602956e45f6SSimon J. Gerraty 
603956e45f6SSimon J. Gerraty void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
604956e45f6SSimon J. Gerraty 
605*06b9b3e0SSimon J. Gerraty #define DEBUG_IMPL(module, args) \
606*06b9b3e0SSimon J. Gerraty 	do { \
607*06b9b3e0SSimon J. Gerraty 		if (DEBUG(module)) \
608*06b9b3e0SSimon J. Gerraty 			debug_printf args; \
609*06b9b3e0SSimon J. Gerraty 	} while (/*CONSTCOND*/ 0)
610*06b9b3e0SSimon J. Gerraty 
611956e45f6SSimon J. Gerraty #define DEBUG0(module, text) \
612*06b9b3e0SSimon J. Gerraty 	DEBUG_IMPL(module, ("%s", text))
613956e45f6SSimon J. Gerraty #define DEBUG1(module, fmt, arg1) \
614*06b9b3e0SSimon J. Gerraty 	DEBUG_IMPL(module, (fmt, arg1))
615956e45f6SSimon J. Gerraty #define DEBUG2(module, fmt, arg1, arg2) \
616*06b9b3e0SSimon J. Gerraty 	DEBUG_IMPL(module, (fmt, arg1, arg2))
617956e45f6SSimon J. Gerraty #define DEBUG3(module, fmt, arg1, arg2, arg3) \
618*06b9b3e0SSimon J. Gerraty 	DEBUG_IMPL(module, (fmt, arg1, arg2, arg3))
619956e45f6SSimon J. Gerraty #define DEBUG4(module, fmt, arg1, arg2, arg3, arg4) \
620*06b9b3e0SSimon J. Gerraty 	DEBUG_IMPL(module, (fmt, arg1, arg2, arg3, arg4))
621956e45f6SSimon J. Gerraty #define DEBUG5(module, fmt, arg1, arg2, arg3, arg4, arg5) \
622*06b9b3e0SSimon J. Gerraty 	DEBUG_IMPL(module, (fmt, arg1, arg2, arg3, arg4, arg5))
623956e45f6SSimon J. Gerraty 
624956e45f6SSimon J. Gerraty typedef enum PrintVarsMode {
625e2eeea75SSimon J. Gerraty 	PVM_NONE,
626e2eeea75SSimon J. Gerraty 	PVM_UNEXPANDED,
627e2eeea75SSimon J. Gerraty 	PVM_EXPANDED
628956e45f6SSimon J. Gerraty } PrintVarsMode;
629956e45f6SSimon J. Gerraty 
630956e45f6SSimon J. Gerraty /* Command line options */
631956e45f6SSimon J. Gerraty typedef struct CmdOpts {
632956e45f6SSimon J. Gerraty 	/* -B: whether we are make compatible */
633956e45f6SSimon J. Gerraty 	Boolean compatMake;
634956e45f6SSimon J. Gerraty 
635956e45f6SSimon J. Gerraty 	/* -d: debug control: There is one bit per module.  It is up to the
636956e45f6SSimon J. Gerraty 	 * module what debug information to print. */
637956e45f6SSimon J. Gerraty 	DebugFlags debug;
638956e45f6SSimon J. Gerraty 
639956e45f6SSimon J. Gerraty 	/* -df: debug output is written here - default stderr */
640956e45f6SSimon J. Gerraty 	FILE *debug_file;
641956e45f6SSimon J. Gerraty 
642e2eeea75SSimon J. Gerraty 	/* -dL: lint mode
643e2eeea75SSimon J. Gerraty 	 *
644e2eeea75SSimon J. Gerraty 	 * Runs make in strict mode, with additional checks and better error
645e2eeea75SSimon J. Gerraty 	 * handling. */
646*06b9b3e0SSimon J. Gerraty 	Boolean strict;
647e2eeea75SSimon J. Gerraty 
648956e45f6SSimon J. Gerraty 	/* -dV: for the -V option, print unexpanded variable values */
649956e45f6SSimon J. Gerraty 	Boolean debugVflag;
650956e45f6SSimon J. Gerraty 
651956e45f6SSimon J. Gerraty 	/* -e: check environment variables before global variables */
652956e45f6SSimon J. Gerraty 	Boolean checkEnvFirst;
653956e45f6SSimon J. Gerraty 
654956e45f6SSimon J. Gerraty 	/* -f: the makefiles to read */
655*06b9b3e0SSimon J. Gerraty 	StringList makefiles;
656956e45f6SSimon J. Gerraty 
657956e45f6SSimon J. Gerraty 	/* -i: if true, ignore all errors from shell commands */
658956e45f6SSimon J. Gerraty 	Boolean ignoreErrors;
659956e45f6SSimon J. Gerraty 
660956e45f6SSimon J. Gerraty 	/* -j: the maximum number of jobs that can run in parallel;
661956e45f6SSimon J. Gerraty 	 * this is coordinated with the submakes */
662956e45f6SSimon J. Gerraty 	int maxJobs;
663956e45f6SSimon J. Gerraty 
664*06b9b3e0SSimon J. Gerraty 	/* -k: if true and an error occurs while making a node, continue
665*06b9b3e0SSimon J. Gerraty 	 * making nodes that do not depend on the erroneous node */
666956e45f6SSimon J. Gerraty 	Boolean keepgoing;
667956e45f6SSimon J. Gerraty 
668956e45f6SSimon J. Gerraty 	/* -N: execute no commands from the targets */
669956e45f6SSimon J. Gerraty 	Boolean noRecursiveExecute;
670956e45f6SSimon J. Gerraty 
671956e45f6SSimon J. Gerraty 	/* -n: execute almost no commands from the targets */
672956e45f6SSimon J. Gerraty 	Boolean noExecute;
673956e45f6SSimon J. Gerraty 
674*06b9b3e0SSimon J. Gerraty 	/* -q: if true, we aren't supposed to really make anything, just see
675*06b9b3e0SSimon J. Gerraty 	 * if the targets are out-of-date */
676956e45f6SSimon J. Gerraty 	Boolean queryFlag;
677956e45f6SSimon J. Gerraty 
678956e45f6SSimon J. Gerraty 	/* -r: raw mode, without loading the builtin rules. */
679956e45f6SSimon J. Gerraty 	Boolean noBuiltins;
680956e45f6SSimon J. Gerraty 
681956e45f6SSimon J. Gerraty 	/* -s: don't echo the shell commands before executing them */
682956e45f6SSimon J. Gerraty 	Boolean beSilent;
683956e45f6SSimon J. Gerraty 
684956e45f6SSimon J. Gerraty 	/* -t: touch the targets if they are out-of-date, but don't actually
685956e45f6SSimon J. Gerraty 	 * make them */
686956e45f6SSimon J. Gerraty 	Boolean touchFlag;
687956e45f6SSimon J. Gerraty 
688956e45f6SSimon J. Gerraty 	/* -[Vv]: print expanded or unexpanded selected variables */
689956e45f6SSimon J. Gerraty 	PrintVarsMode printVars;
690956e45f6SSimon J. Gerraty 	/* -[Vv]: the variables to print */
691*06b9b3e0SSimon J. Gerraty 	StringList variables;
692956e45f6SSimon J. Gerraty 
693956e45f6SSimon J. Gerraty 	/* -W: if true, makefile parsing warnings are treated as errors */
694956e45f6SSimon J. Gerraty 	Boolean parseWarnFatal;
695956e45f6SSimon J. Gerraty 
696956e45f6SSimon J. Gerraty 	/* -w: print Entering and Leaving for submakes */
697956e45f6SSimon J. Gerraty 	Boolean enterFlag;
698956e45f6SSimon J. Gerraty 
699956e45f6SSimon J. Gerraty 	/* -X: if true, do not export variables set on the command line to the
700956e45f6SSimon J. Gerraty 	 * environment. */
701956e45f6SSimon J. Gerraty 	Boolean varNoExportEnv;
702956e45f6SSimon J. Gerraty 
703956e45f6SSimon J. Gerraty 	/* The target names specified on the command line.
704956e45f6SSimon J. Gerraty 	 * Used to resolve .if make(...) statements. */
705*06b9b3e0SSimon J. Gerraty 	StringList create;
706956e45f6SSimon J. Gerraty 
707956e45f6SSimon J. Gerraty } CmdOpts;
708956e45f6SSimon J. Gerraty 
709956e45f6SSimon J. Gerraty extern CmdOpts opts;
7103955d011SMarcel Moolenaar 
7113955d011SMarcel Moolenaar #include "nonints.h"
7123955d011SMarcel Moolenaar 
713e2eeea75SSimon J. Gerraty void GNode_UpdateYoungestChild(GNode *, GNode *);
714e2eeea75SSimon J. Gerraty Boolean GNode_IsOODate(GNode *);
715956e45f6SSimon J. Gerraty void Make_ExpandUse(GNodeList *);
7163955d011SMarcel Moolenaar time_t Make_Recheck(GNode *);
7173955d011SMarcel Moolenaar void Make_HandleUse(GNode *, GNode *);
7183955d011SMarcel Moolenaar void Make_Update(GNode *);
7193955d011SMarcel Moolenaar void Make_DoAllVar(GNode *);
720956e45f6SSimon J. Gerraty Boolean Make_Run(GNodeList *);
721e2eeea75SSimon J. Gerraty Boolean shouldDieQuietly(GNode *, int);
7223955d011SMarcel Moolenaar void PrintOnError(GNode *, const char *);
7233955d011SMarcel Moolenaar void Main_ExportMAKEFLAGS(Boolean);
724e2eeea75SSimon J. Gerraty Boolean Main_SetObjdir(Boolean, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
7253955d011SMarcel Moolenaar int mkTempFile(const char *, char **);
726e2eeea75SSimon J. Gerraty int str2Lst_Append(StringList *, char *);
7272c3632d1SSimon J. Gerraty void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
728956e45f6SSimon J. Gerraty Boolean GNode_ShouldExecute(GNode *gn);
729956e45f6SSimon J. Gerraty 
730956e45f6SSimon J. Gerraty /* See if the node was seen on the left-hand side of a dependency operator. */
731e2eeea75SSimon J. Gerraty MAKE_INLINE Boolean
732956e45f6SSimon J. Gerraty GNode_IsTarget(const GNode *gn)
733956e45f6SSimon J. Gerraty {
734956e45f6SSimon J. Gerraty 	return (gn->type & OP_OPMASK) != 0;
735956e45f6SSimon J. Gerraty }
736956e45f6SSimon J. Gerraty 
737e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
738956e45f6SSimon J. Gerraty GNode_Path(const GNode *gn)
739956e45f6SSimon J. Gerraty {
740956e45f6SSimon J. Gerraty 	return gn->path != NULL ? gn->path : gn->name;
741956e45f6SSimon J. Gerraty }
742956e45f6SSimon J. Gerraty 
743*06b9b3e0SSimon J. Gerraty MAKE_INLINE Boolean
744*06b9b3e0SSimon J. Gerraty GNode_IsWaitingFor(const GNode *gn)
745*06b9b3e0SSimon J. Gerraty {
746*06b9b3e0SSimon J. Gerraty 	return (gn->flags & REMAKE) && gn->made <= REQUESTED;
747*06b9b3e0SSimon J. Gerraty }
748*06b9b3e0SSimon J. Gerraty 
749*06b9b3e0SSimon J. Gerraty MAKE_INLINE Boolean
750*06b9b3e0SSimon J. Gerraty GNode_IsReady(const GNode *gn)
751*06b9b3e0SSimon J. Gerraty {
752*06b9b3e0SSimon J. Gerraty 	return gn->made > DEFERRED;
753*06b9b3e0SSimon J. Gerraty }
754*06b9b3e0SSimon J. Gerraty 
755*06b9b3e0SSimon J. Gerraty MAKE_INLINE Boolean
756*06b9b3e0SSimon J. Gerraty GNode_IsDone(const GNode *gn)
757*06b9b3e0SSimon J. Gerraty {
758*06b9b3e0SSimon J. Gerraty 	return gn->made >= MADE;
759*06b9b3e0SSimon J. Gerraty }
760*06b9b3e0SSimon J. Gerraty 
761*06b9b3e0SSimon J. Gerraty MAKE_INLINE Boolean
762*06b9b3e0SSimon J. Gerraty GNode_IsError(const GNode *gn)
763*06b9b3e0SSimon J. Gerraty {
764*06b9b3e0SSimon J. Gerraty 	return gn->made == ERROR || gn->made == ABORTED;
765*06b9b3e0SSimon J. Gerraty }
766*06b9b3e0SSimon J. Gerraty 
767e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
768956e45f6SSimon J. Gerraty GNode_VarTarget(GNode *gn) { return Var_ValueDirect(TARGET, gn); }
769e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
770956e45f6SSimon J. Gerraty GNode_VarOodate(GNode *gn) { return Var_ValueDirect(OODATE, gn); }
771e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
772956e45f6SSimon J. Gerraty GNode_VarAllsrc(GNode *gn) { return Var_ValueDirect(ALLSRC, gn); }
773e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
774956e45f6SSimon J. Gerraty GNode_VarImpsrc(GNode *gn) { return Var_ValueDirect(IMPSRC, gn); }
775e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
776956e45f6SSimon J. Gerraty GNode_VarPrefix(GNode *gn) { return Var_ValueDirect(PREFIX, gn); }
777e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
778956e45f6SSimon J. Gerraty GNode_VarArchive(GNode *gn) { return Var_ValueDirect(ARCHIVE, gn); }
779e2eeea75SSimon J. Gerraty MAKE_INLINE const char *
780956e45f6SSimon J. Gerraty GNode_VarMember(GNode *gn) { return Var_ValueDirect(MEMBER, gn); }
7813955d011SMarcel Moolenaar 
7823955d011SMarcel Moolenaar #ifdef __GNUC__
7833955d011SMarcel Moolenaar #define UNCONST(ptr)	({		\
7843955d011SMarcel Moolenaar     union __unconst {			\
7853955d011SMarcel Moolenaar 	const void *__cp;		\
7863955d011SMarcel Moolenaar 	void *__p;			\
7873955d011SMarcel Moolenaar     } __d;				\
7883955d011SMarcel Moolenaar     __d.__cp = ptr, __d.__p; })
7893955d011SMarcel Moolenaar #else
7903955d011SMarcel Moolenaar #define UNCONST(ptr)	(void *)(ptr)
7913955d011SMarcel Moolenaar #endif
7923955d011SMarcel Moolenaar 
7934c620fe5SSimon J. Gerraty /* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
7944c620fe5SSimon J. Gerraty #ifdef HAVE_LIMITS_H
7954c620fe5SSimon J. Gerraty #include <limits.h>
7964c620fe5SSimon J. Gerraty #endif
7970dede8b0SSimon J. Gerraty #ifndef MAXPATHLEN
7980dede8b0SSimon J. Gerraty #define MAXPATHLEN	BMAKE_PATH_MAX
7990dede8b0SSimon J. Gerraty #endif
8004c620fe5SSimon J. Gerraty #ifndef PATH_MAX
8014c620fe5SSimon J. Gerraty #define PATH_MAX	MAXPATHLEN
8024c620fe5SSimon J. Gerraty #endif
8030dede8b0SSimon J. Gerraty 
804c7019bf7SSimon J. Gerraty #if defined(SYSV)
805c7019bf7SSimon J. Gerraty #define KILLPG(pid, sig) kill(-(pid), (sig))
806c7019bf7SSimon J. Gerraty #else
807c7019bf7SSimon J. Gerraty #define KILLPG(pid, sig) killpg((pid), (sig))
808c7019bf7SSimon J. Gerraty #endif
809c7019bf7SSimon J. Gerraty 
810e2eeea75SSimon J. Gerraty MAKE_INLINE Boolean
811e2eeea75SSimon J. Gerraty ch_isalnum(char ch) { return isalnum((unsigned char)ch) != 0; }
812e2eeea75SSimon J. Gerraty MAKE_INLINE Boolean
813e2eeea75SSimon J. Gerraty ch_isalpha(char ch) { return isalpha((unsigned char)ch) != 0; }
814e2eeea75SSimon J. Gerraty MAKE_INLINE Boolean
815e2eeea75SSimon J. Gerraty ch_isdigit(char ch) { return isdigit((unsigned char)ch) != 0; }
816e2eeea75SSimon J. Gerraty MAKE_INLINE Boolean
817e2eeea75SSimon J. Gerraty ch_isspace(char ch) { return isspace((unsigned char)ch) != 0; }
818e2eeea75SSimon J. Gerraty MAKE_INLINE Boolean
819e2eeea75SSimon J. Gerraty ch_isupper(char ch) { return isupper((unsigned char)ch) != 0; }
820e2eeea75SSimon J. Gerraty MAKE_INLINE char
821e2eeea75SSimon J. Gerraty ch_tolower(char ch) { return (char)tolower((unsigned char)ch); }
822e2eeea75SSimon J. Gerraty MAKE_INLINE char
823e2eeea75SSimon J. Gerraty ch_toupper(char ch) { return (char)toupper((unsigned char)ch); }
824956e45f6SSimon J. Gerraty 
825e2eeea75SSimon J. Gerraty MAKE_INLINE void
826956e45f6SSimon J. Gerraty cpp_skip_whitespace(const char **pp)
827956e45f6SSimon J. Gerraty {
828956e45f6SSimon J. Gerraty 	while (ch_isspace(**pp))
829956e45f6SSimon J. Gerraty 		(*pp)++;
830956e45f6SSimon J. Gerraty }
831956e45f6SSimon J. Gerraty 
832e2eeea75SSimon J. Gerraty MAKE_INLINE void
833e2eeea75SSimon J. Gerraty cpp_skip_hspace(const char **pp)
834e2eeea75SSimon J. Gerraty {
835e2eeea75SSimon J. Gerraty 	while (**pp == ' ' || **pp == '\t')
836e2eeea75SSimon J. Gerraty 		(*pp)++;
837e2eeea75SSimon J. Gerraty }
838e2eeea75SSimon J. Gerraty 
839e2eeea75SSimon J. Gerraty MAKE_INLINE void
840956e45f6SSimon J. Gerraty pp_skip_whitespace(char **pp)
841956e45f6SSimon J. Gerraty {
842956e45f6SSimon J. Gerraty 	while (ch_isspace(**pp))
843956e45f6SSimon J. Gerraty 		(*pp)++;
844956e45f6SSimon J. Gerraty }
845956e45f6SSimon J. Gerraty 
846e2eeea75SSimon J. Gerraty MAKE_INLINE void
847e2eeea75SSimon J. Gerraty pp_skip_hspace(char **pp)
848e2eeea75SSimon J. Gerraty {
849e2eeea75SSimon J. Gerraty 	while (**pp == ' ' || **pp == '\t')
850e2eeea75SSimon J. Gerraty 		(*pp)++;
851e2eeea75SSimon J. Gerraty }
852e2eeea75SSimon J. Gerraty 
853*06b9b3e0SSimon J. Gerraty #if defined(lint)
854*06b9b3e0SSimon J. Gerraty #  define MAKE_RCSID(id) extern void do_not_define_rcsid(void)
855*06b9b3e0SSimon J. Gerraty #elif defined(MAKE_NATIVE)
856956e45f6SSimon J. Gerraty #  include <sys/cdefs.h>
857956e45f6SSimon J. Gerraty #  define MAKE_RCSID(id) __RCSID(id)
858*06b9b3e0SSimon J. Gerraty #elif defined(MAKE_ALL_IN_ONE) && defined(__COUNTER__)
859*06b9b3e0SSimon J. Gerraty #  define MAKE_RCSID_CONCAT(x, y) CONCAT(x, y)
860*06b9b3e0SSimon J. Gerraty #  define MAKE_RCSID(id) static volatile char \
861*06b9b3e0SSimon J. Gerraty 	MAKE_RCSID_CONCAT(rcsid_, __COUNTER__)[] = id
862*06b9b3e0SSimon J. Gerraty #elif defined(MAKE_ALL_IN_ONE)
863*06b9b3e0SSimon J. Gerraty #  define MAKE_RCSID(id) extern void do_not_define_rcsid(void)
864956e45f6SSimon J. Gerraty #else
865956e45f6SSimon J. Gerraty #  define MAKE_RCSID(id) static volatile char rcsid[] = id
866956e45f6SSimon J. Gerraty #endif
867956e45f6SSimon J. Gerraty 
8682c3632d1SSimon J. Gerraty #endif /* MAKE_MAKE_H */
869