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