Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/bmake/make.h
39475 views
1
/* $NetBSD: make.h,v 1.361 2025/07/06 07:11:31 rillig Exp $ */
2
3
/*
4
* Copyright (c) 1988, 1989, 1990, 1993
5
* The Regents of the University of California. All rights reserved.
6
*
7
* This code is derived from software contributed to Berkeley by
8
* Adam de Boor.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. Neither the name of the University nor the names of its contributors
19
* may be used to endorse or promote products derived from this software
20
* without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
* SUCH DAMAGE.
33
*
34
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
35
*/
36
37
/*
38
* Copyright (c) 1989 by Berkeley Softworks
39
* All rights reserved.
40
*
41
* This code is derived from software contributed to Berkeley by
42
* Adam de Boor.
43
*
44
* Redistribution and use in source and binary forms, with or without
45
* modification, are permitted provided that the following conditions
46
* are met:
47
* 1. Redistributions of source code must retain the above copyright
48
* notice, this list of conditions and the following disclaimer.
49
* 2. Redistributions in binary form must reproduce the above copyright
50
* notice, this list of conditions and the following disclaimer in the
51
* documentation and/or other materials provided with the distribution.
52
* 3. All advertising materials mentioning features or use of this software
53
* must display the following acknowledgement:
54
* This product includes software developed by the University of
55
* California, Berkeley and its contributors.
56
* 4. Neither the name of the University nor the names of its contributors
57
* may be used to endorse or promote products derived from this software
58
* without specific prior written permission.
59
*
60
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70
* SUCH DAMAGE.
71
*
72
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
73
*/
74
75
/*
76
* make.h --
77
* The global definitions for make
78
*/
79
80
#ifndef MAKE_MAKE_H
81
#define MAKE_MAKE_H
82
83
#ifdef HAVE_CONFIG_H
84
# include "config.h"
85
#endif
86
87
#include <sys/types.h>
88
#include <sys/param.h>
89
#include <sys/stat.h>
90
91
#include <assert.h>
92
#include <ctype.h>
93
#include <fcntl.h>
94
#include <stdarg.h>
95
#include <stdio.h>
96
#include <stdlib.h>
97
#ifdef HAVE_STRING_H
98
#include <string.h>
99
#else
100
#include <strings.h>
101
#endif
102
#include <unistd.h>
103
#include <sys/cdefs.h>
104
105
#ifndef FD_CLOEXEC
106
#define FD_CLOEXEC 1
107
#endif
108
109
#if defined(__GNUC__)
110
#define MAKE_GNUC_PREREQ(x, y) \
111
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
112
(__GNUC__ > (x)))
113
#else
114
#define MAKE_GNUC_PREREQ(x, y) 0
115
#endif
116
117
#if MAKE_GNUC_PREREQ(2, 7) || lint
118
#define MAKE_ATTR_UNUSED __attribute__((__unused__))
119
#else
120
#define MAKE_ATTR_UNUSED /* delete */
121
#endif
122
123
#if MAKE_GNUC_PREREQ(2, 5)
124
#define MAKE_ATTR_DEAD __attribute__((__noreturn__))
125
#elif defined(__GNUC__)
126
#define MAKE_ATTR_DEAD __volatile
127
#else
128
#define MAKE_ATTR_DEAD /* delete */
129
#endif
130
131
#if MAKE_GNUC_PREREQ(2, 7)
132
#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) \
133
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
134
#else
135
#define MAKE_ATTR_PRINTFLIKE(fmtarg, firstvararg) /* delete */
136
#endif
137
138
#if MAKE_GNUC_PREREQ(4, 0)
139
#define MAKE_ATTR_USE __attribute__((__warn_unused_result__))
140
#else
141
#define MAKE_ATTR_USE /* delete */
142
#endif
143
144
#if MAKE_GNUC_PREREQ(8, 0)
145
#define MAKE_ATTR_NOINLINE __attribute__((__noinline__))
146
#else
147
#define MAKE_ATTR_NOINLINE /* delete */
148
#endif
149
150
#if __STDC_VERSION__ >= 199901L || defined(lint)
151
#define MAKE_INLINE static inline MAKE_ATTR_UNUSED
152
#else
153
#define MAKE_INLINE static MAKE_ATTR_UNUSED
154
#endif
155
156
/* MAKE_STATIC marks a function that may or may not be inlined. */
157
#if defined(lint)
158
/* As of 2021-07-31, NetBSD lint ignores __attribute__((unused)). */
159
#define MAKE_STATIC MAKE_INLINE
160
#else
161
#define MAKE_STATIC static MAKE_ATTR_UNUSED
162
#endif
163
164
#if __STDC_VERSION__ >= 199901L || defined(lint) || defined(USE_C99_BOOLEAN)
165
#include <stdbool.h>
166
#elif defined(__bool_true_false_are_defined)
167
/*
168
* All files of make must be compiled with the same definition of bool.
169
* Since one of the files includes <stdbool.h>, that means the header is
170
* available on this platform. Recompile everything with -DUSE_C99_BOOLEAN.
171
*/
172
#error "<stdbool.h> is included in pre-C99 mode"
173
#elif defined(bool) || defined(true) || defined(false)
174
/*
175
* In pre-C99 mode, make does not expect that bool is already defined.
176
* You need to ensure that all translation units use the same definition for
177
* bool.
178
*/
179
#error "bool/true/false is defined in pre-C99 mode"
180
#else
181
typedef unsigned char bool;
182
#define true 1
183
#define false 0
184
#endif
185
186
/*
187
* In code coverage mode with gcc>=12, calling vfork/exec does not mark any
188
* further code from the parent process as covered. gcc-10.5.0 is fine, as
189
* are fork/exec calls, as well as posix_spawn.
190
*/
191
#ifndef FORK_FUNCTION
192
#define FORK_FUNCTION vfork
193
#endif
194
195
#include "lst.h"
196
#include "make_malloc.h"
197
#include "str.h"
198
#include "hash.h"
199
#include "make-conf.h"
200
#include "buf.h"
201
202
/*
203
* some vendors don't have this --sjg
204
*/
205
#if defined(S_IFDIR) && !defined(S_ISDIR)
206
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
207
#endif
208
209
#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
210
# define POSIX_SIGNALS
211
#endif
212
213
/*
214
* IRIX defines OP_NONE in sys/fcntl.h
215
*/
216
#if defined(OP_NONE)
217
# undef OP_NONE
218
#endif
219
220
/*
221
* The typical flow of states is:
222
*
223
* The direct successful path:
224
* UNMADE -> BEINGMADE -> MADE.
225
*
226
* The direct error path:
227
* UNMADE -> BEINGMADE -> ERROR.
228
*
229
* The successful path when dependencies need to be made first:
230
* UNMADE -> DEFERRED -> REQUESTED -> BEINGMADE -> MADE.
231
*
232
* A node that has dependencies, and one of the dependencies cannot be made:
233
* UNMADE -> DEFERRED -> ABORTED.
234
*
235
* A node that turns out to be up-to-date:
236
* UNMADE -> BEINGMADE -> UPTODATE.
237
*/
238
typedef enum GNodeMade {
239
/* Not examined yet. */
240
UNMADE,
241
/*
242
* The node has been examined but is not yet ready since its
243
* dependencies have to be made first.
244
*/
245
DEFERRED,
246
247
/* The node is on the toBeMade list. */
248
REQUESTED,
249
250
/*
251
* The node is already being made. Trying to build a node in this
252
* state indicates a cycle in the graph.
253
*/
254
BEINGMADE,
255
256
/* Was out-of-date and has been made. */
257
MADE,
258
/* Was already up-to-date, does not need to be made. */
259
UPTODATE,
260
/*
261
* An error occurred while it was being made. Used only in compat
262
* mode.
263
*/
264
ERROR,
265
/*
266
* The target was aborted due to an error making a dependency. Used
267
* only in compat mode.
268
*/
269
ABORTED
270
} GNodeMade;
271
272
/*
273
* The OP_ constants are used when parsing a dependency line as a way of
274
* communicating to other parts of the program the way in which a target
275
* should be made.
276
*
277
* Some of the OP_ constants can be combined, others cannot.
278
*
279
* See the tests depsrc-*.mk and deptgt-*.mk.
280
*/
281
typedef enum GNodeType {
282
OP_NONE = 0,
283
284
/*
285
* The dependency operator ':' is the most common one. The commands
286
* of this node are executed if any child is out-of-date.
287
*/
288
OP_DEPENDS = 1 << 0,
289
/*
290
* The dependency operator '!' always executes its commands, even if
291
* its children are up-to-date.
292
*/
293
OP_FORCE = 1 << 1,
294
/*
295
* The dependency operator '::' behaves like ':', except that it
296
* allows multiple dependency groups to be defined. Each of these
297
* groups is executed on its own, independently from the others. Each
298
* individual dependency group is called a cohort.
299
*/
300
OP_DOUBLEDEP = 1 << 2,
301
302
/* Matches the dependency operators ':', '!' and '::'. */
303
OP_OPMASK = OP_DEPENDS | OP_FORCE | OP_DOUBLEDEP,
304
305
/* Don't care if the target doesn't exist and can't be created. */
306
OP_OPTIONAL = 1 << 3,
307
/* Use associated commands for parents. */
308
OP_USE = 1 << 4,
309
/*
310
* Target is never out of date, but always execute commands anyway.
311
* Its time doesn't matter, so it has none...sort of.
312
*/
313
OP_EXEC = 1 << 5,
314
/*
315
* Ignore non-zero exit status from shell commands when creating the
316
* node.
317
*/
318
OP_IGNORE = 1 << 6,
319
/* Don't remove the target when interrupted. */
320
OP_PRECIOUS = 1 << 7,
321
/* Don't echo commands when executed. */
322
OP_SILENT = 1 << 8,
323
/*
324
* Target is a recursive make so its commands should always be
325
* executed when it is out of date, regardless of the state of the -n
326
* or -t flags.
327
*/
328
OP_MAKE = 1 << 9,
329
/*
330
* Target is out-of-date only if any of its children was out-of-date.
331
*/
332
OP_JOIN = 1 << 10,
333
/* Assume the children of the node have been already made. */
334
OP_MADE = 1 << 11,
335
/* Special .BEGIN, .END or .INTERRUPT. */
336
OP_SPECIAL = 1 << 12,
337
/* Like .USE, only prepend commands. */
338
OP_USEBEFORE = 1 << 13,
339
/*
340
* The node is invisible to its parents. I.e. it doesn't show up in
341
* the parents' local variables (.IMPSRC, .ALLSRC).
342
*/
343
OP_INVISIBLE = 1 << 14,
344
/*
345
* The node does not become the main target, even if it is the first
346
* target in the first makefile.
347
*/
348
OP_NOTMAIN = 1 << 15,
349
/* Not a file target; run always. */
350
OP_PHONY = 1 << 16,
351
/* Don't search for the file in the path. */
352
OP_NOPATH = 1 << 17,
353
/*
354
* In a dependency line "target: source1 .WAIT source2", source1 is
355
* made first, including its children. Once that is finished,
356
* source2 is made, including its children. The .WAIT keyword may
357
* appear more than once in a single dependency declaration.
358
*/
359
OP_WAIT = 1 << 18,
360
/* .NOMETA do not create a .meta file */
361
OP_NOMETA = 1 << 19,
362
/* .META we _do_ want a .meta file */
363
OP_META = 1 << 20,
364
/* Do not compare commands in .meta file */
365
OP_NOMETA_CMP = 1 << 21,
366
/* Possibly a submake node */
367
OP_SUBMAKE = 1 << 22,
368
369
/* Attributes applied by PMake */
370
371
/* The node is a transformation rule, such as ".c.o". */
372
OP_TRANSFORM = 1 << 30,
373
/* Target is a member of an archive */
374
/* XXX: How does this differ from OP_ARCHV? */
375
OP_MEMBER = 1 << 29,
376
/*
377
* The node is a library, its name has the form "-l<libname>".
378
*/
379
OP_LIB = 1 << 28,
380
/*
381
* The node is an archive member, its name has the form
382
* "archive(member)".
383
*/
384
/* XXX: How does this differ from OP_MEMBER? */
385
OP_ARCHV = 1 << 27,
386
/*
387
* Target has all the commands it should. Used when parsing to catch
388
* multiple command groups for a target. Only applies to the
389
* dependency operators ':' and '!', but not to '::'.
390
*/
391
OP_HAS_COMMANDS = 1 << 26,
392
/*
393
* The special command "..." has been seen. All further commands from
394
* this node will be saved on the .END node instead, to be executed
395
* at the very end.
396
*/
397
OP_SAVE_CMDS = 1 << 25,
398
/*
399
* Already processed by Suff_FindDeps, to find dependencies from
400
* suffix transformation rules.
401
*/
402
OP_DEPS_FOUND = 1 << 24,
403
/* Node found while expanding .ALLSRC */
404
OP_MARK = 1 << 23
405
} GNodeType;
406
407
typedef struct GNodeFlags {
408
/* this target needs to be (re)made */
409
bool remake:1;
410
/* children of this target were made */
411
bool childMade:1;
412
/* children don't exist, and we pretend made */
413
bool force:1;
414
/* Set by Make_ProcessWait() */
415
bool doneWait:1;
416
/* Build requested by .ORDER processing */
417
bool doneOrder:1;
418
/* Node created from .depend */
419
bool fromDepend:1;
420
/* We do it once only */
421
bool doneAllsrc:1;
422
/* Used by MakePrintStatus */
423
bool cycle:1;
424
/* Used by MakePrintStatus */
425
bool doneCycle:1;
426
} GNodeFlags;
427
428
typedef struct List StringList;
429
typedef struct ListNode StringListNode;
430
431
typedef struct List GNodeList;
432
typedef struct ListNode GNodeListNode;
433
434
typedef struct SearchPath {
435
List /* of CachedDir */ dirs;
436
} SearchPath;
437
438
/*
439
* A graph node represents a target that can possibly be made, including its
440
* relation to other targets.
441
*/
442
typedef struct GNode {
443
/* The target's name, such as "clean" or "make.c" */
444
char *name;
445
/* The unexpanded name of a .USE node */
446
char *uname;
447
/*
448
* The full pathname of the file belonging to the target.
449
*
450
* XXX: What about .PHONY targets? These don't have an associated
451
* path.
452
*/
453
char *path;
454
455
/*
456
* The type of operator used to define the sources (see the OP flags
457
* below).
458
*
459
* XXX: This looks like a wild mixture of type and flags.
460
*/
461
GNodeType type;
462
GNodeFlags flags;
463
464
/* The state of processing on this node */
465
GNodeMade made;
466
/* The number of unmade children */
467
int unmade;
468
469
/*
470
* The modification time; 0 means the node does not have a
471
* corresponding file; see GNode_IsOODate.
472
*/
473
time_t mtime;
474
struct GNode *youngestChild;
475
476
/*
477
* The GNodes for which this node is an implied source. May be empty.
478
* For example, when there is an inference rule for .c.o, the node
479
* for file.c has the node for file.o in this list.
480
*/
481
GNodeList implicitParents;
482
483
/*
484
* The nodes that depend on this one, or in other words, the nodes
485
* for which this is a source.
486
*/
487
GNodeList parents;
488
/* The nodes on which this one depends. */
489
GNodeList children;
490
491
/*
492
* .ORDER nodes we need made. The nodes that must be made (if they're
493
* made) before this node can be made, but that do not enter into the
494
* datedness of this node.
495
*/
496
GNodeList order_pred;
497
/*
498
* .ORDER nodes who need us. The nodes that must be made (if they're
499
* made at all) after this node is made, but that do not depend on
500
* this node, in the normal sense.
501
*/
502
GNodeList order_succ;
503
504
/*
505
* Other nodes of the same name, for targets that were defined using
506
* the '::' dependency operator (OP_DOUBLEDEP).
507
*/
508
GNodeList cohorts;
509
/* The "#n" suffix for this cohort, or "" for other nodes */
510
char cohort_num[8];
511
/* The number of unmade instances on the cohorts list */
512
int unmade_cohorts;
513
/*
514
* Pointer to the first instance of a '::' node; only set when on a
515
* cohorts list
516
*/
517
struct GNode *centurion;
518
519
/* Last time (sequence number) we tried to make this node */
520
unsigned checked_seqno;
521
522
/*
523
* The "local" variables that are specific to this target and this
524
* target only, such as $@, $<, $?.
525
*
526
* Also used for the global variable scopes SCOPE_GLOBAL,
527
* SCOPE_CMDLINE, SCOPE_INTERNAL, which contain variables with
528
* arbitrary names.
529
*/
530
HashTable /* of Var pointer */ vars;
531
532
/* The commands to be given to a shell to create this target. */
533
StringList commands;
534
535
/*
536
* Suffix for the node (determined by Suff_FindDeps and opaque to
537
* everyone but the Suff module)
538
*/
539
struct Suffix *suffix;
540
541
/* Filename where the GNode got defined, unlimited lifetime */
542
const char *fname;
543
/* Line number where the GNode got defined, 1-based */
544
unsigned lineno;
545
int exit_status;
546
} GNode;
547
548
/*
549
* Keep track of whether to include <posix.mk> when parsing the line
550
* '.POSIX:'.
551
*/
552
extern enum PosixState {
553
PS_NOT_YET,
554
PS_MAYBE_NEXT_LINE,
555
PS_NOW_OR_NEVER,
556
PS_SET,
557
PS_TOO_LATE
558
} posix_state;
559
560
/* Error levels for diagnostics during parsing. */
561
typedef enum ParseErrorLevel {
562
/*
563
* Exit when the current top-level makefile has been parsed
564
* completely.
565
*/
566
PARSE_FATAL = 1,
567
/* Print "warning"; may be upgraded to fatal by the -w option. */
568
PARSE_WARNING,
569
/* Informational, mainly used during development of makefiles. */
570
PARSE_INFO
571
} ParseErrorLevel;
572
573
/*
574
* Values returned by Cond_EvalLine and Cond_EvalCondition.
575
*/
576
typedef enum CondResult {
577
CR_TRUE, /* Parse the next lines */
578
CR_FALSE, /* Skip the next lines */
579
CR_ERROR /* Unknown directive or parse error */
580
} CondResult;
581
582
typedef struct {
583
enum GuardKind {
584
GK_VARIABLE,
585
GK_TARGET
586
} kind;
587
char *name;
588
} Guard;
589
590
/* Names of the variables that are "local" to a specific target. */
591
#define TARGET "@" /* Target of dependency */
592
#define OODATE "?" /* All out-of-date sources */
593
#define ALLSRC ">" /* All sources */
594
#define IMPSRC "<" /* Source implied by transformation */
595
#define PREFIX "*" /* Common prefix */
596
#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
597
#define MEMBER "%" /* Member in "archive(member)" syntax */
598
599
/*
600
* Global Variables
601
*/
602
603
/* True if every target is precious */
604
extern bool allPrecious;
605
/* True if failed targets should be deleted */
606
extern bool deleteOnError;
607
/* true while processing .depend */
608
extern bool doing_depend;
609
/* .DEFAULT rule */
610
extern GNode *defaultNode;
611
612
/*
613
* Variables defined internally by make which should not override those set
614
* by makefiles.
615
*/
616
extern GNode *SCOPE_INTERNAL;
617
/* Variables defined in a global scope, e.g in the makefile itself. */
618
extern GNode *SCOPE_GLOBAL;
619
/* Variables defined on the command line. */
620
extern GNode *SCOPE_CMDLINE;
621
622
/*
623
* Value returned by Var_Parse when an error is encountered. It points to an
624
* empty string, so naive callers needn't worry about it.
625
*/
626
extern char var_Error[];
627
628
/* The time at the start of this whole process */
629
extern time_t now;
630
631
/*
632
* The list of directories to search when looking for targets (set by the
633
* special target .PATH).
634
*/
635
extern SearchPath dirSearchPath;
636
/* Used for .include "...". */
637
extern SearchPath *parseIncPath;
638
/*
639
* Used for .include <...>, for the built-in sys.mk and for makefiles from
640
* the command line arguments.
641
*/
642
extern SearchPath *sysIncPath;
643
/* The default for sysIncPath. */
644
extern SearchPath *defSysIncPath;
645
646
/* Startup directory */
647
extern char curdir[];
648
/* The basename of the program name, suffixed with [n] for sub-makes. */
649
extern const char *progname;
650
extern int makelevel;
651
/* Name of the .depend makefile */
652
extern char *makeDependfile;
653
/* If we replaced environ, this will be non-NULL. */
654
extern char **savedEnv;
655
extern GNode *mainNode;
656
657
extern pid_t myPid;
658
659
#define MAKEFLAGS ".MAKEFLAGS"
660
#ifndef MAKE_LEVEL_ENV
661
# define MAKE_LEVEL_ENV "MAKELEVEL"
662
#endif
663
664
typedef struct DebugFlags {
665
bool DEBUG_ARCH:1;
666
bool DEBUG_COND:1;
667
bool DEBUG_CWD:1;
668
bool DEBUG_DIR:1;
669
bool DEBUG_ERROR:1;
670
bool DEBUG_FOR:1;
671
bool DEBUG_GRAPH1:1;
672
bool DEBUG_GRAPH2:1;
673
bool DEBUG_GRAPH3:1;
674
bool DEBUG_HASH:1;
675
bool DEBUG_JOB:1;
676
bool DEBUG_LOUD:1;
677
bool DEBUG_MAKE:1;
678
bool DEBUG_META:1;
679
bool DEBUG_PARSE:1;
680
bool DEBUG_SCRIPT:1;
681
bool DEBUG_SHELL:1;
682
bool DEBUG_SUFF:1;
683
bool DEBUG_TARG:1;
684
bool DEBUG_VAR:1;
685
} DebugFlags;
686
687
#define CONCAT(a, b) a##b
688
689
#define DEBUG(module) (opts.debug.CONCAT(DEBUG_, module))
690
691
void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
692
693
#define DEBUG_IMPL(module, args) \
694
do { \
695
if (DEBUG(module)) \
696
debug_printf args; \
697
} while (false)
698
699
#define DEBUG0(module, fmt) \
700
DEBUG_IMPL(module, (fmt))
701
#define DEBUG1(module, fmt, arg1) \
702
DEBUG_IMPL(module, (fmt, arg1))
703
#define DEBUG2(module, fmt, arg1, arg2) \
704
DEBUG_IMPL(module, (fmt, arg1, arg2))
705
#define DEBUG3(module, fmt, arg1, arg2, arg3) \
706
DEBUG_IMPL(module, (fmt, arg1, arg2, arg3))
707
#define DEBUG4(module, fmt, arg1, arg2, arg3, arg4) \
708
DEBUG_IMPL(module, (fmt, arg1, arg2, arg3, arg4))
709
#define DEBUG5(module, fmt, arg1, arg2, arg3, arg4, arg5) \
710
DEBUG_IMPL(module, (fmt, arg1, arg2, arg3, arg4, arg5))
711
712
typedef enum PrintVarsMode {
713
PVM_NONE,
714
PVM_UNEXPANDED,
715
PVM_EXPANDED
716
} PrintVarsMode;
717
718
/* Command line options */
719
typedef struct CmdOpts {
720
/* -B: whether to be compatible to traditional make */
721
bool compatMake;
722
723
/*
724
* -d: debug control: There is one flag per module. It is up to the
725
* module what debug information to print.
726
*/
727
DebugFlags debug;
728
729
/* -dF: debug output is written here - default stderr */
730
FILE *debug_file;
731
732
/*
733
* -dL: lint mode
734
*
735
* Runs make in strict mode, with additional checks and better error
736
* handling.
737
*/
738
bool strict;
739
740
/* -dV: for the -V option, print unexpanded variable values */
741
bool debugVflag;
742
743
/* -e: check environment variables before global variables */
744
bool checkEnvFirst;
745
746
/* -f: the makefiles to read */
747
StringList makefiles;
748
749
/* -i: if true, ignore all errors from shell commands */
750
bool ignoreErrors;
751
752
/*
753
* -j: the maximum number of jobs that can run in parallel; this is
754
* coordinated with the submakes
755
*/
756
int maxJobs;
757
758
/*
759
* -k: if true and an error occurs while making a node, continue
760
* making nodes that do not depend on the erroneous node
761
*/
762
bool keepgoing;
763
764
/* -N: execute no commands from the targets */
765
bool noRecursiveExecute;
766
767
/* -n: execute almost no commands from the targets */
768
bool noExecute;
769
770
/*
771
* -q: if true, do not really make anything, just see if the targets
772
* are out-of-date
773
*/
774
bool query;
775
776
/* -r: raw mode, do not load the builtin rules. */
777
bool noBuiltins;
778
779
/* -s: don't echo the shell commands before executing them */
780
bool silent;
781
782
/*
783
* -t: touch the targets if they are out-of-date, but don't actually
784
* make them
785
*/
786
bool touch;
787
788
/* -[Vv]: print expanded or unexpanded selected variables */
789
PrintVarsMode printVars;
790
/* -[Vv]: the variables to print */
791
StringList variables;
792
793
/* -W: if true, makefile parsing warnings are treated as errors */
794
bool parseWarnFatal;
795
796
/* -w: print 'Entering' and 'Leaving' for submakes */
797
bool enterFlag;
798
799
/*
800
* -X: if true, do not export variables set on the command line to
801
* the environment.
802
*/
803
bool varNoExportEnv;
804
805
/*
806
* The target names specified on the command line. Used to resolve
807
* .if make(...) statements.
808
*/
809
StringList create;
810
811
/*
812
* Randomize the order in which the targets from toBeMade are made,
813
* to catch undeclared dependencies.
814
*/
815
bool randomizeTargets;
816
} CmdOpts;
817
818
extern CmdOpts opts;
819
extern bool forceJobs;
820
extern char **environ;
821
822
/* arch.c */
823
void Arch_Init(void);
824
#ifdef CLEANUP
825
void Arch_End(void);
826
#endif
827
828
bool Arch_ParseArchive(char **, GNodeList *, GNode *);
829
void Arch_Touch(GNode *);
830
void Arch_TouchLib(GNode *);
831
void Arch_UpdateMTime(GNode *);
832
void Arch_UpdateMemberMTime(GNode *);
833
void Arch_FindLib(GNode *, SearchPath *);
834
bool Arch_LibOODate(GNode *) MAKE_ATTR_USE;
835
bool Arch_IsLib(GNode *) MAKE_ATTR_USE;
836
837
/* compat.c */
838
bool Compat_RunCommand(const char *, GNode *, StringListNode *);
839
void Compat_MakeAll(GNodeList *);
840
void Compat_Make(GNode *, GNode *);
841
842
/* cond.c */
843
extern unsigned cond_depth;
844
CondResult Cond_EvalCondition(const char *) MAKE_ATTR_USE;
845
CondResult Cond_EvalLine(const char *) MAKE_ATTR_USE;
846
Guard *Cond_ExtractGuard(const char *) MAKE_ATTR_USE;
847
void Cond_EndFile(void);
848
849
/* dir.c; see also dir.h */
850
851
MAKE_INLINE const char * MAKE_ATTR_USE
852
str_basename(const char *pathname)
853
{
854
const char *lastSlash = strrchr(pathname, '/');
855
return lastSlash != NULL ? lastSlash + 1 : pathname;
856
}
857
858
MAKE_INLINE SearchPath * MAKE_ATTR_USE
859
SearchPath_New(void)
860
{
861
SearchPath *path = bmake_malloc(sizeof *path);
862
Lst_Init(&path->dirs);
863
return path;
864
}
865
866
void SearchPath_Free(SearchPath *);
867
868
/* for.c */
869
struct ForLoop;
870
int For_Eval(const char *) MAKE_ATTR_USE;
871
bool For_Accum(const char *, int *) MAKE_ATTR_USE;
872
void For_Run(unsigned, unsigned);
873
bool For_NextIteration(struct ForLoop *, Buffer *);
874
char *ForLoop_Details(const struct ForLoop *);
875
void ForLoop_Free(struct ForLoop *);
876
void For_Break(struct ForLoop *);
877
878
/* job.c */
879
void JobReapChild(pid_t, int, bool);
880
881
/* longer than this we use a temp file */
882
#ifndef MAKE_CMDLEN_LIMIT
883
# define MAKE_CMDLEN_LIMIT 1000
884
#endif
885
/* main.c */
886
void Main_ParseArgLine(const char *);
887
void Cmd_Argv(const char *, size_t, const char *[5], char *, size_t,
888
bool, bool);
889
char *Cmd_Exec(const char *, char **) MAKE_ATTR_USE;
890
void Var_ExportStackTrace(const char *, const char *);
891
void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
892
void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
893
void Punt(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;
894
void DieHorribly(void) MAKE_ATTR_DEAD;
895
int unlink_file(const char *) MAKE_ATTR_USE;
896
void execDie(const char *, const char *);
897
char *getTmpdir(void) MAKE_ATTR_USE;
898
bool ParseBoolean(const char *, bool) MAKE_ATTR_USE;
899
const char *cached_realpath(const char *, char *);
900
bool GetBooleanExpr(const char *, bool);
901
902
/* parse.c */
903
extern int parseErrors;
904
void Parse_Init(void);
905
#ifdef CLEANUP
906
void Parse_End(void);
907
#endif
908
909
void PrintLocation(FILE *, bool, const GNode *);
910
const char *GetParentStackTrace(void);
911
char *GetStackTrace(bool);
912
void PrintStackTrace(bool);
913
void Parse_Error(ParseErrorLevel, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
914
bool Parse_VarAssign(const char *, bool, GNode *) MAKE_ATTR_USE;
915
void Parse_File(const char *, int);
916
void Parse_PushInput(const char *, unsigned, unsigned, Buffer,
917
struct ForLoop *);
918
void Parse_MainName(GNodeList *);
919
unsigned CurFile_CondMinDepth(void) MAKE_ATTR_USE;
920
void Parse_GuardElse(void);
921
void Parse_GuardEndif(void);
922
923
924
/* suff.c */
925
void Suff_Init(void);
926
#ifdef CLEANUP
927
void Suff_End(void);
928
#endif
929
930
void Suff_ClearSuffixes(void);
931
bool Suff_IsTransform(const char *) MAKE_ATTR_USE;
932
GNode *Suff_AddTransform(const char *);
933
void Suff_EndTransform(GNode *);
934
void Suff_AddSuffix(const char *);
935
SearchPath *Suff_GetPath(const char *) MAKE_ATTR_USE;
936
void Suff_ExtendPaths(void);
937
void Suff_AddInclude(const char *);
938
void Suff_AddLib(const char *);
939
void Suff_FindDeps(GNode *);
940
SearchPath *Suff_FindPath(GNode *) MAKE_ATTR_USE;
941
void Suff_SetNull(const char *);
942
void Suff_PrintAll(void);
943
char *Suff_NamesStr(void) MAKE_ATTR_USE;
944
945
/* targ.c */
946
void Targ_Init(void);
947
void Targ_End(void);
948
949
void Targ_Stats(void);
950
GNodeList *Targ_List(void) MAKE_ATTR_USE;
951
GNode *GNode_New(const char *) MAKE_ATTR_USE;
952
GNode *Targ_FindNode(const char *) MAKE_ATTR_USE;
953
GNode *Targ_GetNode(const char *) MAKE_ATTR_USE;
954
GNode *Targ_NewInternalNode(const char *) MAKE_ATTR_USE;
955
GNode *Targ_GetEndNode(void);
956
void Targ_FindList(GNodeList *, StringList *);
957
void Targ_PrintCmds(GNode *);
958
void Targ_PrintNode(GNode *, int);
959
void Targ_PrintNodes(GNodeList *, int);
960
const char *Targ_FmtTime(time_t) MAKE_ATTR_USE;
961
void Targ_PrintType(GNodeType);
962
void Targ_PrintGraph(int);
963
void Targ_Propagate(void);
964
const char *GNodeMade_Name(GNodeMade) MAKE_ATTR_USE;
965
#ifdef CLEANUP
966
void Parse_RegisterCommand(char *);
967
#else
968
MAKE_INLINE
969
void Parse_RegisterCommand(char *cmd MAKE_ATTR_UNUSED)
970
{
971
}
972
#endif
973
974
/* var.c */
975
976
typedef enum VarEvalMode {
977
978
/*
979
* Only parse the expression but don't evaluate any part of it.
980
*
981
* TODO: Document what Var_Parse and Var_Subst return in this mode.
982
* As of 2021-03-15, they return unspecified, inconsistent results.
983
*/
984
VARE_PARSE,
985
986
/*
987
* Parse text in which '${...}' and '$(...)' are not parsed as
988
* subexpressions (with all their individual escaping rules) but
989
* instead simply as text with balanced '${}' or '$()'. Other '$'
990
* are copied verbatim.
991
*/
992
VARE_PARSE_BALANCED,
993
994
/* Parse and evaluate the expression. */
995
VARE_EVAL,
996
997
/*
998
* Parse and evaluate the expression. It is an error if a
999
* subexpression evaluates to undefined.
1000
*/
1001
VARE_EVAL_DEFINED_LOUD,
1002
1003
/*
1004
* Parse and evaluate the expression. It is a silent error if a
1005
* subexpression evaluates to undefined.
1006
*/
1007
VARE_EVAL_DEFINED,
1008
1009
/*
1010
* Parse and evaluate the expression. Keep undefined variables as-is
1011
* instead of expanding them to an empty string.
1012
*
1013
* Example for a ':=' assignment:
1014
* CFLAGS = $(.INCLUDES)
1015
* CFLAGS := -I.. $(CFLAGS)
1016
* # If .INCLUDES (an undocumented special variable, by the
1017
* # way) is still undefined, the updated CFLAGS becomes
1018
* # "-I.. $(.INCLUDES)".
1019
*/
1020
VARE_EVAL_KEEP_UNDEFINED,
1021
1022
/*
1023
* Parse and evaluate the expression. Keep '$$' as '$$' and preserve
1024
* undefined subexpressions.
1025
*/
1026
VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED
1027
} VarEvalMode;
1028
1029
typedef enum VarSetFlags {
1030
VAR_SET_NONE = 0,
1031
1032
/* do not export */
1033
VAR_SET_NO_EXPORT = 1 << 0,
1034
1035
/*
1036
* Make the variable read-only. No further modification is possible,
1037
* except for another call to Var_Set with the same flag. See the
1038
* special targets '.NOREADONLY' and '.READONLY'.
1039
*/
1040
VAR_SET_READONLY = 1 << 1,
1041
VAR_SET_INTERNAL = 1 << 2
1042
} VarSetFlags;
1043
1044
typedef enum VarExportMode {
1045
/* .export-all */
1046
VEM_ALL,
1047
/* .export-env */
1048
VEM_ENV,
1049
/* .export: Initial export or update an already exported variable. */
1050
VEM_PLAIN,
1051
/* .export-literal: Do not expand the variable value. */
1052
VEM_LITERAL
1053
} VarExportMode;
1054
1055
void Var_Delete(GNode *, const char *);
1056
#ifdef CLEANUP
1057
void Var_DeleteAll(GNode *scope);
1058
#endif
1059
void Var_Undef(const char *);
1060
void Var_Set(GNode *, const char *, const char *);
1061
void Var_SetExpand(GNode *, const char *, const char *);
1062
void Var_SetWithFlags(GNode *, const char *, const char *, VarSetFlags);
1063
void Var_Append(GNode *, const char *, const char *);
1064
void Var_AppendExpand(GNode *, const char *, const char *);
1065
bool Var_Exists(GNode *, const char *) MAKE_ATTR_USE;
1066
bool Var_ExistsExpand(GNode *, const char *) MAKE_ATTR_USE;
1067
FStr Var_Value(GNode *, const char *) MAKE_ATTR_USE;
1068
const char *GNode_ValueDirect(GNode *, const char *) MAKE_ATTR_USE;
1069
FStr Var_Parse(const char **, GNode *, VarEvalMode);
1070
char *Var_Subst(const char *, GNode *, VarEvalMode);
1071
char *Var_SubstInTarget(const char *, GNode *);
1072
void Var_Expand(FStr *, GNode *, VarEvalMode);
1073
void Var_Stats(void);
1074
void Var_Dump(GNode *);
1075
void Var_ReexportVars(GNode *);
1076
void Var_Export(VarExportMode, const char *);
1077
void Var_ExportVars(const char *);
1078
void Var_UnExport(bool, const char *);
1079
void Var_ReadOnly(const char *, bool);
1080
1081
void Global_Set(const char *, const char *);
1082
void Global_Append(const char *, const char *);
1083
void Global_Delete(const char *);
1084
void Global_Set_ReadOnly(const char *, const char *);
1085
1086
void EvalStack_PushMakeflags(const char *);
1087
void EvalStack_Pop(void);
1088
bool EvalStack_Details(Buffer *buf) MAKE_ATTR_USE;
1089
1090
/* util.c */
1091
typedef void (*SignalProc)(int);
1092
SignalProc bmake_signal(int, SignalProc);
1093
1094
/* make.c */
1095
void GNode_UpdateYoungestChild(GNode *, GNode *);
1096
bool GNode_IsOODate(GNode *) MAKE_ATTR_USE;
1097
void Make_ExpandUse(GNodeList *);
1098
time_t Make_Recheck(GNode *) MAKE_ATTR_USE;
1099
void Make_HandleUse(GNode *, GNode *);
1100
void Make_Update(GNode *);
1101
void GNode_SetLocalVars(GNode *);
1102
bool Make_MakeParallel(GNodeList *);
1103
bool shouldDieQuietly(GNode *, int) MAKE_ATTR_USE;
1104
void PrintOnError(GNode *, const char *);
1105
void Main_ExportMAKEFLAGS(bool);
1106
bool Main_SetObjdir(bool, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
1107
int mkTempFile(const char *, char *, size_t) MAKE_ATTR_USE;
1108
void AppendWords(StringList *, char *);
1109
void GNode_FprintDetails(FILE *, const char *, const GNode *, const char *);
1110
bool GNode_ShouldExecute(GNode *gn) MAKE_ATTR_USE;
1111
char *GNodeType_ToString(GNodeType);
1112
1113
#ifndef HAVE_STRLCPY
1114
size_t strlcpy(char *, const char *, size_t);
1115
#endif
1116
1117
/* See if the node was seen on the left-hand side of a dependency operator. */
1118
MAKE_INLINE bool MAKE_ATTR_USE
1119
GNode_IsTarget(const GNode *gn)
1120
{
1121
return (gn->type & OP_OPMASK) != OP_NONE;
1122
}
1123
1124
MAKE_INLINE const char * MAKE_ATTR_USE
1125
GNode_Path(const GNode *gn)
1126
{
1127
return gn->path != NULL ? gn->path : gn->name;
1128
}
1129
1130
MAKE_INLINE bool MAKE_ATTR_USE
1131
GNode_IsWaitingFor(const GNode *gn)
1132
{
1133
return gn->flags.remake && gn->made <= REQUESTED;
1134
}
1135
1136
MAKE_INLINE bool MAKE_ATTR_USE
1137
GNode_IsReady(const GNode *gn)
1138
{
1139
return gn->made > DEFERRED;
1140
}
1141
1142
MAKE_INLINE bool MAKE_ATTR_USE
1143
GNode_IsDone(const GNode *gn)
1144
{
1145
return gn->made >= MADE;
1146
}
1147
1148
MAKE_INLINE bool MAKE_ATTR_USE
1149
GNode_IsError(const GNode *gn)
1150
{
1151
return gn->made == ERROR || gn->made == ABORTED;
1152
}
1153
1154
MAKE_INLINE bool MAKE_ATTR_USE
1155
GNode_IsMainCandidate(const GNode *gn)
1156
{
1157
return (gn->type & (OP_NOTMAIN | OP_USE | OP_USEBEFORE |
1158
OP_EXEC | OP_TRANSFORM)) == 0;
1159
}
1160
1161
/* Return whether the target file should be preserved on interrupt. */
1162
MAKE_INLINE bool MAKE_ATTR_USE
1163
GNode_IsPrecious(const GNode *gn)
1164
{
1165
/* XXX: Why are '::' targets precious? */
1166
return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP);
1167
}
1168
1169
MAKE_INLINE const char * MAKE_ATTR_USE
1170
GNode_VarTarget(GNode *gn) { return GNode_ValueDirect(gn, TARGET); }
1171
MAKE_INLINE const char * MAKE_ATTR_USE
1172
GNode_VarOodate(GNode *gn) { return GNode_ValueDirect(gn, OODATE); }
1173
MAKE_INLINE const char * MAKE_ATTR_USE
1174
GNode_VarAllsrc(GNode *gn) { return GNode_ValueDirect(gn, ALLSRC); }
1175
MAKE_INLINE const char * MAKE_ATTR_USE
1176
GNode_VarImpsrc(GNode *gn) { return GNode_ValueDirect(gn, IMPSRC); }
1177
MAKE_INLINE const char * MAKE_ATTR_USE
1178
GNode_VarPrefix(GNode *gn) { return GNode_ValueDirect(gn, PREFIX); }
1179
MAKE_INLINE const char * MAKE_ATTR_USE
1180
GNode_VarArchive(GNode *gn) { return GNode_ValueDirect(gn, ARCHIVE); }
1181
MAKE_INLINE const char * MAKE_ATTR_USE
1182
GNode_VarMember(GNode *gn) { return GNode_ValueDirect(gn, MEMBER); }
1183
1184
MAKE_INLINE void * MAKE_ATTR_USE
1185
UNCONST(const void *ptr)
1186
{
1187
void *ret;
1188
memcpy(&ret, &ptr, sizeof(ret));
1189
return ret;
1190
}
1191
1192
/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */
1193
#ifdef HAVE_LIMITS_H
1194
#include <limits.h>
1195
#endif
1196
#ifndef MAXPATHLEN
1197
#define MAXPATHLEN BMAKE_PATH_MAX
1198
#endif
1199
#ifndef PATH_MAX
1200
#define PATH_MAX MAXPATHLEN
1201
#endif
1202
1203
#if defined(SYSV)
1204
#define KILLPG(pid, sig) kill(-(pid), (sig))
1205
#else
1206
#define KILLPG(pid, sig) killpg((pid), (sig))
1207
#endif
1208
1209
MAKE_INLINE bool MAKE_ATTR_USE
1210
ch_isalnum(char ch) { return isalnum((unsigned char)ch) != 0; }
1211
MAKE_INLINE bool MAKE_ATTR_USE
1212
ch_isalpha(char ch) { return isalpha((unsigned char)ch) != 0; }
1213
MAKE_INLINE bool MAKE_ATTR_USE
1214
ch_isdigit(char ch) { return isdigit((unsigned char)ch) != 0; }
1215
MAKE_INLINE bool MAKE_ATTR_USE
1216
ch_islower(char ch) { return islower((unsigned char)ch) != 0; }
1217
MAKE_INLINE bool MAKE_ATTR_USE
1218
ch_isprint(char ch) { return isprint((unsigned char)ch) != 0; }
1219
MAKE_INLINE bool MAKE_ATTR_USE
1220
ch_isspace(char ch) { return isspace((unsigned char)ch) != 0; }
1221
MAKE_INLINE bool MAKE_ATTR_USE
1222
ch_isupper(char ch) { return isupper((unsigned char)ch) != 0; }
1223
MAKE_INLINE char MAKE_ATTR_USE
1224
ch_tolower(char ch) { return (char)tolower((unsigned char)ch); }
1225
MAKE_INLINE char MAKE_ATTR_USE
1226
ch_toupper(char ch) { return (char)toupper((unsigned char)ch); }
1227
1228
MAKE_INLINE void
1229
cpp_skip_whitespace(const char **pp)
1230
{
1231
while (ch_isspace(**pp))
1232
(*pp)++;
1233
}
1234
1235
MAKE_INLINE void
1236
cpp_skip_hspace(const char **pp)
1237
{
1238
while (**pp == ' ' || **pp == '\t')
1239
(*pp)++;
1240
}
1241
1242
MAKE_INLINE bool
1243
cpp_skip_string(const char **pp, const char *s)
1244
{
1245
const char *p = *pp;
1246
while (*p == *s && *s != '\0')
1247
p++, s++;
1248
if (*s == '\0')
1249
*pp = p;
1250
return *s == '\0';
1251
}
1252
1253
MAKE_INLINE void
1254
pp_skip_whitespace(char **pp)
1255
{
1256
while (ch_isspace(**pp))
1257
(*pp)++;
1258
}
1259
1260
MAKE_INLINE void
1261
pp_skip_hspace(char **pp)
1262
{
1263
while (**pp == ' ' || **pp == '\t')
1264
(*pp)++;
1265
}
1266
1267
#if defined(lint)
1268
void do_not_define_rcsid(void); /* for lint */
1269
# define MAKE_RCSID(id) void do_not_define_rcsid(void)
1270
#elif defined(MAKE_NATIVE)
1271
# include <sys/cdefs.h>
1272
# ifndef __IDSTRING
1273
# define __IDSTRING(name,string) \
1274
static const char name[] MAKE_ATTR_UNUSED = string
1275
# endif
1276
# ifndef __RCSID
1277
# define __RCSID(s) __IDSTRING(rcsid,s)
1278
# endif
1279
# ifndef __COPYRIGHT
1280
# define __COPYRIGHT(s) __IDSTRING(copyright,s)
1281
# endif
1282
# define MAKE_RCSID(id) __RCSID(id)
1283
#elif defined(MAKE_ALL_IN_ONE) && defined(__COUNTER__)
1284
# define MAKE_RCSID_CONCAT(x, y) CONCAT(x, y)
1285
# define MAKE_RCSID(id) static volatile char \
1286
MAKE_RCSID_CONCAT(rcsid_, __COUNTER__)[] = id
1287
#elif defined(MAKE_ALL_IN_ONE)
1288
# define MAKE_RCSID(id) void do_not_define_rcsid(void)
1289
#else
1290
# define MAKE_RCSID(id) static volatile char rcsid[] = id
1291
#endif
1292
1293
#endif
1294
1295